-
-
Save bamfbamf/84ef909a0ec214002ec5bc7f03fdafd0 to your computer and use it in GitHub Desktop.
Infinite grid in GLSL
This file contains 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 460 core | |
/* ----------------------------------------------------------------- | |
INPUTS | | |
----------------------------------------------------------------- */ | |
layout(location = 0) uniform mat4 VIEW; | |
layout(location = 1) uniform mat4 PROJECTION; | |
layout(location = 2) uniform vec3 VIEW_POS; | |
layout(location = 3) uniform float NEAR_PLANE; | |
layout(location = 4) uniform float FAR_PLANE; | |
layout(location = 5) uniform int gridAxis; | |
layout(location = 6) uniform float gridCellSize; | |
layout(location = 7) uniform float gridOpacity; | |
in vec3 pass_NearPoint; | |
in vec3 pass_FarPoint; | |
/* ----------------------------------------------------------------- | |
OUTPUTS | | |
----------------------------------------------------------------- */ | |
out vec4 out_CLR; | |
/* ----------------------------------------------------------------- | |
HELPERS | | |
----------------------------------------------------------------- */ | |
const float N = 200.0; // Grid ratio. | |
float | |
AnalyticalBoxFilter(vec2 p, vec2 ddx, vec2 ddy) // https://iquilezles.org/articles/filterableprocedurals/ | |
{ | |
// Filter kernel. | |
vec2 w = max(abs(ddx), abs(ddy)) + 0.01; | |
// Analytic (box) filtering. | |
vec2 a = p + 0.5 * w; | |
vec2 b = p - 0.5 * w; | |
vec2 i = (floor(a) + min(fract(a) * N, 1.0) - floor(b) - min(fract(b) * N, 1.0)) / (N * w); | |
// Pattern. | |
return (1.0 - i.x) * (1.0 - i.y); | |
} | |
vec4 | |
Grid(vec2 plane, float cell_size, float grid_opacity, bool filtered) | |
{ | |
vec2 coord = plane * cell_size; // Use the cell_size variable to set the distance between the lines. | |
vec2 derivative = fwidth(coord); | |
vec2 grid = abs(fract(coord - 0.5) - 0.5) / derivative; | |
float line = min(grid.x, grid.y); | |
float minimumZ = min(derivative.y, 1); | |
float minimumX = min(derivative.x, 1); | |
vec4 color = vec4(0.0, 0.0, 0.0, 1.0 - min(line, 1.0)); | |
color.w *= grid_opacity; | |
if (filtered) | |
{ | |
vec2 ddx = dFdx(coord); | |
vec2 ddy = dFdy(coord); | |
float filterWeight = AnalyticalBoxFilter(coord, ddx, ddy); | |
color *= filterWeight; | |
} | |
return color; | |
} | |
vec2 | |
ComputeDepth(vec3 position, float near_plane, float far_plane, mat4 view, mat4 projection) | |
{ | |
// Raw depth value of the fragment position in clip space. | |
vec4 clipSpacePosition = projection * view * vec4(position.xyz, 1.0); | |
float depth = (clipSpacePosition.z / clipSpacePosition.w); | |
// Linear depth of the fragment position in view space. | |
float shiftedDepth = depth * 2.0 - 1.0; // Put back between -1 and 1. | |
float linearDepth = (2.0 * near_plane * far_plane) / (far_plane + near_plane - shiftedDepth * (far_plane - near_plane)); // Get linear value between 0.01 and 100. | |
linearDepth = linearDepth / far_plane; // Normalize. | |
return vec2(depth, linearDepth); | |
} | |
/* ----------------------------------------------------------------- | |
MAIN | | |
----------------------------------------------------------------- */ | |
void | |
main() | |
{ | |
if (gridAxis == 0) // X | |
{ | |
float t = -VIEW_POS.x / (pass_FarPoint.x - VIEW_POS.x); | |
vec3 position = VIEW_POS + t * (pass_FarPoint - VIEW_POS); | |
vec2 depth = ComputeDepth(position, NEAR_PLANE, FAR_PLANE, VIEW, PROJECTION); | |
gl_FragDepth = ((gl_DepthRange.diff * depth.x) + gl_DepthRange.near + gl_DepthRange.far) / 2.0; // https://paroj.github.io/gltut/Illumination/Tut13%20Deceit%20in%20Depth.html | |
// Draw grid. | |
vec4 grid = Grid(position.yz, gridCellSize, gridOpacity, true); | |
float fading = max(0.0, 1 - max(abs(position.y - VIEW_POS.y), abs(position.z - VIEW_POS.z)) * 0.05); | |
out_CLR = grid; | |
out_CLR *= vec4(1.0, 1.0, 1.0, max(0.0, fading - float(t < 0.0))); // Hide the grid where it should not be visible. | |
} | |
else if (gridAxis == 1) // Y | |
{ | |
float t = -VIEW_POS.y / (pass_FarPoint.y - VIEW_POS.y); | |
vec3 position = VIEW_POS + t * (pass_FarPoint - VIEW_POS); | |
vec2 depth = ComputeDepth(position, NEAR_PLANE, FAR_PLANE, VIEW, PROJECTION); | |
gl_FragDepth = ((gl_DepthRange.diff * depth.x) + gl_DepthRange.near + gl_DepthRange.far) / 2.0; // https://paroj.github.io/gltut/Illumination/Tut13%20Deceit%20in%20Depth.html | |
// Draw grid. | |
vec4 grid = Grid(position.xz, gridCellSize, gridOpacity, true); | |
float fading = max(0.0, 1 - max(abs(position.x - VIEW_POS.x), abs(position.z - VIEW_POS.z)) * 0.05); | |
out_CLR = grid; | |
out_CLR *= vec4(1.0, 1.0, 1.0, max(0.0, fading - float(t < 0.0))); // Hide the grid where it should not be visible. | |
} | |
else // Z | |
{ | |
float t = -VIEW_POS.z / (pass_FarPoint.z - VIEW_POS.z); | |
vec3 position = VIEW_POS + t * (pass_FarPoint - VIEW_POS); | |
vec2 depth = ComputeDepth(position, NEAR_PLANE, FAR_PLANE, VIEW, PROJECTION); | |
gl_FragDepth = ((gl_DepthRange.diff * depth.x) + gl_DepthRange.near + gl_DepthRange.far) / 2.0; // https://paroj.github.io/gltut/Illumination/Tut13%20Deceit%20in%20Depth.html | |
// Draw grid. | |
vec4 grid = Grid(position.xy, gridCellSize, gridOpacity, true); | |
float fading = max(0.0, 1 - max(abs(position.x - VIEW_POS.x), abs(position.y - VIEW_POS.y)) * 0.05); | |
out_CLR = grid; | |
out_CLR *= vec4(1.0, 1.0, 1.0, max(0.0, fading - float(t < 0.0))); // Hide the grid where it should not be visible. | |
} | |
} |
This file contains 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 460 core | |
layout (triangles) in; | |
layout (triangle_strip, max_vertices = 4) out; | |
/* ----------------------------------------------------------------- | |
INPUTS | | |
----------------------------------------------------------------- */ | |
layout(location = 0) uniform mat4 VIEW; | |
layout(location = 1) uniform mat4 PROJECTION; | |
/* ----------------------------------------------------------------- | |
OUTPUTS | | |
----------------------------------------------------------------- */ | |
out vec3 pass_NearPoint; | |
out vec3 pass_FarPoint; | |
/* ----------------------------------------------------------------- | |
HELPERS | | |
----------------------------------------------------------------- */ | |
vec3 | |
ToWorldSpace(vec3 clip_space_position, mat4 view, mat4 projection) | |
{ | |
vec4 position = inverse(view) * inverse(projection) * vec4(clip_space_position.xyz, 1.0); | |
return position.xyz / position.w; | |
} | |
/* ----------------------------------------------------------------- | |
MAIN | | |
----------------------------------------------------------------- */ | |
void | |
main() | |
{ | |
// Clipped space coordinates for the quad. | |
vec4 clipSpaceCoords[4] = vec4[] | |
( | |
vec4(-1.0, -1.0, 0.0, 1.0), | |
vec4(1.0, -1.0, 0.0, 1.0), | |
vec4(-1.0, 1.0, 0.0, 1.0), | |
vec4(1.0, 1.0, 0.0, 1.0) | |
); | |
// Emit vertices for the quad | |
for (int i = 0; i < 4; ++i) | |
{ | |
vec4 p = clipSpaceCoords[i]; | |
gl_Position = p; // Using directly the clipped coordinates. | |
pass_NearPoint = ToWorldSpace(vec3(gl_Position.xy, -1.0), VIEW, PROJECTION); | |
pass_FarPoint = ToWorldSpace(vec3(gl_Position.xy, 1.0), VIEW, PROJECTION); | |
EmitVertex(); | |
} | |
EndPrimitive(); | |
} |
This file contains 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 460 core | |
void | |
main() { } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment