Jump to content
  • Advertisement
Sign in to follow this  
Silverlan

OpenGL Odd fragment shader depth output behavior? (Manual perspective division)

This topic is 868 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to implement shadow mapping with Vulkan. The rendering for the actual shadow map works fine, however in my scene shader, I need to do manual perspective division (Since gl_Position is already in use) to transform the scene depth values to light space (To be able to compare them with the samples from the shadow map), which produces weird results.

So I ended up doing some tests, and I've noticed very weird behavior with depth values in general.

 

Here are some example cases:

 

#1

If I use the default fragment shader (Implicit depth output), the depth values are written correctly.

 

Vertex Shader:

void main()
{
    gl_Position = MVP *vec4(vertexPosition,1.0);
}

Fragment Shader:

void main()
{} // Also works with gl_FragDepth = gl_FragCoord.z;

Result (Everything is as expected):

weave_2016-05-08_18-32-57.png

(Depth values are linearized in post-processing to make them more clearly visible.)

 

#2

This case is an odd one which I've stumbled upon by accident. If I have any reference to gl_FragDepth anywhere in the fragment shader, the resulting depth values change for no apparant reason:

 

Vertex Shader (Same as #1):

void main()
{
    gl_Position = MVP *vec4(vertexPosition,1.0);
}

Fragment Shader:

void main()
{
	float d = gl_FragDepth;
} 

According to the OpenGL Docs, "If depth buffering is enabled and no shader writes to gl_FragDepth, then the fixed function value for depth will be used[...]", I'm assuming this also applies when using Vulkan(?). Obviously gl_FragDepth is not being written to here, and yet the result is different than case #1:

weave_2016-05-08_18-34-30.png

(Values are very close to 0, but don't quite reach 0.)

 

#3 Manual perspective division

If I don't use the default perspective division, and attempt to do it manually, only about half of the depth values for the geometry are being written.

 

Vertex Shader:

void main()
{
	gl_Position = MVP *vec4(vertexPosition,1.0);
	gl_Position.xyz /= gl_Position.w;
	gl_Position.w = 1.0;
}

Fragment Shader:

void main()
{}

Result:

weave_2016-05-08_18-42-43.png

 

#4 Writing depth value manually

Attempting to calculate and pass the depth value to the fragment shader manually has similar results to case #3.

 

Vertex Shader:

out float test_depth;

void main()
{
	gl_Position = MVP *vec4(vertexPosition,1.0);
	test_depth = gl_Position.z /gl_Position.w;
}

Fragment Shader:

#version 320

in float test_depth;

void main()
{
	gl_FragDepth = test_depth;
}

Result:

weave_2016-05-08_18-49-24.png

 

 

The depth range for the viewport is set to [0,1], in case that could make a difference. I'm using a 32bit floating point depth format, so precision shouldn't be a problem.

I have the latest AMD beta Vulkan drivers installed, and I'm using Vulkan 1.0.8.0.

 

 

Can someone explain this to me?

What's the 'proper' way of doing perspective division manually with Vulkan (i.e. replicating the default behavior manually)?

Edited by Silverlan

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!