Better water

This commit is contained in:
2025-07-07 00:16:48 +03:00
parent c72b1cf35e
commit 4a790a060a
9 changed files with 139 additions and 84 deletions

View File

@@ -21,7 +21,6 @@ Comments:
******************************************************************************/
OGRE_NATIVE_GLSL_VERSION_DIRECTIVE
#include <OgreUnifiedShader.h>
#line 3
OGRE_UNIFORMS(
uniform vec3 eyePosition;
@@ -32,6 +31,8 @@ uniform highp float time;
uniform float waveFreq;
uniform float waveAmp;
uniform mat4 world;
uniform mat4 viewProj;
uniform mat4 worldView;
uniform mat4 worldViewProj;
uniform mat4 textureProjMatrix;
uniform mat3 normalMatrix;
@@ -39,78 +40,77 @@ uniform float scale; // the amount to scale the noise texture by
uniform float scroll; // the amount by which to scroll the noise
uniform float noise; // the noise perturb as a factor of the time
)
// wave functions
struct Wave {
float freq; // 2*PI / wavelength
float amp; // amplitude
float phase; // speed * 2*PI / wavelength
vec2 dir;
};
#line 41
//vec4 wave_a = vec4(1.0, 1.0, 0.35, 3.0); // xy = Direction, z = Steepness, w = Length
f32vec4 wave_a = vec4(1.0, 1.0, 0.55, 24.3); // xy = Direction, z = Steepness, w = Length
f32vec4 wave_b = vec4(1.0, 0.6, 0.29, 12.55); // xy = Direction, z = Steepness, w = Length
f32vec4 wave_c = vec4(1.0, 1.41, 0.11, 10.8); // xy = Direction, z = Steepness, w = Length
f32vec4 wave(f32vec4 parameter, f32vec2 position, float32_t t, inout f32vec3 tangent, inout f32vec3 binormal)
{
#line 51
f32vec2 dir = normalize(parameter.xy);
float32_t wave_steepness = parameter.z;
float32_t wave_length = parameter.w;
float32_t freq = 2.0 * 3.14159265359 / wave_length;
float32_t phase = sqrt(9.8 / freq);
float32_t f = freq * (dot(dir, position) - phase * t);
float32_t a = wave_steepness / freq;
tangent += normalize(
vec3(1.0 - dir.x * dir.x * (wave_steepness * sin(f)), dir.x * (wave_steepness * cos(f)), -dir.x * dir.y * (wave_steepness * sin(f)))
);
binormal += normalize(
vec3( -dir.x * dir.y * (wave_steepness * sin(f)), dir.y * (wave_steepness * cos(f)), 1.0-dir.y * dir.y * (wave_steepness * sin(f)))
);
f32vec4 result = vec4(dir.x * a * cos(f), a * sin(f) * 0.25, dir.y * (a * cos(f)), 0.0);
return result;
}
vec4 wave2(vec4 parameter, vec2 position, float t, inout vec3 tangent, inout vec3 binormal)
{
vec2 dir = normalize(parameter.xy);
float wave_steepness = parameter.z;
float wave_length = parameter.w;
float freq = 2.0 * 3.14159265359 / wave_length;
float phase = sqrt(9.8 / freq);
float f = freq * (dot(dir, position) - phase * t);
float a = wave_steepness / freq;
float m = freq * (position.x - phase * t);
float n = freq * (position.y - phase * t);
tangent += normalize(
vec3(1.0-sin(m), cos(m), -sin(m))
);
binormal += normalize(
vec3( -sin(n), cos(n), 1.0-sin(n))
);
return vec4(dir.x * a * cos(f), a * sin(f) * 0.25, dir.y * (a * cos(f)), 0.0);
}
MAIN_PARAMETERS
IN(vec4 vertex, POSITION)
IN(vec3 normal, NORMAL)
// IN(vec3 tangent, TANGENT)
IN(vec3 uv0, TEXCOORD0)
OUT(mat3 rotMatrix, TEXCOORD1)
//OUT(vec4 bumpCoordA, TEXCOORD2)
//OUT(vec4 bumpCoordB, TEXCOORD3)
// OUT(vec3 noiseCoord, TEXCOORD4)
OUT(highp vec4 projectionCoord, TEXCOORD4)
//OUT(vec3 eyeDir, TEXCOORD5)
//OUT(vec3 oNormal, TEXCOORD6)
OUT(f32vec3 positionWS, TEXCOORD7)
OUT(f32vec3 positionWS, TEXCOORD0)
OUT(f32vec3 vnormal, TEXCOORD1)
OUT(f32vec3 vbinormal, TEXCOORD2)
OUT(f32vec3 vtangent, TEXCOORD3)
OUT(float vertex_height, TEXCOORD4)
MAIN_DECLARATION
{
#if 1
#define NWAVES 4
Wave wave[NWAVES];
wave[0] = Wave( waveFreq, waveAmp, 0.5, vec2(-1.0, 0.0) );
wave[1] = Wave( 3.0 * waveFreq, 0.33 * waveAmp, 1.7, vec2(-0.7, 0.7) );
wave[2] = Wave( 7.5 * waveFreq, 0.15 * waveAmp, 2.9, vec2(-0.2, 0.2) );
wave[3] = Wave( 11.5 * waveFreq, 0.075 * waveAmp, 5.9, vec2(-0.2, 0.3) );
vec4 P = worldViewProj * vertex;
vec4 R = vertex;
// sum waves
float ddx = 0.0, ddy = 0.0;
float deriv;
float angle;
projectionCoord = mul(textureProjMatrix, vertex);
// Noise map coords
// noiseCoord.xy = (uv0.xy + (time * scroll)) * scale;
// noiseCoord.z = noise * time;
// wave synthesis using two sine waves at different frequencies and phase shift
for(int i = 0; i<NWAVES; ++i)
{
angle = dot(wave[i].dir, P.xz) * wave[i].freq + time * wave[i].phase;
P.y += wave[i].amp * sin( angle );
// calculate derivate of wave function
deriv = wave[i].freq * wave[i].amp * cos(angle);
ddx -= deriv * wave[i].dir.x;
ddy -= deriv * wave[i].dir.y;
}
R.y = P.y;
// compute the 3x3 transform from tangent space to object space
// compute tangent basis
vec3 T = normalize(vec3(1.0, ddy, 0.0)) * BumpScale;
vec3 B = normalize(vec3(0.0, ddx, 1.0)) * BumpScale;
vec3 N = normalize(vec3(ddx, 1.0, ddy));
rotMatrix = mat3(T, B, N);
gl_Position = P;
// calculate texture coordinates for normal map lookup
#if 0
bumpCoordA.xy = uv0.xy * textureScale + time * bumpSpeed;
bumpCoordA.zw = uv0.xy * textureScale * 2.0 + time * bumpSpeed * 4.0;
bumpCoordB.xy = uv0.xy * textureScale * 4.0 + time * bumpSpeed * 8.0;
#endif
// eyeDir = normalize(R.xyz - eyePosition);
// oNormal = normalize(normal + N);
f32vec4 position = vec4(mul(world, vertex).xyz, 1.0);
f32vec3 vertex_position = position.xyz;
f32vec3 tang = vec3(0.0, 0.0, 0.0);
f32vec3 bin = vec3(0.0, 0.0, 0.0);
position += wave(wave_a, vertex_position.xz, time, tang, bin);
position += wave(wave_b, vertex_position.xz, time, tang, bin);
position += wave(wave_c, vertex_position.xz, time, tang, bin);
vtangent = tang;
vbinormal = bin;
vertex_position = position.xyz;
// vnormal = normalize(mul(mat3(world), cross(vbinormal, vtangent)));
vnormal = normalize(cross(vbinormal, vtangent));
// vnormal = normalize(vec3(0.0, 1.0, 0.0));
// gl_Position = mul(worldViewProj, vertex);
gl_Position = mul(viewProj, position);
positionWS = mul(world, vertex).xyz;
#else
gl_Position = worldViewProj * vertex;
projectionCoord = mul(textureProjMatrix, vertex);
#endif
}