mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-08 06:06:51 +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);
|
game->waterDrop(animation.getJoints(getMatrix(), 14).pos, 96.0f, 0.01f);
|
||||||
} else {
|
} else {
|
||||||
if (animation.frameIndex % 4 == 0)
|
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) {
|
if (input & FORTH) {
|
||||||
|
32
src/level.h
32
src/level.h
@@ -313,10 +313,12 @@ struct Level : IGame {
|
|||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
if (items[i].to == roomIndex) {
|
if (items[i].to == roomIndex) {
|
||||||
nextRoom = items[i].from;
|
nextRoom = items[i].from;
|
||||||
|
if (!items[i].visible) {
|
||||||
|
items[i].visible = true;
|
||||||
|
visible++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextRoom == TR::NO_ROOM)
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +344,6 @@ struct Level : IGame {
|
|||||||
if (count == MAX_SURFACES) return;
|
if (count == MAX_SURFACES) return;
|
||||||
|
|
||||||
items[count++] = Item(from, to);
|
items[count++] = Item(from, to);
|
||||||
|
|
||||||
visible++;
|
visible++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,6 +410,7 @@ struct Level : IGame {
|
|||||||
item.timer -= SIMULATE_TIMESTEP;
|
item.timer -= SIMULATE_TIMESTEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// calc caustics
|
// calc caustics
|
||||||
vec3 rPosScale[2] = { vec3(0.0f), vec3(1.0f / PLANE_DETAIL) };
|
vec3 rPosScale[2] = { vec3(0.0f), vec3(1.0f / PLANE_DETAIL) };
|
||||||
Core::active.shader->setParam(uType, Shader::WATER_CAUSTICS);
|
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));
|
Core::active.shader->setParam(uTexParam, vec4(1.0f, 1.0f, sx, sz));
|
||||||
|
|
||||||
item.data[0]->bind(sNormal);
|
|
||||||
item.caustics->unbind(sReflect);
|
item.caustics->unbind(sReflect);
|
||||||
|
item.data[0]->bind(sNormal);
|
||||||
Core::setTarget(item.caustics);
|
Core::setTarget(item.caustics);
|
||||||
level->mesh->renderPlane();
|
level->mesh->renderPlane();
|
||||||
}
|
}
|
||||||
@@ -493,21 +495,23 @@ struct Level : IGame {
|
|||||||
// simulate water
|
// simulate water
|
||||||
level->setPassShader(Core::passWater);
|
level->setPassShader(Core::passWater);
|
||||||
|
|
||||||
if (item.timer >= SIMULATE_TIMESTEP || dropCount) {
|
|
||||||
Core::setBlending(bmNone);
|
Core::setBlending(bmNone);
|
||||||
Core::setDepthTest(false);
|
Core::setDepthTest(false);
|
||||||
|
item.mask->bind(sMask);
|
||||||
|
|
||||||
|
if (item.timer >= SIMULATE_TIMESTEP || dropCount) {
|
||||||
|
|
||||||
Core::active.shader->setParam(uTexParam, vec4(1.0f / item.data[0]->width, 1.0f / item.data[0]->height, 1.0f, 1.0f));
|
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);
|
drop(item);
|
||||||
step(item);
|
step(item);
|
||||||
|
|
||||||
Core::setBlending(bmAlpha);
|
|
||||||
Core::setDepthTest(true);
|
|
||||||
}
|
}
|
||||||
Core::setTarget(NULL);
|
Core::setTarget(NULL);
|
||||||
|
|
||||||
|
Core::setBlending(bmAlpha);
|
||||||
|
Core::setDepthTest(true);
|
||||||
|
|
||||||
// render water plane
|
// render water plane
|
||||||
if (level->level.rooms[item.from].lightsCount) {
|
if (level->level.rooms[item.from].lightsCount) {
|
||||||
TR::Room::Light &light = level->level.rooms[item.from].lights[0];
|
TR::Room::Light &light = level->level.rooms[item.from].lights[0];
|
||||||
@@ -529,16 +533,15 @@ struct Level : IGame {
|
|||||||
|
|
||||||
Core::active.shader->setParam(uTexParam, vec4(1.0f, 1.0f, sx, sz));
|
Core::active.shader->setParam(uTexParam, vec4(1.0f, 1.0f, sx, sz));
|
||||||
|
|
||||||
|
|
||||||
refract->bind(sDiffuse);
|
refract->bind(sDiffuse);
|
||||||
reflect->bind(sReflect);
|
reflect->bind(sReflect);
|
||||||
item.data[0]->bind(sNormal);
|
item.data[0]->bind(sNormal);
|
||||||
Core::setCulling(cfNone);
|
Core::setCulling(cfNone);
|
||||||
//vec3 rPosScale[2] = { item.pos, item.size * vec3(1.0f / PLANE_DETAIL, 1.0f, 1.0f / PLANE_DETAIL) };
|
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);
|
Core::active.shader->setParam(uPosScale, rPosScale[0], 2);
|
||||||
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
level->mesh->renderQuad();
|
//level->mesh->renderQuad();
|
||||||
//level->mesh->renderPlane();
|
level->mesh->renderPlane();
|
||||||
// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
|
||||||
Core::setCulling(cfFront);
|
Core::setCulling(cfFront);
|
||||||
@@ -1119,6 +1122,7 @@ struct Level : IGame {
|
|||||||
|
|
||||||
atlas->bind(sDiffuse);
|
atlas->bind(sDiffuse);
|
||||||
cube->bind(sEnvironment);
|
cube->bind(sEnvironment);
|
||||||
|
Core::whiteTex->bind(sMask);
|
||||||
|
|
||||||
if (!Core::support.VAO)
|
if (!Core::support.VAO)
|
||||||
mesh->bind();
|
mesh->bind();
|
||||||
@@ -1357,7 +1361,7 @@ struct Level : IGame {
|
|||||||
|
|
||||||
|
|
||||||
// Debug::Level::rooms(level, lara->pos, lara->getEntity().room);
|
// 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);
|
// Debug::Level::sectors(level, lara->getRoomIndex(), (int)lara->pos.y);
|
||||||
// Core::setDepthTest(false);
|
// Core::setDepthTest(false);
|
||||||
// Debug::Level::portals(level);
|
// Debug::Level::portals(level);
|
||||||
|
@@ -4,11 +4,11 @@
|
|||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX };
|
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 };
|
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 *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" };
|
const char *UniformName[uMAX] = { "uType", "uCaustics", "uParam", "uTexParam", "uViewProj", "uViewInv", "uBasis", "uLightProj", "uColor", "uAmbient", "uViewPos", "uLightsCount", "uLightPos", "uLightColor", "uAnimTexRanges", "uAnimTexOffsets", "uRoomSize", "uPosScale" };
|
||||||
|
|
||||||
struct Shader {
|
struct Shader {
|
||||||
|
@@ -335,8 +335,8 @@ struct Waterfall : Trigger {
|
|||||||
|
|
||||||
drop = true;
|
drop = true;
|
||||||
dropPos = pos + vec3(randf() * 1024.0f - 512.0f, 0.0f, randf() * 1024.0f - 512.0f);
|
dropPos = pos + vec3(randf() * 1024.0f - 512.0f, 0.0f, randf() * 1024.0f - 512.0f);
|
||||||
dropRadius = randf() * 256.0f + 128.0f;
|
dropRadius = 256.0f;//randf() * 128.0f + 128.0f;
|
||||||
dropStrength = randf() * 0.1f + 0.1f;
|
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);
|
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;
|
vTexCoord = (aCoord.xy * 0.5 + 0.5) * uTexParam.zw;
|
||||||
|
|
||||||
if (uType >= WATER_MASK) {
|
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);
|
vec4 cp = uViewProj * vec4(vCoord, 1.0);
|
||||||
|
|
||||||
vProjCoord = cp;
|
vProjCoord = cp;
|
||||||
@@ -50,7 +59,7 @@ uniform sampler2D sNormal;
|
|||||||
vec3 rCoord = vec3(aCoord.x, 0.0, aCoord.y) * uPosScale[1];
|
vec3 rCoord = vec3(aCoord.x, 0.0, aCoord.y) * uPosScale[1];
|
||||||
|
|
||||||
vec4 info = texture2D(sNormal, (rCoord.xz * 0.5 + 0.5) * uTexParam.zw);
|
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 light = vec3(0.0, -1.0, 0.0);
|
||||||
vec3 refractedLight = refract(-light, vec3(0.0, 1.0, 0.0), ETA_AIR / ETA_WATER);
|
vec3 refractedLight = refract(-light, vec3(0.0, 1.0, 0.0), ETA_AIR / ETA_WATER);
|
||||||
@@ -71,7 +80,7 @@ uniform sampler2D sNormal;
|
|||||||
#else
|
#else
|
||||||
uniform sampler2D sDiffuse;
|
uniform sampler2D sDiffuse;
|
||||||
uniform sampler2D sReflect;
|
uniform sampler2D sReflect;
|
||||||
uniform sampler2D sEnvironment;
|
uniform sampler2D sMask;
|
||||||
|
|
||||||
uniform vec3 uLightPos;
|
uniform vec3 uLightPos;
|
||||||
uniform vec4 uLightColor;
|
uniform vec4 uLightColor;
|
||||||
@@ -91,54 +100,34 @@ uniform sampler2D sNormal;
|
|||||||
drop = 0.5 - cos(drop * PI) * 0.5;
|
drop = 0.5 - cos(drop * PI) * 0.5;
|
||||||
v.x += drop * uParam.w;
|
v.x += drop * uParam.w;
|
||||||
|
|
||||||
return v * texture2D(sEnvironment, tc).x; // apply coast mask
|
return v;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
float getHeight(float ref, vec2 tc) {
|
|
||||||
return mix(ref, texture2D(sDiffuse, tc).x, texture2D(sEnvironment, tc).x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 step() {
|
vec4 step() {
|
||||||
vec2 tc = gl_FragCoord.xy * uTexParam.xy;
|
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 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);
|
vec3 d = vec3(uTexParam.xy, 0.0);
|
||||||
vec2 f = vec2(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);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
float average = dot(f, vec4(0.25));
|
float average = dot(f, vec4(0.25));
|
||||||
|
|
||||||
// normal
|
// normal
|
||||||
f.xy -= v.x;
|
v.zw = normalize( vec3(f.x - f.z, 64.0 / (1024.0 * 2.0), f.y - f.w) ).xz;
|
||||||
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;
|
|
||||||
|
|
||||||
// velocity
|
// integrate
|
||||||
v.y += (average - v.x) * 1.9;
|
const float vel = 1.8;
|
||||||
v.y *= uParam.x; // fadeout
|
const float vis = 0.995;
|
||||||
|
|
||||||
// amplitude
|
v.y *= vis;
|
||||||
v.x += v.y * uParam.y;
|
v.y += (average - v.x) * vel;
|
||||||
|
v.x += v.y;
|
||||||
|
|
||||||
return v * texture2D(sEnvironment, tc).x; // apply coast mask
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 caustics() {
|
vec4 caustics() {
|
||||||
@@ -156,7 +145,8 @@ uniform sampler2D sNormal;
|
|||||||
|
|
||||||
vec4 value = texture2D(sNormal, vTexCoord);
|
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;
|
vec2 dudv = (uViewProj * vec4(normal.x, 0.0, normal.z, 0.0)).xy;
|
||||||
|
|
||||||
vec3 viewVec = normalize(uViewPos - vCoord);
|
vec3 viewVec = normalize(uViewPos - vCoord);
|
||||||
|
Reference in New Issue
Block a user