1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-02-24 07:22:58 +01:00

fix water mask; add sky shader

This commit is contained in:
XProger 2019-02-02 00:41:35 +03:00
parent 68f6572204
commit bf27452b20
8 changed files with 50 additions and 34 deletions

View File

@ -31,6 +31,8 @@ struct ShaderCache {
if (Core::settings.detail.shadows > Core::Settings::LOW)
prepareShadows(FX_NONE);
prepareSky(FX_NONE);
if (Core::settings.detail.water > Core::Settings::LOW)
prepareWater(FX_NONE);
@ -69,7 +71,7 @@ struct ShaderCache {
compile(Core::passCompose, Shader::SPRITE, fx, rsFull | RS_DISCARD);
compile(Core::passCompose, Shader::SPRITE, fx | FX_UNDERWATER, rsFull | RS_DISCARD);
compile(Core::passCompose, Shader::FLASH, fx, rsFull | RS_BLEND_MULT);
compile(Core::passCompose, Shader::FLASH, fx, rsFull | RS_BLEND_MULT); // spot shadow
}
void prepareAmbient(int fx) {
@ -79,7 +81,6 @@ struct ShaderCache {
compile(Core::passAmbient, Shader::ROOM, fx | FX_UNDERWATER, rsFull | RS_DISCARD);
compile(Core::passAmbient, Shader::SPRITE, fx, rsFull | RS_DISCARD);
compile(Core::passAmbient, Shader::SPRITE, fx | FX_UNDERWATER, rsFull | RS_DISCARD);
compile(Core::passAmbient, Shader::FLASH, fx, rsFull); // sky
}
void prepareShadows(int fx) {
@ -88,6 +89,10 @@ struct ShaderCache {
compile(Core::passShadow, Shader::ENTITY, fx, rsShadow | RS_DISCARD);
}
void prepareSky(int fx) {
compile(Core::passSky, Shader::DEFAULT, fx, rsBase);
}
void prepareWater(int fx) {
compile(Core::passWater, Shader::WATER_MASK, fx, RS_COLOR_WRITE_A | RS_DEPTH_TEST);
compile(Core::passWater, Shader::WATER_SIMULATE, fx, RS_COLOR_WRITE);
@ -159,6 +164,7 @@ struct ShaderCache {
}
break;
}
case Core::passSky : break;
case Core::passWater : def[defCount++] = SD_WATER_DROP + type; break;
case Core::passFilter : def[defCount++] = SD_FILTER_UPSCALE + type; break;
case Core::passGUI : break;
@ -968,7 +974,7 @@ struct WaterCache {
item.mask->bind(sMask);
item.data[0]->bind(sNormal);
Core::setCullMode(cmNone);
Core::setBlendMode(bmNone);
Core::setBlendMode(bmAlpha);
#ifdef WATER_USE_GRID
vec4 rPosScale[2] = { vec4(item.pos, 0.0f), vec4(item.size * vec3(1.0f / PLANE_DETAIL, 512.0f, 1.0f / PLANE_DETAIL), 1.0f) };
Core::active.shader->setParam(uPosScale, rPosScale[0], 2);

View File

@ -508,9 +508,9 @@ namespace Core {
Texture *whiteTex, *whiteCube, *blackTex, *ditherTex, *noiseTex;
enum Pass { passCompose, passShadow, passAmbient, passWater, passFilter, passGUI, passMAX } pass;
enum Pass { passCompose, passShadow, passAmbient, passSky, passWater, passFilter, passGUI, passMAX } pass;
const char *passNames[Core::passMAX] = { "COMPOSE", "SHADOW", "AMBIENT", "WATER", "FILTER", "GUI" };
const char *passNames[Core::passMAX] = { "COMPOSE", "SHADOW", "AMBIENT", "SKY", "WATER", "FILTER", "GUI" };
GAPI::Texture *defaultTarget;

View File

@ -353,6 +353,10 @@ namespace GAPI {
#include "shaders/shader.glsl"
;
const char SHADER_SKY[] =
#include "shaders/sky.glsl"
;
const char SHADER_WATER[] =
#include "shaders/water.glsl"
;
@ -412,6 +416,7 @@ namespace GAPI {
case Core::passCompose :
case Core::passShadow :
case Core::passAmbient : source = SHADER_BASE; break;
case Core::passSky : source = SHADER_SKY; break;
case Core::passWater : source = SHADER_WATER; break;
case Core::passFilter : source = SHADER_FILTER; break;
case Core::passGUI : source = SHADER_GUI; break;
@ -424,6 +429,7 @@ namespace GAPI {
case Core::passCompose :
case Core::passShadow :
case Core::passAmbient : stream = new Stream("../../src/shaders/shader.glsl"); break;
case Core::passSky : stream = new Stream("../../src/shaders/sky.glsl"); break;
case Core::passWater : stream = new Stream("../../src/shaders/water.glsl"); break;
case Core::passFilter : stream = new Stream("../../src/shaders/filter.glsl"); break;
case Core::passGUI : stream = new Stream("../../src/shaders/gui.glsl"); break;

View File

@ -59,6 +59,7 @@ struct Level : IGame {
bool needRedrawReflections;
bool needRenderGame;
bool showStats;
bool skyIsVisible;
TR::LevelID nextLevel;
@ -1486,45 +1487,43 @@ struct Level : IGame {
void renderSky() {
if (level.extra.sky == -1) return;
ASSERT(mesh->transparent == 0);
mat4 m = Core::mViewProj;
Core::Pass pass = Core::pass;
mat4 mView = Core::mView;
mView.setPos(vec3(0));
Core::mViewProj = Core::mProj * mView;
mat4 mProj = Core::mProj;
//Animation anim(&level, &level.models[level.extra.sky]);
Core::mView.setPos(vec3(0));
// TODO TR2 TR3 use animation frame to get skydome rotation
Basis b;
if (level.version & TR::VER_TR2)
b = Basis(quat(vec3(1, 0, 0), PI * 0.5f), vec3(0));
else
b = Basis(quat(0, 0, 0, 1), vec3(0));
Core::setBlendMode(bmNone);
Core::setDepthTest(false);
setShader(Core::pass, Shader::FLASH, false, false);
Core::setMaterial(1.0f / 1.8f, 0.0f, 0.0f, 0.0f);
// Animation anim(&level, &level.models[level.extra.sky]);
// anim.getJoints(Basis(quat(0, 0, 0, 1), vec3(0)), 0, false));//Basis(anim.getJointRot(0), vec3(0)));
Core::setBasis(&b, 1);
mesh->transparent = 0;
if (level.version & TR::VER_TR2) {
Core::mView.rotateX(PIH);
}
Core::setViewProj(Core::mView, Core::mProj);
setShader(Core::passSky, Shader::DEFAULT, false, false);
//Basis b;
//Core::setBasis(&b, 1); // unused
mesh->renderModel(level.extra.sky);
Core::setDepthTest(true);
Core::mViewProj = m;
Core::setViewProj(mView, mProj);
Core::pass = pass;
}
void prepareRooms(int *roomsList, int roomsCount) {
bool hasSky = false;
skyIsVisible = false;
for (int i = 0; i < level.roomsCount; i++)
level.rooms[i].flags.visible = false;
for (int i = 0; i < roomsCount; i++) {
TR::Room &r = level.rooms[roomsList[i]];
hasSky |= r.flags.sky;
skyIsVisible |= r.flags.sky;
r.flags.visible = true;
}
@ -1543,9 +1542,6 @@ struct Level : IGame {
}
setMainLight(player);
if (hasSky)
renderSky();
}
void renderRooms(int *roomsList, int roomsCount, int transp) {
@ -2081,6 +2077,9 @@ struct Level : IGame {
void renderOpaque(int *roomsList, int roomsCount) {
renderRooms(roomsList, roomsCount, 0);
renderEntities(0);
if (Core::pass != Core::passShadow && skyIsVisible) {
renderSky();
}
}
void renderTransparent(int *roomsList, int roomsCount) {
@ -2165,7 +2164,6 @@ struct Level : IGame {
prepareRooms(roomsList, roomsCount);
renderOpaque(roomsList, roomsCount);
renderTransparent(roomsList, roomsCount);

View File

@ -1382,7 +1382,8 @@ struct MeshBuilder {
}
void renderModel(int modelIndex, bool underwater = false) {
ASSERT(level->models[modelIndex].mCount == Core::active.basisCount);
ASSERT((Core::pass != Core::passCompose && Core::pass != Core::passShadow && Core::pass != Core::passAmbient) ||
level->models[modelIndex].mCount == Core::active.basisCount);
int part = 0;

View File

@ -236,6 +236,7 @@
<None Include="..\..\shaders\filter.glsl" />
<None Include="..\..\shaders\gui.glsl" />
<None Include="..\..\shaders\shader.glsl" />
<None Include="..\..\shaders\sky.glsl" />
<None Include="..\..\shaders\water.glsl" />
</ItemGroup>
<ItemGroup>

View File

@ -72,6 +72,9 @@
<None Include="..\..\shaders\shader.glsl">
<Filter>shaders</Filter>
</None>
<None Include="..\..\shaders\sky.glsl">
<Filter>shaders</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Filter Include="shaders">

View File

@ -152,7 +152,7 @@ vec3 calcNormal(vec2 tc, float base) {
v.y += (average - v.x) * vel;
v.y *= vis;
v.x += v.y + noise3D(vec3(tc * 32.0, uParam.w)) * 0.00025;
v *= texture2D(sMask, vMaskCoord).a;
v *= texture2D(sMask, vMaskCoord).x;
return vec4(v.xy, 0.0, 0.0);
}
@ -241,8 +241,9 @@ vec3 calcNormal(vec2 tc, float base) {
float fresnel = calcFresnel(max(0.0, dot(normal, viewVec)), 0.12);
vec4 color = mix(refr, refl, fresnel) + spec * 1.5;
color.w *= texture2D(sMask, vMaskCoord).a;
vec4 color = mix(refr, refl, fresnel);
color.xyz += spec * 1.5;
color.w = texture2D(sMask, vMaskCoord).x;
applyFog(color.xyz, vViewVec.y / viewVec.y);
return color;