From 7abd204a5e23641099331a0bafe0faa7bc2f686c Mon Sep 17 00:00:00 2001 From: XProger Date: Fri, 3 Feb 2017 07:01:13 +0300 Subject: [PATCH] #23 water --- src/lara.h | 2 +- src/level.h | 42 +++++++++++++++++--------------- src/shader.h | 4 +-- src/trigger.h | 4 +-- src/water.glsl | 66 +++++++++++++++++++++----------------------------- 5 files changed, 56 insertions(+), 62 deletions(-) diff --git a/src/lara.h b/src/lara.h index 9b5f9ea..3ff13be 100644 --- a/src/lara.h +++ b/src/lara.h @@ -1421,7 +1421,7 @@ struct Lara : Character { game->waterDrop(animation.getJoints(getMatrix(), 14).pos, 96.0f, 0.01f); } else { if (animation.frameIndex % 4 == 0) - game->waterDrop(animation.getJoints(getMatrix(), 14).pos, 128.0f, 0.05f); + game->waterDrop(animation.getJoints(getMatrix(), 14).pos, 96.0f, 0.01f); } if (input & FORTH) { diff --git a/src/level.h b/src/level.h index c76fd9a..83d4ab9 100644 --- a/src/level.h +++ b/src/level.h @@ -313,11 +313,13 @@ struct Level : IGame { for (int i = 0; i < count; i++) if (items[i].to == roomIndex) { nextRoom = items[i].from; + if (!items[i].visible) { + items[i].visible = true; + visible++; + } break; } - - if (nextRoom == TR::NO_ROOM) - return; + return; } int from, to; // from surface room to underwater room @@ -342,7 +344,6 @@ struct Level : IGame { if (count == MAX_SURFACES) return; items[count++] = Item(from, to); - visible++; } @@ -398,7 +399,7 @@ struct Level : IGame { Core::active.shader->setParam(uType, Shader::WATER_STEP); Core::active.shader->setParam(uParam, vec4(0.995f, 1.0f, 0, 0)); - + while (item.timer >= SIMULATE_TIMESTEP) { // water step item.data[0]->bind(sDiffuse); @@ -409,6 +410,7 @@ struct Level : IGame { item.timer -= SIMULATE_TIMESTEP; } + // calc caustics vec3 rPosScale[2] = { vec3(0.0f), vec3(1.0f / PLANE_DETAIL) }; Core::active.shader->setParam(uType, Shader::WATER_CAUSTICS); @@ -419,8 +421,8 @@ struct Level : IGame { Core::active.shader->setParam(uTexParam, vec4(1.0f, 1.0f, sx, sz)); - item.data[0]->bind(sNormal); item.caustics->unbind(sReflect); + item.data[0]->bind(sNormal); Core::setTarget(item.caustics); level->mesh->renderPlane(); } @@ -493,21 +495,23 @@ struct Level : IGame { // simulate water level->setPassShader(Core::passWater); + Core::setBlending(bmNone); + Core::setDepthTest(false); + item.mask->bind(sMask); + if (item.timer >= SIMULATE_TIMESTEP || dropCount) { - Core::setBlending(bmNone); - Core::setDepthTest(false); Core::active.shader->setParam(uTexParam, vec4(1.0f / item.data[0]->width, 1.0f / item.data[0]->height, 1.0f, 1.0f)); - item.mask->bind(sEnvironment); drop(item); step(item); - Core::setBlending(bmAlpha); - Core::setDepthTest(true); } Core::setTarget(NULL); + Core::setBlending(bmAlpha); + Core::setDepthTest(true); + // render water plane if (level->level.rooms[item.from].lightsCount) { TR::Room::Light &light = level->level.rooms[item.from].lights[0]; @@ -529,17 +533,16 @@ struct Level : IGame { Core::active.shader->setParam(uTexParam, vec4(1.0f, 1.0f, sx, sz)); - refract->bind(sDiffuse); reflect->bind(sReflect); item.data[0]->bind(sNormal); Core::setCulling(cfNone); - //vec3 rPosScale[2] = { item.pos, item.size * vec3(1.0f / PLANE_DETAIL, 1.0f, 1.0f / PLANE_DETAIL) }; - //Core::active.shader->setParam(uPosScale, rPosScale[0], 2); - //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - level->mesh->renderQuad(); - //level->mesh->renderPlane(); - //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + vec3 rPosScale[2] = { item.pos, item.size * vec3(1.0f / PLANE_DETAIL, 512.0f, 1.0f / PLANE_DETAIL) }; + Core::active.shader->setParam(uPosScale, rPosScale[0], 2); + // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + //level->mesh->renderQuad(); + level->mesh->renderPlane(); + // glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); Core::setCulling(cfFront); } @@ -1119,6 +1122,7 @@ struct Level : IGame { atlas->bind(sDiffuse); cube->bind(sEnvironment); + Core::whiteTex->bind(sMask); if (!Core::support.VAO) mesh->bind(); @@ -1357,7 +1361,7 @@ struct Level : IGame { // Debug::Level::rooms(level, lara->pos, lara->getEntity().room); - Debug::Level::lights(level, lara->getRoomIndex()); + // Debug::Level::lights(level, lara->getRoomIndex()); // Debug::Level::sectors(level, lara->getRoomIndex(), (int)lara->pos.y); // Core::setDepthTest(false); // Debug::Level::portals(level); diff --git a/src/shader.h b/src/shader.h index e57f443..868efa3 100644 --- a/src/shader.h +++ b/src/shader.h @@ -4,11 +4,11 @@ #include "core.h" enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX }; -enum SamplerType { sDiffuse, sNormal, sReflect, sShadow, sEnvironment, sMAX }; +enum SamplerType { sDiffuse, sNormal, sReflect, sShadow, sEnvironment, sMask, sMAX }; enum UniformType { uType, uCaustics, uParam, uTexParam, uViewProj, uViewInv, uBasis, uLightProj, uColor, uAmbient, uViewPos, uLightsCount, uLightPos, uLightColor, uAnimTexRanges, uAnimTexOffsets, uRoomSize, uPosScale, uMAX }; const char *AttribName[aMAX] = { "aCoord", "aTexCoord", "aNormal", "aColor" }; -const char *SamplerName[sMAX] = { "sDiffuse", "sNormal", "sReflect", "sShadow", "sEnvironment" }; +const char *SamplerName[sMAX] = { "sDiffuse", "sNormal", "sReflect", "sShadow", "sEnvironment", "sMask" }; const char *UniformName[uMAX] = { "uType", "uCaustics", "uParam", "uTexParam", "uViewProj", "uViewInv", "uBasis", "uLightProj", "uColor", "uAmbient", "uViewPos", "uLightsCount", "uLightPos", "uLightColor", "uAnimTexRanges", "uAnimTexOffsets", "uRoomSize", "uPosScale" }; struct Shader { diff --git a/src/trigger.h b/src/trigger.h index 5963b34..2709053 100644 --- a/src/trigger.h +++ b/src/trigger.h @@ -335,8 +335,8 @@ struct Waterfall : Trigger { drop = true; dropPos = pos + vec3(randf() * 1024.0f - 512.0f, 0.0f, randf() * 1024.0f - 512.0f); - dropRadius = randf() * 256.0f + 128.0f; - dropStrength = randf() * 0.1f + 0.1f; + dropRadius = 256.0f;//randf() * 128.0f + 128.0f; + dropStrength = 0.15f;//randf() * 0.1f + 0.05f; Sprite::add(game, TR::Entity::WATER_SPLASH, getRoomIndex(), (int)dropPos.x, (int)dropPos.y, (int)dropPos.z); } diff --git a/src/water.glsl b/src/water.glsl index 246e091..ad1effd 100644 --- a/src/water.glsl +++ b/src/water.glsl @@ -39,7 +39,16 @@ uniform sampler2D sNormal; vTexCoord = (aCoord.xy * 0.5 + 0.5) * uTexParam.zw; if (uType >= WATER_MASK) { - vCoord = vec3(aCoord.x, 0.0, aCoord.y) * uPosScale[1] + uPosScale[0]; + + float height = 0.0; + + if (uType == WATER_COMPOSE) { + vTexCoord = (aCoord.xy * 0.01 * 0.5 + 0.5) * uTexParam.zw; + height = texture2D(sNormal, vTexCoord).x; + } + + vCoord = vec3(aCoord.x, height, aCoord.y) * uPosScale[1] + uPosScale[0]; + vec4 cp = uViewProj * vec4(vCoord, 1.0); vProjCoord = cp; @@ -50,7 +59,7 @@ uniform sampler2D sNormal; vec3 rCoord = vec3(aCoord.x, 0.0, aCoord.y) * uPosScale[1]; vec4 info = texture2D(sNormal, (rCoord.xz * 0.5 + 0.5) * uTexParam.zw); - vec3 normal = vec3(info.b, -sqrt(1.0 - dot(info.ba, info.ba)), info.a); + vec3 normal = vec3(info.z, -sqrt(1.0 - dot(info.zw, info.zw)), info.w); vec3 light = vec3(0.0, -1.0, 0.0); vec3 refractedLight = refract(-light, vec3(0.0, 1.0, 0.0), ETA_AIR / ETA_WATER); @@ -71,7 +80,7 @@ uniform sampler2D sNormal; #else uniform sampler2D sDiffuse; uniform sampler2D sReflect; - uniform sampler2D sEnvironment; + uniform sampler2D sMask; uniform vec3 uLightPos; uniform vec4 uLightColor; @@ -91,54 +100,34 @@ uniform sampler2D sNormal; drop = 0.5 - cos(drop * PI) * 0.5; v.x += drop * uParam.w; - return v * texture2D(sEnvironment, tc).x; // apply coast mask - } - - - float getHeight(float ref, vec2 tc) { - return mix(ref, texture2D(sDiffuse, tc).x, texture2D(sEnvironment, tc).x); + return v; } vec4 step() { vec2 tc = gl_FragCoord.xy * uTexParam.xy; + if (texture2D(sMask, tc).x == 0.0) + return vec4(0.0); + vec4 v = texture2D(sDiffuse, tc); // height, speed, normal.xz -/* - vec4 dx = vec4(0.25, 0.96, -0.25, -0.96) * uTexParam.xyxy + tc.xyxy; - vec4 dy = vec4(0.25, 0.96, -0.25, -0.96) * uTexParam.yxyx + tc.yxyx; - float average = (texture2D(sDiffuse, dy.yx).x + - texture2D(sDiffuse, dx.zy).x + - texture2D(sDiffuse, dy.wz).x + - texture2D(sDiffuse, dx.xw).x) * 0.25; - vec3 d = vec3(uTexParam.xy, 0.0); - vec2 f = vec2(texture2D(sDiffuse, tc + d.xz).x, texture2D(sDiffuse, tc + d.zy).x); -*/ - - vec3 d = vec3(uTexParam.xy, 0.0); - vec4 f = vec4(getHeight(v.x, tc + d.xz), getHeight(v.x, tc + d.zy), - getHeight(v.x, tc - d.xz), getHeight(v.x, tc - d.zy)); - -// vec4 f = vec4(texture2D(sDiffuse, tc + d.xz).x, texture2D(sDiffuse, tc + d.zy).x, -// texture2D(sDiffuse, tc - d.xz).x, texture2D(sDiffuse, tc - d.zy).x); - + vec4 f = vec4(texture2D(sDiffuse, tc + d.xz).x, texture2D(sDiffuse, tc + d.zy).x, + texture2D(sDiffuse, tc - d.xz).x, texture2D(sDiffuse, tc - d.zy).x); float average = dot(f, vec4(0.25)); // normal - f.xy -= v.x; - vec3 nx = vec3(d.x, f.x, 0.0); - vec3 ny = vec3(0.0, f.y, d.y); - v.zw = normalize(cross(ny, nx)).xz * 0.5; + v.zw = normalize( vec3(f.x - f.z, 64.0 / (1024.0 * 2.0), f.y - f.w) ).xz; - // velocity - v.y += (average - v.x) * 1.9; - v.y *= uParam.x; // fadeout + // integrate + const float vel = 1.8; + const float vis = 0.995; - // amplitude - v.x += v.y * uParam.y; + v.y *= vis; + v.y += (average - v.x) * vel; + v.x += v.y; - return v * texture2D(sEnvironment, tc).x; // apply coast mask + return v; } vec4 caustics() { @@ -156,7 +145,8 @@ uniform sampler2D sNormal; vec4 value = texture2D(sNormal, vTexCoord); - vec3 normal = normalize(vec3(value.b, -sqrt(1.0 - dot(value.ba, value.ba)), value.a)); + vec3 normal = vec3(value.z, -sqrt(1.0 - dot(value.zw, value.zw)), value.w); + vec2 dudv = (uViewProj * vec4(normal.x, 0.0, normal.z, 0.0)).xy; vec3 viewVec = normalize(uViewPos - vCoord);