uniform sampler2D height; uniform float scale; uniform float size; uniform float uTime; uniform float glitch; uniform vec3 mouse; uniform vec4 waveOpts; uniform bool isWave; uniform bool IsEarthHeightMap; varying vec3 vColor; varying vec3 vDeltaPosition; varying vec2 vUv; varying float vBackfacing; vec3 hsb2rgb(in vec3 c) { vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0); rgb = rgb * rgb * (3.0 - 2.0 * rgb); return c.z * mix(vec3(1.0), rgb, c.y); } vec3 calcWave(vec3 position) { float waveIntensity = waveOpts.x; float waveAmplitude = waveOpts.y; float waveFrequency = waveOpts.z; float waveSpeed = waveOpts.w; float height = 0.2; float sharpness = 1.5; vec3 p = position + mouse; float r = length(p) * 0.9; vec3 col = hsb2rgb(vec3(0.24, 0.7, 0.4)); float a = pow(r, 2.0); float b = sin(r * 0.8 - 2.6); float c = sin(r - 0.010); float s = sin(a - waveIntensity * 2.8 + b) * c; col = vec3(abs(1.0 / (s * (sharpness * 10.0))) - 0.01); vec3 transformed = position + normal * min(col * height, height + 0.005); return mix(position, transformed, waveIntensity); } void main() { vUv = uv; vColor = color; float time = uTime * 0.0007; float f = gln_normalize(gln_simplex((vec3(position + time) * 1000.0))); vec3 glitchPosition = position + (f * 0.05 * normal); vec3 glitchMix = mix(position, glitchPosition, glitch); vec3 transformed = calcWave(glitchMix); vDeltaPosition = transformed - glitchMix; if (isWave) { if (!IsEarthHeightMap) { transformed += gln_normalize(gln_perlin((transformed * 8.0) + (uTime * 0.2) * vec3(1.0, 0.0, 0.8))) * gln_normalize(gln_perlin((transformed * 5.0) + (uTime * 0.4))) * normal * 0.05; } else { vec4 h = texture2D(height, uv); transformed += normal * h.r * 0.1; } } vec4 mvPosition = modelViewMatrix * vec4(transformed, 1.0); vec3 matrixNormal = normalMatrix * normal; vBackfacing = step(0., dot(-normalize(mvPosition.xyz), normalize(matrixNormal))); gl_PointSize = size * (scale / length(mvPosition.xyz)); gl_Position = projectionMatrix * mvPosition; }