mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-07 13:46:45 +02:00
#23 water
This commit is contained in:
@@ -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) {
|
||||
|
40
src/level.h
40
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++;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
@@ -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 {
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user