Skip to content

Instantly share code, notes, and snippets.

@cmbruns cmbruns/plane01.vert
Last active May 14, 2020

Embed
What would you like to do?
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
You can’t perform that action at this time.