Infinite plane shader version 2. See description at https://biospud.blogspot.com/2020/05/infinite-plane-rendering-2-texturing.html
#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; | |
} |
#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