Better water
This commit is contained in:
@@ -92,19 +92,23 @@ void Water::init()
|
||||
float w = 1000.0f;
|
||||
// mWindow->addListener(this);
|
||||
create_cameras();
|
||||
#if 0
|
||||
Ogre::MeshPtr water_plane =
|
||||
Ogre::MeshManager::getSingleton().createPlane(
|
||||
"water",
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
mWaterPlane, w, w, 100, 100, true, 1, 100, 100,
|
||||
Ogre::Vector3::UNIT_Z);
|
||||
#endif
|
||||
if (!Ogre::MeshLodGenerator::getSingletonPtr())
|
||||
new Ogre::MeshLodGenerator();
|
||||
|
||||
#if 0
|
||||
Ogre::LodConfig lod_config(water_plane);
|
||||
lod_config.createGeneratedLodLevel(w, 0.5f);
|
||||
lod_config.createGeneratedLodLevel(w * 2.0, 0.25f);
|
||||
Ogre::MeshLodGenerator::getSingleton().generateLodLevels(lod_config);
|
||||
#endif
|
||||
|
||||
Ogre::Vector3 positions[] = { { 0, 0, 0 }, { 0, 0, -1 }, { 0, 0, 1 },
|
||||
{ -1, 0, 0 }, { 1, 0, 0 }, { -1, 0, -1 },
|
||||
@@ -117,6 +121,7 @@ void Water::init()
|
||||
auto mat2 = Ogre::MaterialManager::getSingleton().getByName("Water/Below");
|
||||
mat2->load();
|
||||
mat2->setReceiveShadows(false);
|
||||
#if 0
|
||||
|
||||
for (i = 0; i < (int)sizeof(positions) / (int)sizeof(positions[0]);
|
||||
i++) {
|
||||
@@ -133,6 +138,14 @@ void Water::init()
|
||||
water_lod1->setVisibilityFlags(WATER_MASK);
|
||||
mWaterMeshes.push_back(water_lod1);
|
||||
}
|
||||
#endif
|
||||
Ogre::Entity *water_ent = mScnMgr->createEntity("Ocean", "sea.glb");
|
||||
water_ent->setVisibilityFlags(WATER_MASK);
|
||||
water_ent->setCastShadows(true);
|
||||
water_ent->setMaterialName("Water/Above");
|
||||
water_ent->setMaterial(mat);
|
||||
mWaterNode->attachObject(water_ent);
|
||||
mWaterMeshes.push_back(water_ent);
|
||||
}
|
||||
|
||||
void Water::createWater(Ogre::RenderWindow * window, Ogre::Camera *camera)
|
||||
@@ -150,13 +163,18 @@ void Water::createWater(Ogre::RenderWindow * window, Ogre::Camera *camera)
|
||||
void Water::updateWater(float delta)
|
||||
{
|
||||
int i;
|
||||
if (mCameraPosition.squaredDistance(mCameraNode->getPosition()) >
|
||||
200.0f * 200.0f) {
|
||||
mCameraPosition = mCameraNode->getPosition();
|
||||
Ogre::Vector3 waterPosition = mCameraPosition;
|
||||
waterPosition.y = 0;
|
||||
mWaterNode->setPosition(waterPosition);
|
||||
}
|
||||
Ogre::Vector3 mCameraPos = mCameraNode->_getDerivedPosition();
|
||||
Ogre::Vector3 waterPos = mWaterNode->_getDerivedPosition();
|
||||
mCameraPos.y = 0;
|
||||
waterPos.y = 0;
|
||||
|
||||
Ogre::Vector3 d = mCameraPos - waterPos;
|
||||
// Ogre::Vector3 waterPosition = mCameraPos;
|
||||
// mWaterNode->setPosition(waterPosition);
|
||||
if (d.squaredLength() < 100.0f * 100.0f)
|
||||
mWaterNode->translate(d * 3.0f * delta);
|
||||
else
|
||||
mWaterNode->translate(d);
|
||||
if (mAbove) {
|
||||
if (mCameraNode->getPosition().y < 0) {
|
||||
mAbove = false;
|
||||
|
||||
@@ -4,21 +4,29 @@ OGRE_NATIVE_GLSL_VERSION_DIRECTIVE
|
||||
SAMPLER2D(reflectMap, 0);
|
||||
// SAMPLER2D(refractMap, 1);
|
||||
OGRE_UNIFORMS(
|
||||
uniform float renderTargetFlipping;
|
||||
uniform vec4 viewportSize;
|
||||
uniform f32vec4 cameraPosition;
|
||||
)
|
||||
MAIN_PARAMETERS
|
||||
IN(highp vec4 projectionCoord, TEXCOORD4)
|
||||
IN(f32vec3 positionWS, TEXCOORD7)
|
||||
IN(f32vec3 positionWS, TEXCOORD0)
|
||||
IN(f32vec3 vnormal, TEXCOORD1)
|
||||
MAIN_DECLARATION
|
||||
{
|
||||
float flip = -renderTargetFlipping;
|
||||
vec2 screenUV = gl_FragCoord.xy / viewportSize.xy;
|
||||
|
||||
#if !defined(OGRE_HLSL) && !defined(VULKAN)
|
||||
screenUV.y = 1.0 - screenUV.y * 0.6 - 0.2;
|
||||
// vec2 final = projectionCoord.xy / projectionCoord.w;
|
||||
#else
|
||||
screenUV.y = screenUV.y * 0.6 + 0.2;
|
||||
#endif
|
||||
float depth = saturate(length(positionWS - cameraPosition.xyz) * 0.01);
|
||||
vec4 reflectionColour = texture2D(reflectMap, screenUV * vec2(0.5, 1.0));
|
||||
vec4 refractionColour = texture2D(reflectMap, screenUV * vec2(0.5, 1.0) + vec2(0.5, 0.0));
|
||||
vec4 result = mix(mix(reflectionColour, refractionColour, 0.5), vec4(0.0, 1.0, 1.0, 1.0), depth);
|
||||
float mul = dot(vec3(0.0, 1.0, 0.0), vnormal);
|
||||
result = result * mul;
|
||||
result.a = 1.0;
|
||||
gl_FragColor = result;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ material Water/Above
|
||||
{
|
||||
pass
|
||||
{
|
||||
lighting on
|
||||
ambient 1.0 1.0 1.0 1.0
|
||||
diffuse 0.0 0.2 0.5 1.0
|
||||
cull_hardware none
|
||||
@@ -108,6 +109,11 @@ material Water/Above
|
||||
*/
|
||||
}
|
||||
}
|
||||
rtshader_system
|
||||
{
|
||||
// Override lighting stage with per pixel lighting.
|
||||
lighting_stage per_pixel
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -117,6 +123,7 @@ material Water/Below
|
||||
{
|
||||
pass
|
||||
{
|
||||
lighting on
|
||||
ambient 1.0 1.0 1.0 1.0
|
||||
diffuse 0.0 0.2 0.5 1.0
|
||||
cull_hardware none
|
||||
@@ -166,6 +173,11 @@ material Water/Below
|
||||
*/
|
||||
}
|
||||
}
|
||||
rtshader_system
|
||||
{
|
||||
// Override lighting stage with per pixel lighting.
|
||||
lighting_stage per_pixel
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -22,6 +22,7 @@ fragment_program Water/water_fp glsl glsles glslang hlsl
|
||||
source water.frag
|
||||
default_params
|
||||
{
|
||||
param_named_auto renderTargetFlipping render_target_flipping
|
||||
param_named_auto cameraPosition camera_position
|
||||
param_named_auto ambient surface_ambient_colour
|
||||
param_named_auto diffuse surface_diffuse_colour
|
||||
@@ -61,11 +62,14 @@ vertex_program Water/water_vp glsl glsles glslang hlsl
|
||||
param_named_auto worldViewProj worldviewproj_matrix
|
||||
param_named_auto textureProjMatrix texture_worldviewproj_matrix 0
|
||||
param_named_auto eyePosition camera_position_object_space
|
||||
param_named_auto normalMatrix normal_matrix
|
||||
param_named_auto worldView worldview_matrix
|
||||
param_named_auto viewProj viewproj_matrix
|
||||
param_named BumpScale float 0.2
|
||||
param_named textureScale float2 25 26
|
||||
param_named bumpSpeed float2 0.015 0.005
|
||||
param_named_auto time time_0_x 100.0
|
||||
param_named waveFreq float 0.028
|
||||
param_named waveFreq float 0.5
|
||||
param_named waveAmp float 1.0
|
||||
param_named scroll float 1
|
||||
param_named scale float 1
|
||||
|
||||
134
water/water.vert
134
water/water.vert
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user