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;
}
Tags
grid, VR, XR
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

Circle Mask (with Feathering & Position)

Quick Procedural Floor Tiles

Dashed Grid (The Best Darn Grid Shader (Yet))

Subscribe
Notify of
guest

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Kimau
Kimau
9 months ago

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;