1+ // CODE Room Floor Shader (Tim Rodenbroeker style)
2+ // Generative grid pattern with dynamic highlights based on player position
3+
4+ uniform float time;
5+ uniform vec3 playerPos;
6+ varying vec2 vUv;
7+
8+ // Pattern constants
9+ #define GRID_SIZE 20.0
10+ #define SMALL_GRID_SIZE 4.0
11+ #define LINE_WIDTH 0.03
12+ #define NODE_RADIUS 0.15
13+ #define MAX_NODES 5
14+
15+ // Helper for anti-aliasing
16+ float aastep(float threshold, float value) {
17+ float afwidth = length (vec2 (dFdx (value), dFdy (value))) * 0.70710678118654757 ;
18+ return smoothstep (threshold- afwidth, threshold+ afwidth, value);
19+ }
20+
21+ // Create a grid pattern
22+ float grid(vec2 uv, float size, float lineWidth) {
23+ vec2 grid = fract (uv * size);
24+ vec2 smoothWidth = vec2 (lineWidth) / size;
25+ vec2 gridLines = smoothstep (vec2 (0.0 ), smoothWidth, grid) *
26+ (1.0 - smoothstep (vec2 (1.0 ) - smoothWidth, vec2 (1.0 ), grid));
27+ return max (gridLines.x, gridLines.y);
28+ }
29+
30+ // Create a circular node
31+ float node(vec2 uv, vec2 position, float radius) {
32+ float dist = distance (uv, position);
33+ return 1.0 - smoothstep (radius - 0.01 , radius, dist);
34+ }
35+
36+ // Generate stable random value
37+ float random(vec2 st) {
38+ return fract (sin (dot (st.xy, vec2 (12.9898 , 78.233 ))) * 43758.5453123 );
39+ }
40+
41+ void main() {
42+ // Get normalized UV coordinates
43+ vec2 uv = vUv;
44+
45+ // Create base grid
46+ float mainGrid = grid(uv, GRID_SIZE, LINE_WIDTH);
47+ float subGrid = grid(uv, GRID_SIZE * SMALL_GRID_SIZE, LINE_WIDTH * 0.5 );
48+
49+ // Calculate base color from grid
50+ vec3 baseColor = vec3 (0.1 , 0.1 , 0.12 );
51+ vec3 gridColor = vec3 (0.34 , 0.85 , 0.53 ); // green similar to 0x34a853
52+ vec3 color = mix (baseColor, gridColor, mainGrid * 0.7 );
53+ color = mix (color, gridColor * 0.7 , subGrid * 0.3 );
54+
55+ // Add nodes at grid intersections
56+ for (int i = 0 ; i < MAX_NODES; i++ ) {
57+ // Stable node positions based on index
58+ float ix = float (i) / float (MAX_NODES);
59+ vec2 nodePos = vec2 (
60+ 0.1 + 0.8 * fract (sin (ix * 234.5 ) * 43758.5453123 ),
61+ 0.1 + 0.8 * fract (cos (ix * 598.3 ) * 13758.5123891 )
62+ );
63+
64+ // Make nodes pulse based on time
65+ float pulse = 0.5 + 0.5 * sin (time * (0.5 + ix) + ix * 10.0 );
66+ float nodeSize = NODE_RADIUS * (0.7 + 0.3 * pulse);
67+
68+ // Create node and add to color
69+ float nodeValue = node(uv, nodePos, nodeSize);
70+ vec3 nodeColor = mix (
71+ gridColor,
72+ vec3 (0.7 , 0.9 , 0.8 ),
73+ pulse
74+ );
75+ color = mix (color, nodeColor, nodeValue * pulse);
76+
77+ // Add subtle glow around node
78+ float glowRadius = nodeSize * 3.0 ;
79+ float glow = (1.0 - smoothstep (nodeSize, glowRadius, distance (uv, nodePos))) * 0.15 * pulse;
80+ color += nodeColor * glow;
81+ }
82+
83+ // Add player highlight effect
84+ vec2 playerUV = playerPos.xz / 20.0 + vec2 (0.5 ); // Convert player position to UV space
85+ float distToPlayer = distance (uv, playerUV);
86+
87+ // Create radial highlight around player position
88+ float playerHighlight = 1.0 - smoothstep (0.0 , 0.2 , distToPlayer);
89+ color = mix (color, gridColor * 1.5 , playerHighlight * 0.3 );
90+
91+ // Add subtle ripple effect from player
92+ float ripple = sin (distToPlayer * 20.0 - time * 2.0 ) * 0.5 + 0.5 ;
93+ ripple *= smoothstep (0.5 , 0.0 , distToPlayer); // Fade out with distance
94+ color += gridColor * ripple * 0.15 ;
95+
96+ // Output final color
97+ gl_FragColor = vec4 (color, 1.0 );
98+ }
0 commit comments