glslang icon indicating copy to clipboard operation
glslang copied to clipboard

GLSL: Add a option to fix up clip space.

Open chirsz-ever opened this issue 2 years ago • 2 comments

OpenGL uses the NDC with z of [-1, 1], and Vulkan, DirectX, Metal use the NDC with z of [0, 1].

When we want fix a vertex shader originally written for OpenGL, we can add an extra line:

gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;

Or generate SPIR-V code of this meaning.

SPIRV-Cross has an option for it.

Like #2936, I want use the same source code of shaders for OpenGL and Vulkan.

chirsz-ever avatar May 17 '22 09:05 chirsz-ever

OK. But this indeed can only be done under a new option. We can't regress code that has already taken this into account.

Note that #2936 is asking for the same transformation for GLSL as is done for HLSL. For fixup-clipspace, should we do for HLSL what is being requested for GLSL?

greg-lunarg avatar May 20 '22 23:05 greg-lunarg

The strategy of SPIRV-Cross's fixup_clipspace option is:

For GLSL targets, enabling this will convert a shader which assumes [0, w] depth range (Vulkan / D3D / Metal) into [-w, w] range. For MSL and HLSL targets, enabling this will convert a shader in [-w, w] depth range (OpenGL) to [0, w] depth range.

IMO, this is because D3D and Metal have NDCs with [0, 1] z-range and OpenGL has a [-1, 1] z-range.

An HLSL shader always assumes that the NDC z-range is [0, 1], so we don't need to worry about it when convert it to SPIR-V for Vulkan.

But there are also SPIR-V for OpenGL and glslang support it. In this case maybe we need add a line to transform Z-coordinate form [0, 1] to [-1. 1]:

gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;

I think this kind of situations is very rare.

My conclusion is, the --fixup-clipspace option should not be allowed or do the [0, w] to [-w, w] transformation if the source code format is HLSL.

chirsz-ever avatar May 21 '22 14:05 chirsz-ever