|
32 | 32 |
|
33 | 33 | import * as THREE from 'three/webgpu';
|
34 | 34 |
|
35 |
| - import { Fn, length, fract, vec4, positionWorld, smoothstep, max, abs, float, cameraPosition, clamp } from 'three/tsl'; |
| 35 | + import { Fn, length, fract, vec4, positionWorld, smoothstep, max, abs, float, fwidth } from 'three/tsl'; |
36 | 36 |
|
37 | 37 | import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
38 | 38 |
|
|
119 | 119 |
|
120 | 120 | // Ground plane
|
121 | 121 |
|
122 |
| - const material = new THREE.MeshStandardNodeMaterial(); |
| 122 | + const material = new THREE.MeshBasicNodeMaterial(); |
123 | 123 |
|
124 | 124 | const gridXZ = Fn( ( [ gridSize = float( 1.0 ), dotWidth = float( 0.1 ), lineWidth = float( 0.02 ) ] ) => {
|
125 | 125 |
|
126 | 126 | const worldPos = positionWorld;
|
127 |
| - const grid = fract( worldPos.xz.div( gridSize ) ); |
| 127 | + const coord = worldPos.xz.div( gridSize ); |
| 128 | + const grid = fract( coord ); |
128 | 129 |
|
129 |
| - // Distance-based antialiasing |
130 |
| - const distToCamera = length( worldPos.sub( cameraPosition ) ); |
131 |
| - const smoothing = clamp( distToCamera.div( 100.0 ), 0.01, 0.02 ); |
| 130 | + // Screen-space derivative for automatic antialiasing |
| 131 | + const fw = fwidth( coord ); |
| 132 | + const smoothing = max( fw.x, fw.y ).mul( 0.5 ); |
132 | 133 |
|
133 |
| - // Create dots at cell centers |
134 |
| - const dotDist = length( grid.sub( 0.5 ) ); |
135 |
| - const dots = smoothstep( dotWidth.add( smoothing ), dotWidth.sub( smoothing ), dotDist ); |
| 134 | + // Create squares at cell centers |
| 135 | + const squareDist = max( abs( grid.x.sub( 0.5 ) ), abs( grid.y.sub( 0.5 ) ) ); |
| 136 | + const dots = smoothstep( dotWidth.add( smoothing ), dotWidth.sub( smoothing ), squareDist ); |
136 | 137 |
|
137 |
| - // Create grid lines |
| 138 | + // Create grid lines with derivative-based antialiasing |
138 | 139 | const lineX = smoothstep( lineWidth.add( smoothing ), lineWidth.sub( smoothing ), abs( grid.x.sub( 0.5 ) ) );
|
139 | 140 | const lineZ = smoothstep( lineWidth.add( smoothing ), lineWidth.sub( smoothing ), abs( grid.y.sub( 0.5 ) ) );
|
140 | 141 | const lines = max( lineX, lineZ );
|
|
150 | 151 | } );
|
151 | 152 |
|
152 | 153 | // Create grid pattern
|
153 |
| - const gridPattern = gridXZ( 1.0, 0.04, 0.01 ); |
| 154 | + const gridPattern = gridXZ( 1.0, 0.03, 0.005 ); |
154 | 155 | const baseColor = vec4( 1.0, 1.0, 1.0, 0.0 );
|
155 |
| - const gridColor = vec4( 0.2, 0.2, 0.2, 1.0 ); |
| 156 | + const gridColor = vec4( 0.5, 0.5, 0.5, 1.0 ); |
156 | 157 |
|
157 | 158 | // Mix base color with grid lines
|
158 | 159 | material.colorNode = gridPattern.mix( baseColor, gridColor ).mul( radialGradient( 30.0, 20.0 ) );
|
159 | 160 | material.transparent = true;
|
160 | 161 |
|
161 |
| - const plane = new THREE.Mesh( new THREE.CircleGeometry( 50 ), material ); |
| 162 | + const plane = new THREE.Mesh( new THREE.CircleGeometry( 40 ), material ); |
162 | 163 | plane.rotation.x = - Math.PI / 2;
|
163 | 164 | plane.renderOrder = - 1;
|
164 | 165 | scene.add( plane );
|
|
0 commit comments