Skip to content

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.

Released under the MIT License.