mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-13 00:24:24 +02:00
#23 underwater fog
This commit is contained in:
@@ -422,7 +422,7 @@ namespace Core {
|
||||
memset(&active, 0, sizeof(active));
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
setCulling(cfFront);
|
||||
setBlending(bmAlpha);
|
||||
setBlending(bmNone);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -329,7 +329,7 @@ namespace Debug {
|
||||
glEnd();
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
Core::setBlending(bmAlpha);
|
||||
Core::setBlending(bmNone);
|
||||
}
|
||||
|
||||
void entities(const TR::Level &level) {
|
||||
|
52
src/level.h
52
src/level.h
@@ -29,6 +29,9 @@ const char GUI[] =
|
||||
#include "gui.glsl"
|
||||
;
|
||||
|
||||
#define FOG_DIST (18 * 1024)
|
||||
#define WATER_FOG_DIST (8 * 1024)
|
||||
|
||||
struct Level : IGame {
|
||||
enum { shCompose, shShadow, shAmbient, shFilter, shWater, shGUI, shMAX };
|
||||
|
||||
@@ -42,9 +45,14 @@ struct Level : IGame {
|
||||
Camera *camera;
|
||||
Texture *shadow;
|
||||
|
||||
vec3 waterColor;
|
||||
|
||||
struct {
|
||||
float time;
|
||||
float clipHeight;
|
||||
float waterHeight;
|
||||
float clipSign;
|
||||
float clipHeight;
|
||||
} params;
|
||||
|
||||
struct AmbientCache {
|
||||
Level *level;
|
||||
@@ -374,10 +382,13 @@ struct Level : IGame {
|
||||
if (!item || !item->caustics) {
|
||||
Core::blackTex->bind(sReflect);
|
||||
Core::active.shader->setParam(uRoomSize, vec4(0.0f));
|
||||
level->params.waterHeight = -10000000.0f;
|
||||
} else {
|
||||
item->caustics->bind(sReflect);
|
||||
Core::active.shader->setParam(uRoomSize, vec4(item->pos.x - item->size.x, item->pos.z - item->size.z, item->pos.x + item->size.x, item->pos.z + item->size.z));
|
||||
level->params.waterHeight = item->pos.y;
|
||||
}
|
||||
Core::active.shader->setParam(uParam, *((vec4*)&level->params));
|
||||
}
|
||||
|
||||
void addDrop(const vec3 &pos, float radius, float strength) {
|
||||
@@ -497,11 +508,11 @@ struct Level : IGame {
|
||||
//bool underwater = level->camera->pos.y > item.pos.y;
|
||||
|
||||
level->camera->reflectPlane = &reflectPlane;
|
||||
level->clipSign = underwater ? -1.0f : 1.0f;
|
||||
level->clipHeight = item.pos.y * level->clipSign;
|
||||
level->params.clipSign = underwater ? -1.0f : 1.0f;
|
||||
level->params.clipHeight = item.pos.y * level->params.clipSign;
|
||||
level->renderCompose(underwater ? item.from : item.to);
|
||||
level->clipHeight = 1000000.0f;
|
||||
level->clipSign = 1.0f;
|
||||
level->params.clipHeight = 1000000.0f;
|
||||
level->params.clipSign = 1.0f;
|
||||
|
||||
level->camera->reflectPlane = NULL;
|
||||
level->camera->setup(true);
|
||||
@@ -509,7 +520,6 @@ struct Level : IGame {
|
||||
// simulate water
|
||||
level->setPassShader(Core::passWater);
|
||||
|
||||
Core::setBlending(bmNone);
|
||||
Core::setDepthTest(false);
|
||||
item.mask->bind(sMask);
|
||||
|
||||
@@ -522,7 +532,6 @@ struct Level : IGame {
|
||||
}
|
||||
Core::setTarget(NULL);
|
||||
|
||||
Core::setBlending(bmAlpha);
|
||||
Core::setDepthTest(true);
|
||||
|
||||
// render water plane
|
||||
@@ -540,6 +549,7 @@ struct Level : IGame {
|
||||
Core::active.shader->setParam(uLightPos, Core::lightPos[0], 1);
|
||||
Core::active.shader->setParam(uLightColor, Core::lightColor[0], 1);
|
||||
Core::active.shader->setParam(uParam, vec4(float(Core::width) / refract->width, float(Core::height) / refract->height, 0.05f, 0.02f));
|
||||
Core::active.shader->setParam(uColor, vec4(level->waterColor * 0.2f, 1.0f));
|
||||
|
||||
float sx = item.size.x * DETAIL / (item.data[0]->width / 2);
|
||||
float sz = item.size.z * DETAIL / (item.data[0]->height / 2);
|
||||
@@ -618,7 +628,9 @@ struct Level : IGame {
|
||||
}
|
||||
|
||||
|
||||
Level(Stream &stream, bool demo, bool home) : level(stream, demo), lara(NULL), time(0.0f) {
|
||||
Level(Stream &stream, bool demo, bool home) : level(stream, demo), lara(NULL), waterColor(0.6f, 0.9f, 0.9f) {
|
||||
params.time = 0.0f;
|
||||
|
||||
#ifdef _DEBUG
|
||||
Debug::init();
|
||||
#endif
|
||||
@@ -817,14 +829,15 @@ struct Level : IGame {
|
||||
else
|
||||
strcat(ext, "#define SHADOW_COLOR\n");
|
||||
|
||||
sprintf(def, "%s#define PASS_COMPOSE\n#define MAX_LIGHTS %d\n#define MAX_RANGES %d\n#define MAX_OFFSETS %d\n", ext, MAX_LIGHTS, mesh->animTexRangesCount, mesh->animTexOffsetsCount);
|
||||
sprintf(def, "%s#define PASS_COMPOSE\n#define MAX_LIGHTS %d\n#define MAX_RANGES %d\n#define MAX_OFFSETS %d\n#define FOG_DIST (1.0/%d.0)\n#define WATER_FOG_DIST (1.0/%d.0)\n", ext, MAX_LIGHTS, mesh->animTexRangesCount, mesh->animTexOffsetsCount, FOG_DIST, WATER_FOG_DIST);
|
||||
shaders[shCompose] = new Shader(SHADER, def);
|
||||
sprintf(def, "%s#define PASS_SHADOW\n", ext);
|
||||
shaders[shShadow] = new Shader(SHADER, def);
|
||||
sprintf(def, "%s#define PASS_AMBIENT\n", ext);
|
||||
shaders[shAmbient] = new Shader(SHADER, def);
|
||||
shaders[shFilter] = new Shader(FILTER, "");
|
||||
shaders[shWater] = new Shader(WATER, "");
|
||||
sprintf(def, "#define WATER_FOG_DIST (1.0/%d.0)\n", WATER_FOG_DIST);
|
||||
shaders[shWater] = new Shader(WATER, def);
|
||||
shaders[shGUI] = new Shader(GUI, "");
|
||||
}
|
||||
|
||||
@@ -947,7 +960,7 @@ struct Level : IGame {
|
||||
TR::Room &room = level.rooms[roomIndex];
|
||||
|
||||
if (room.flags.water) {
|
||||
Core::color = vec4(0.6f, 0.9f, 0.9f, intensity);
|
||||
Core::color = vec4(waterColor, intensity);
|
||||
Core::active.shader->setParam(uCaustics, 1);
|
||||
/*
|
||||
// trace to water surface room
|
||||
@@ -1120,7 +1133,7 @@ struct Level : IGame {
|
||||
}
|
||||
|
||||
void update() {
|
||||
time += Core::deltaTime;
|
||||
params.time += Core::deltaTime;
|
||||
|
||||
for (int i = 0; i < level.entitiesCount; i++) {
|
||||
TR::Entity &e = level.entities[i];
|
||||
@@ -1162,7 +1175,7 @@ struct Level : IGame {
|
||||
sh->setParam(uLightProj, Core::mLightProj);
|
||||
sh->setParam(uViewInv, Core::mViewInv);
|
||||
sh->setParam(uViewPos, Core::viewPos);
|
||||
sh->setParam(uParam, vec4(time, 0.0f, clipSign, clipHeight));
|
||||
sh->setParam(uParam, *((vec4*)¶ms));
|
||||
sh->setParam(uLightsCount, 3);
|
||||
sh->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount);
|
||||
sh->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount);
|
||||
@@ -1270,7 +1283,6 @@ struct Level : IGame {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
setupCubeCamera(pos, i);
|
||||
setPassShader(Core::passAmbient);
|
||||
Core::setBlending(bmAlpha);
|
||||
Texture *target = targets[0]->cube ? targets[0] : targets[i * stride];
|
||||
Core::setTarget(target, i);
|
||||
Core::clear(vec4(0, 0, 0, 1));
|
||||
@@ -1297,15 +1309,16 @@ struct Level : IGame {
|
||||
PROFILE_MARKER("PASS_COMPOSE");
|
||||
setPassShader(Core::passCompose);
|
||||
|
||||
Core::setBlending(bmAlpha);
|
||||
Core::setBlending(bmNone);
|
||||
Core::clear(vec4(0.0f));
|
||||
shadow->bind(sShadow);
|
||||
renderScene(roomIndex);
|
||||
}
|
||||
|
||||
void render() {
|
||||
clipHeight = 1000000.0f;
|
||||
clipSign = 1.0f;
|
||||
params.clipHeight = 1000000.0f;
|
||||
params.clipSign = 1.0f;
|
||||
params.waterHeight = params.clipHeight;
|
||||
Core::resetStates();
|
||||
|
||||
ambientCache->precessQueue();
|
||||
@@ -1359,7 +1372,7 @@ struct Level : IGame {
|
||||
// renderModel(level.models[modelIndex], level.entities[4]);
|
||||
*/
|
||||
Debug::begin();
|
||||
|
||||
/*
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
@@ -1397,6 +1410,7 @@ struct Level : IGame {
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
*/
|
||||
|
||||
|
||||
// Debug::Level::rooms(level, lara->pos, lara->getEntity().room);
|
||||
@@ -1406,7 +1420,7 @@ struct Level : IGame {
|
||||
// Debug::Level::portals(level);
|
||||
// Core::setDepthTest(true);
|
||||
// Debug::Level::meshes(level);
|
||||
Debug::Level::entities(level);
|
||||
// Debug::Level::entities(level);
|
||||
/*
|
||||
static int dbg_ambient = 0;
|
||||
dbg_ambient = int(time * 2) % 4;
|
||||
|
@@ -25,6 +25,7 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
|
||||
uniform int uType;
|
||||
|
||||
#ifdef PASS_COMPOSE
|
||||
uniform vec3 uViewPos;
|
||||
uniform int uCaustics;
|
||||
uniform vec4 uParam;
|
||||
uniform vec4 uRoomSize; // xy - minXZ, zw - maxXZ
|
||||
@@ -40,7 +41,6 @@ uniform int uType;
|
||||
#endif
|
||||
|
||||
#ifdef PASS_COMPOSE
|
||||
uniform vec3 uViewPos;
|
||||
uniform vec2 uAnimTexRanges[MAX_RANGES];
|
||||
uniform vec2 uAnimTexOffsets[MAX_OFFSETS];
|
||||
#endif
|
||||
@@ -235,6 +235,11 @@ uniform int uType;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
vec3 applyFog(vec3 color, vec3 fogColor, float factor) {
|
||||
float fog = clamp(1.0 / exp(factor), 0.0, 1.0);
|
||||
return mix(fogColor, color, fog);
|
||||
// return color.xyz * exp(factor);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
float getLuminance(vec3 color) {
|
||||
@@ -323,8 +328,6 @@ uniform int uType;
|
||||
}
|
||||
|
||||
color.xyz *= light;
|
||||
|
||||
//color.xyz = normal * 0.5 + 0.5;
|
||||
} else {
|
||||
color.w = uColor.w;
|
||||
}
|
||||
@@ -332,9 +335,14 @@ uniform int uType;
|
||||
|
||||
color.xyz = pow(abs(color.xyz), vec3(1.0/2.2)); // back to gamma space
|
||||
|
||||
// apply fog
|
||||
float fog = clamp(1.0 / exp(gl_FragCoord.z / gl_FragCoord.w * 0.000025), 0.0, 1.0);
|
||||
color = mix(vec4(0.0, 0.0, 0.0, 1.0), color, fog);
|
||||
#ifdef PASS_COMPOSE
|
||||
color.xyz = applyFog(color.xyz, vec3(0.0), length(vViewVec) * FOG_DIST);
|
||||
if (uCaustics != 0) {
|
||||
float d = abs((vCoord.y - max(uViewPos.y, uParam.y)) / normalize(vViewVec).y);
|
||||
d *= step(0.0, vCoord.y - uParam.y);
|
||||
color.xyz = applyFog(color.xyz, uColor.xyz * 0.2, d * WATER_FOG_DIST);
|
||||
}
|
||||
#endif
|
||||
|
||||
gl_FragColor = color;
|
||||
#endif
|
||||
|
@@ -9,6 +9,8 @@ varying vec2 vTexCoord;
|
||||
varying vec4 vProjCoord;
|
||||
varying vec3 vRefPos1;
|
||||
varying vec3 vRefPos2;
|
||||
varying vec3 vViewVec;
|
||||
varying vec3 vLightVec;
|
||||
|
||||
#define WATER_DROP 0
|
||||
#define WATER_STEP 1
|
||||
@@ -19,10 +21,12 @@ varying vec3 vRefPos2;
|
||||
uniform int uType;
|
||||
uniform vec3 uViewPos;
|
||||
uniform mat4 uViewProj;
|
||||
uniform vec3 uLightPos;
|
||||
uniform vec3 uPosScale[2];
|
||||
|
||||
uniform vec4 uTexParam;
|
||||
uniform vec4 uParam;
|
||||
uniform vec4 uColor;
|
||||
|
||||
uniform sampler2D sNormal;
|
||||
|
||||
@@ -73,13 +77,14 @@ uniform sampler2D sNormal;
|
||||
gl_Position = vec4(aCoord.xyz, 1.0);
|
||||
}
|
||||
}
|
||||
vViewVec = uViewPos - vCoord.xyz;
|
||||
vLightVec = uLightPos - vCoord.xyz;
|
||||
}
|
||||
#else
|
||||
uniform sampler2D sDiffuse;
|
||||
uniform sampler2D sReflect;
|
||||
uniform sampler2D sMask;
|
||||
|
||||
uniform vec3 uLightPos;
|
||||
uniform vec4 uLightColor;
|
||||
|
||||
#define PI 3.141592653589793
|
||||
@@ -89,6 +94,11 @@ uniform sampler2D sNormal;
|
||||
return clamp(fbias + (1.0 - fbias) * pow(f, fpow), 0.0, 1.0);
|
||||
}
|
||||
|
||||
vec3 applyFog(vec3 color, vec3 fogColor, float factor) {
|
||||
float fog = clamp(1.0 / exp(factor), 0.0, 1.0);
|
||||
return mix(fogColor, color, fog);
|
||||
}
|
||||
|
||||
vec4 drop() {
|
||||
vec2 tc = gl_FragCoord.xy * uTexParam.xy;
|
||||
vec4 v = texture2D(sDiffuse, tc);
|
||||
@@ -146,9 +156,9 @@ uniform sampler2D sNormal;
|
||||
|
||||
vec2 dudv = (uViewProj * vec4(normal.x, 0.0, normal.z, 0.0)).xy;
|
||||
|
||||
vec3 viewVec = normalize(uViewPos - vCoord);
|
||||
vec3 viewVec = normalize(vViewVec);
|
||||
vec3 rv = reflect(-viewVec, normal);
|
||||
vec3 lv = normalize(uLightPos - vCoord.xyz);
|
||||
vec3 lv = normalize(vLightVec);
|
||||
|
||||
float spec = pow(max(0.0, dot(rv, lv)), 64.0) * 0.5;
|
||||
|
||||
@@ -158,7 +168,14 @@ uniform sampler2D sNormal;
|
||||
vec4 refl = texture2D(sReflect, vec2(tc.x, 1.0 - tc.y) + dudv * uParam.w);
|
||||
|
||||
float fresnel = calcFresnel(dot(normal, viewVec), 0.1, 2.0);
|
||||
return mix(refr, refl, fresnel) + spec;
|
||||
|
||||
vec4 color = mix(refr, refl, fresnel) + spec;
|
||||
|
||||
float d = abs((vCoord.y - uViewPos.y) / normalize(vViewVec).y);
|
||||
d *= step(0.0, uViewPos.y - vCoord.y); // apply fog only when camera is underwater
|
||||
color.xyz = applyFog(color.xyz, uColor.xyz, d * WATER_FOG_DIST);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4 pass() {
|
||||
|
Reference in New Issue
Block a user