VR Grid floor with falloff based on XRCamera position.
A nicely antialiased grid shader that calculates the falloff from the center of the XRCamera.
(Finally updated with Kimau’s comments).
Shader code
// Inspired and heavily copied code from this excellent post:
// https://bgolus.medium.com/the-best-darn-grid-shader-yet-727f9278b9d8
shader_type spatial;
render_mode blend_mix;
uniform vec3 baseColor = vec3(0.1,0.1,0.1);
uniform float scaleFactor = 50.0;
uniform vec2 lineWidth = vec2(0.01, 0.01);
uniform float falloffEnd = 20.0; // End of the falloff
uniform float falloffRate = 1.0; // Controls how quickly the falloff happens
float pristineGrid(vec2 uv, vec2 _lineWidth) {
vec2 ddx = dFdx(uv);
vec2 ddy = dFdy(uv);
vec2 uvDeriv = vec2(length(vec2(ddx.x, ddy.x)), length(vec2(ddx.y, ddy.y)));
bvec2 invertLine = bvec2(_lineWidth.x > 0.5, _lineWidth.y > 0.5);
vec2 targetWidth = vec2(
invertLine.x ? .0 - _lineWidth.x : _lineWidth.x,
invertLine.y ? 1.0 - _lineWidth.y : _lineWidth.y
);
vec2 drawWidth = clamp(targetWidth, uvDeriv, vec2(0.5));
vec2 lineAA = uvDeriv * 1.5;
vec2 gridUV = abs(fract(uv) * 2.0 - 1.0);
gridUV.x = invertLine.x ? gridUV.x : 1.0 - gridUV.x;
gridUV.y = invertLine.y ? gridUV.y : 1.0 - gridUV.y;
vec2 grid2 = smoothstep(drawWidth + lineAA, drawWidth - lineAA, gridUV);
grid2 *= clamp(targetWidth / drawWidth, 0.0, 1.0);
grid2 = mix(grid2, targetWidth, clamp(uvDeriv * 2.0 - 1.0, 0.0, 1.0));
grid2.x = invertLine.x ? 1.0 - grid2.x : grid2.x;
grid2.y = invertLine.y ? 1.0 - grid2.y : grid2.y;
return mix(grid2.x, 1.0, grid2.y);
}
void fragment() {
vec2 scaledUV = UV * scaleFactor;
// Generate the grid pattern
float gridValue = pristineGrid(scaledUV, lineWidth);
// Calculate distance falloff using CAMERA_POSITION_WORLD
vec3 worldPos = (INV_VIEW_MATRIX * vec4(VERTEX, 1.0)).xyz;
vec3 cameraPos = CAMERA_POSITION_WORLD;
float centerDistance = length(worldPos.xz - cameraPos.xz);
float falloffStart = 0.0; // Start of the falloff
// Apply falloffRate to control the speed of falloff
float falloffProgress = (centerDistance - falloffStart) / (falloffEnd - falloffStart);
float falloff = 1.0 - pow(clamp(falloffProgress, 0.0, 1.0), falloffRate);
// Apply the distance falloff to the grid value
float finalGridValue = gridValue * falloff;
ALBEDO = baseColor * vec3(finalGridValue);
ALPHA = finalGridValue;
}
You can just use the global CAMERA_POSITION_WORLD.
Also you prob should make uniforms
uniform float grid_scale = 50.0;
uniform float line_width = 0.01;
Ohh, didn’t know that. Will try it out and update the shader, thanks!
Yeah I should make the uniforms 😉