eulerjs API / @eulerjs/marine / sumOfSinesShaderChunk
sumOfSinesShaderChunk
ts
const sumOfSinesShaderChunk: "\nuniform float waveTime;\nuniform float wavePeakSharpness;\nuniform float wavePeakOffset;\nuniform float waveShapeMean;\nuniform float waveMinSamplesPerPeriod;\nuniform float waveFullSamplesPerPeriod;\nuniform float waveAmplitude[WAVE_COUNT];\nuniform float waveFrequency[WAVE_COUNT];\nuniform float waveAngularFrequency[WAVE_COUNT];\nuniform vec2 waveDirection[WAVE_COUNT];\n\nfloat wavePhase(int index, vec2 point) {\n return waveFrequency[index] * dot(waveDirection[index], point) + waveAngularFrequency[index] * waveTime;\n}\n\n// 0 when a grid with this spacing has fewer than minSamples samples per period of the wave, 1 from fullSamples.\nfloat waveResolvability(int index, float spacing, float minSamples, float fullSamples) {\n float period = 6.283185307179586 / waveFrequency[index];\n return smoothstep(minSamples, fullSamples, period / spacing);\n}\n\nfloat waveHeight(int index, vec2 point) {\n return waveAmplitude[index] * (exp(wavePeakSharpness * sin(wavePhase(index, point)) - wavePeakOffset) - waveShapeMean);\n}\n\n// Exact gradient of waveHeight with respect to the point.\nvec2 waveSlope(int index, vec2 point) {\n float phase = wavePhase(index, point);\n float magnitude = wavePeakSharpness * waveAmplitude[index] * waveFrequency[index] * cos(phase)\n * exp(wavePeakSharpness * sin(phase) - wavePeakOffset);\n return waveDirection[index] * magnitude;\n}\n\n// How far wave index pushes a point per unit of its direction: its slope with the sharpness\n// left out of the exponent, which keeps the warp gentle.\nfloat waveWarpSlope(int index, vec2 point) {\n float phase = wavePhase(index, point);\n return wavePeakSharpness * waveAmplitude[index] * waveFrequency[index] * cos(phase) * exp(sin(phase) - wavePeakOffset);\n}\n\n// Surface point for the undisplaced grid position on a mesh whose vertices are spacing apart:\n// (displaced x, height, displaced z). Waves the mesh can't resolve are faded out.\nvec3 sumOfSinesSurface(vec2 grid, float spacing) {\n vec2 displaced = grid;\n float height = 0.0;\n float previousWeight = 1.0;\n for (int index = 0; index < WAVE_COUNT; index++) {\n float weight = waveResolvability(index, spacing, waveMinSamplesPerPeriod, waveFullSamplesPerPeriod);\n if (weight <= 0.0 && previousWeight <= 0.0) break;\n if (index > 0) {\n int previous = index - 1;\n displaced.x += previousWeight * waveWarpSlope(previous, displaced) * waveDirection[previous].x;\n displaced.y += previousWeight * waveWarpSlope(previous, displaced) * waveDirection[previous].y;\n }\n height += weight * waveHeight(index, grid);\n previousWeight = weight;\n }\n return vec3(displaced.x, height, displaced.y);\n}\n";Defined in: packages/marine/src/waves/sumOfSinesShader.ts:8
GLSL that evaluates a SumOfSines exactly as SumOfSines does on the CPU. Needs the define WAVE_COUNT (= waves.waves.length) and the uniforms from createSumOfSinesUniforms.
