Variable instancingWindVertexShaderConst
instancingWindVertexShader: "\n attribute vec3 position;\n attribute vec3 normal;\n attribute float instanceRandom;\n \n uniform float uTime;\n uniform vec3 uCameraPosition;\n uniform float uWindStrength;\n uniform float uLodDistance;\n uniform bool uEnableWind;\n \n varying vec3 vNormal;\n varying vec3 vWorldPos;\n \n // Noise functions for wind variation\n float hash(float n) {\n return fract(sin(n) * 43758.5453);\n }\n \n float hash3(vec3 p) {\n return hash(p.x + p.y * 157.0 + p.z * 113.0);\n }\n \n float noise3D(vec3 p) {\n vec3 i = floor(p);\n vec3 f = fract(p);\n f = f * f * (3.0 - 2.0 * f);\n \n float n000 = hash3(i);\n float n100 = hash3(i + vec3(1.0, 0.0, 0.0));\n float n010 = hash3(i + vec3(0.0, 1.0, 0.0));\n float n110 = hash3(i + vec3(1.0, 1.0, 0.0));\n float n001 = hash3(i + vec3(0.0, 0.0, 1.0));\n float n101 = hash3(i + vec3(1.0, 0.0, 1.0));\n float n011 = hash3(i + vec3(0.0, 1.0, 1.0));\n float n111 = hash3(i + vec3(1.0, 1.0, 1.0));\n \n float nx00 = mix(n000, n100, f.x);\n float nx10 = mix(n010, n110, f.x);\n float nx01 = mix(n001, n101, f.x);\n float nx11 = mix(n011, n111, f.x);\n \n float nxy0 = mix(nx00, nx10, f.y);\n float nxy1 = mix(nx01, nx11, f.y);\n \n return mix(nxy0, nxy1, f.z);\n }\n \n // Quaternion operations\n vec3 quatRotate(vec4 q, vec3 v) {\n return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\n }\n \n vec4 quatMul(vec4 q1, vec4 q2) {\n return vec4(\n q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y,\n q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x,\n q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w,\n q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z\n );\n }\n \n void main() {\n vec3 localPos = position;\n vec3 localNormal = normal;\n \n // Get instance position from model matrix\n vec3 instancePosition = (modelMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz;\n \n // Calculate LOD scale based on distance\n float distToCamera = length(instancePosition - uCameraPosition);\n float lodScale = 1.0 - clamp((distToCamera - uLodDistance * 0.5) / (uLodDistance * 0.5), 0.0, 1.0);\n \n // Hide if too far\n if (lodScale < 0.01) {\n gl_Position = vec4(0.0, 0.0, -1.0, 1.0);\n return;\n }\n \n // Apply LOD scale\n localPos *= lodScale;\n \n // Calculate wind effect on GPU\n if (uEnableWind && uWindStrength > 0.0) {\n // Wind phase with instance-specific variation\n float windPhase = uTime * 2.0 + instancePosition.x * 0.1 + instancePosition.z * 0.1 + instanceRandom * 6.28;\n \n // Wind noise for variation\n float windNoise = noise3D(instancePosition * 0.05 + vec3(uTime * 0.5));\n \n // Calculate bend angle\n float bendAngle = sin(windPhase) * uWindStrength * 0.3 * (0.5 + 0.5 * windNoise);\n \n // Bend axis (perpendicular to wind direction)\n vec3 bendAxis = normalize(vec3(-cos(windPhase), 0.0, sin(windPhase)));\n \n // Apply wind rotation\n float halfAngle = bendAngle * 0.5;\n vec4 windQuat = vec4(bendAxis * sin(halfAngle), cos(halfAngle));\n localPos = quatRotate(windQuat, localPos);\n localNormal = quatRotate(windQuat, localNormal);\n }\n \n vNormal = normalize(normalMatrix * localNormal);\n vWorldPos = (modelMatrix * vec4(localPos, 1.0)).xyz;\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4(localPos, 1.0);\n }\n" = ...
GPU-Driven Instancing Wind/LOD Shader
Vertex shader for drei's Instances with wind and LOD support