Last active
January 13, 2022 18:10
-
-
Save cmbruns/3c184d303e665ee2e987e4c1c2fe4b56 to your computer and use it in GitHub Desktop.
Infinite plane shader version 2. See description at https://biospud.blogspot.com/2020/05/infinite-plane-rendering-2-texturing.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 450 core | |
// Simplified vertex shader for rendering an infinite plane. | |
layout(location = 1) uniform mat4 projection = mat4(1); | |
layout(location = 2) uniform mat4 view = mat4(1); | |
layout(location = 3) uniform mat4 model = mat4( | |
1, 0, 0, 0, | |
0, 1, 0, 0, | |
0, 0, 1, 0, | |
0, 0.3, 0, 1); | |
// simple but expensive 1: vertices cover the entire screen | |
// projected screen quad - this is our hard-coded "vertex buffer" | |
const vec4 screen_quad[4] = vec4[4]( | |
vec4(-1, -1, 1, 1), | |
vec4( 1, -1, 1, 1), | |
vec4( 1, 1, 1, 1), | |
vec4(-1, 1, 1, 1)); | |
const int triangle_strip[4] = int[4]( | |
0, 1, 3, 2); | |
// Output coordinates of view/plane intersection in view space | |
out vec4 point; | |
out vec4 uhat; | |
out vec4 vhat; | |
out vec4 ndc; | |
vec3 dehomog(vec4 v) | |
{ | |
return v.xyz/v.w; | |
} | |
void main() | |
{ | |
vec4 corner_ndc = screen_quad[triangle_strip[gl_VertexID]]; | |
// Screen-quad corner coordinates arrive dirctly in clip-space. Pass them through unchanged. | |
gl_Position = corner_ndc; | |
vec3 plane_translation_eye = dehomog(view * model * vec4(0, 0, 0, 1)); | |
// Basis vectors for texture coordinates | |
uhat = view * model * vec4(1, 0, 0, 0); | |
vhat = view * model * vec4(0, 0, 1, 0); | |
// Pack uv translation into w-component of texture axes | |
uhat.w = -dot(plane_translation_eye, uhat.xyz); | |
vhat.w = -dot(plane_translation_eye, vhat.xyz); | |
// Notation from OpenGL super bible ray tracing section | |
vec4 D = inverse(projection) * corner_ndc; | |
vec4 N = view * model * vec4(0, 1, 0, 0); | |
float d = -dot(N.xyz, plane_translation_eye); | |
point = vec4( | |
-d * D.xyz, // xyz, numerator | |
dot(D.xyz, N.xyz) // w, denominator | |
); | |
ndc = projection * point; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 450 core | |
in vec4 point; // in view space | |
in vec4 uhat; | |
in vec4 vhat; | |
in vec4 ndc; | |
out vec4 frag_color; | |
void main() | |
{ | |
// simple but expensive 2: discard pixels not on the plane | |
if (point.w > 0) | |
discard; | |
float u = dot(uhat.xyz, point.xyz/point.w) + uhat.w; | |
float v = dot(vhat.xyz, point.xyz/point.w) + vhat.w; | |
// Simple procedural texture test | |
frag_color = vec4(fract(u), fract(v), 0.5, 1); | |
gl_FragDepth = (ndc.z / ndc.w + 1.0) / 2.0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for your informative blog post. There is hardly any good information on rendering infinite planes out there.
I am trying to port the shader to Unity's Universal Render Pipeline as a full screen post effect (Render Feature).
The plane horizon and uv all work fine, but I cannot get to work the depthbbuffer.
I have the suspicion that it is somehow connected to NDC differences between OpenGL and DirectX but I am not sure.
This is my transformation from NDC to depth as DirectX should not require the offset as OpenGL does.
The resulting color is pretty much white (with a slight gradient) however.
It may also be caused by me using the cameras projection matrix which has a far plane.
But if I would use an infinite projection matrix it would not be possible to compare the plane and the scene depth would it?
Btw. I do not understand why D is in view space while every other vector used is translated to object/model space?
I would really appreciate any help with this issue.