1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-13 16:44:50 +02:00

split GLSL uber-shader by passes

This commit is contained in:
XProger
2019-02-16 03:59:52 +03:00
parent 62fbbd60d7
commit 0ad35ea26d
9 changed files with 385 additions and 272 deletions

View File

@@ -77,10 +77,7 @@ struct ShaderCache {
void prepareAmbient(int fx) {
compile(Core::passAmbient, Shader::ROOM, fx, rsFull);
compile(Core::passAmbient, Shader::ROOM, fx, rsFull | RS_DISCARD);
compile(Core::passAmbient, Shader::ROOM, fx | FX_UNDERWATER, rsFull);
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);
}
void prepareShadows(int fx) {

View File

@@ -520,8 +520,6 @@ namespace Core {
enum Pass { passCompose, passShadow, passAmbient, passSky, passWater, passFilter, passGUI, passMAX } pass;
const char *passNames[Core::passMAX] = { "COMPOSE", "SHADOW", "AMBIENT", "SKY", "WATER", "FILTER", "GUI" };
GAPI::Texture *defaultTarget;
int32 renderState;

View File

@@ -334,8 +334,16 @@ namespace GAPI {
// Shader
#ifndef FFP
const char SHADER_BASE[] =
#include "shaders/shader.glsl"
const char SHADER_COMPOSE[] =
#include "shaders/compose.glsl"
;
const char SHADER_SHADOW[] =
#include "shaders/shadow.glsl"
;
const char SHADER_AMBIENT[] =
#include "shaders/ambient.glsl"
;
const char SHADER_SKY[] =
@@ -398,9 +406,9 @@ namespace GAPI {
void init(Pass pass, int type, int *def, int defCount) {
const char *source;
switch (pass) {
case Core::passCompose :
case Core::passShadow :
case Core::passAmbient : source = SHADER_BASE; break;
case Core::passCompose : source = SHADER_COMPOSE; break;
case Core::passShadow : source = SHADER_SHADOW; break;
case Core::passAmbient : source = SHADER_AMBIENT; break;
case Core::passSky : source = SHADER_SKY; break;
case Core::passWater : source = SHADER_WATER; break;
case Core::passFilter : source = SHADER_FILTER; break;
@@ -411,9 +419,9 @@ namespace GAPI {
#ifdef _DEBUG_SHADERS
Stream *stream = NULL;
switch (pass) {
case Core::passCompose :
case Core::passShadow :
case Core::passAmbient : stream = new Stream("../../src/shaders/shader.glsl"); break;
case Core::passCompose : stream = new Stream("../../src/shaders/compose.glsl"); break;
case Core::passShadow : stream = new Stream("../../src/shaders/shadow.glsl"); break;
case Core::passAmbient : stream = new Stream("../../src/shaders/ambient.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;
@@ -448,7 +456,6 @@ namespace GAPI {
for (int i = 0; i < defCount; i++) {
sprintf(defines + strlen(defines), "#define %s\n", DefineName[def[i]]);
}
sprintf(defines + strlen(defines), "#define PASS_%s\n", passNames[pass]);
#if defined(_OS_RPI) || defined(_OS_CLOVER)
strcat(defines, "#define OPT_VLIGHTPROJ\n");

View File

@@ -71,6 +71,10 @@ struct Level : IGame {
float animTexTimer;
float statsTimeDelta;
vec3 underwaterColor;
vec4 underwaterFogParams;
vec4 levelFogParams;
// IGame implementation ========
virtual void loadLevel(TR::LevelID id) {
sndWater = sndTrack = NULL;
@@ -519,17 +523,6 @@ struct Level : IGame {
alphaTest = true;
}
setShader(Core::pass, type, room.flags.water, alphaTest);
if (room.flags.water) {
if (waterCache)
waterCache->bindCaustics(roomIndex);
setWaterParams(float(room.waterLevel[level.state.flags.flipped]));
} else
setWaterParams(NO_CLIP_PLANE);
Core::active.shader->setParam(uParam, Core::params);
#ifdef FFP
switch (type) {
case Shader::SPRITE :
@@ -549,7 +542,36 @@ struct Level : IGame {
}
#endif
Core::setMaterial(diffuse, ambient, specular, alpha);
vec4 material;
if (Core::pass == Core::passAmbient) {
if (room.flags.water) {
Core::fogParams = underwaterFogParams;
material = vec4(underwaterColor, 1.0f);
} else {
Core::fogParams = levelFogParams;
material = vec4(1.0f);
}
} else {
Core::fogParams = levelFogParams;
material = vec4(diffuse, ambient, specular, alpha);
}
setShader(Core::pass, type, (Core::pass == Core::passAmbient) ? false : room.flags.water, alphaTest);
Core::setMaterial(material.x, material.y, material.z, material.w);
if (room.flags.water) {
if (waterCache) {
waterCache->bindCaustics(roomIndex);
}
setWaterParams(float(room.waterLevel[level.state.flags.flipped]));
} else {
setWaterParams(NO_CLIP_PLANE);
}
Core::active.shader->setParam(uParam, Core::params);
Core::updateLights();
if (Core::settings.detail.shadows > Core::Settings::MEDIUM)
@@ -835,7 +857,9 @@ struct Level : IGame {
memset(players, 0, sizeof(players));
player = NULL;
Core::fogParams = TR::getFogParams(level.id);
underwaterColor = vec3(0.6f, 0.9f, 0.9f);
underwaterFogParams = vec4(underwaterColor * 0.2f, 1.0f / (6 * 1024));
levelFogParams = TR::getFogParams(level.id);
inventory->game = this;

View File

@@ -233,9 +233,11 @@
<ClInclude Include="..\..\video.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\shaders\ambient.glsl" />
<None Include="..\..\shaders\compose.glsl" />
<None Include="..\..\shaders\filter.glsl" />
<None Include="..\..\shaders\gui.glsl" />
<None Include="..\..\shaders\shader.glsl" />
<None Include="..\..\shaders\shadow.glsl" />
<None Include="..\..\shaders\sky.glsl" />
<None Include="..\..\shaders\water.glsl" />
</ItemGroup>

View File

@@ -69,10 +69,16 @@
<None Include="..\..\shaders\water.glsl">
<Filter>shaders</Filter>
</None>
<None Include="..\..\shaders\shader.glsl">
<None Include="..\..\shaders\sky.glsl">
<Filter>shaders</Filter>
</None>
<None Include="..\..\shaders\sky.glsl">
<None Include="..\..\shaders\shadow.glsl">
<Filter>shaders</Filter>
</None>
<None Include="..\..\shaders\ambient.glsl">
<Filter>shaders</Filter>
</None>
<None Include="..\..\shaders\compose.glsl">
<Filter>shaders</Filter>
</None>
</ItemGroup>

69
src/shaders/ambient.glsl Normal file
View File

@@ -0,0 +1,69 @@
R"====(
uniform mat4 uViewProj;
uniform vec4 uViewPos;
uniform vec4 uFogParams;
varying vec2 vTexCoord;
varying vec4 vDiffuse;
#ifdef VERTEX
uniform vec4 uBasis[2];
uniform vec4 uMaterial;
attribute vec4 aCoord;
attribute vec4 aTexCoord;
attribute vec3 aColor;
attribute vec3 aLight;
vec3 mulQuat(vec4 q, vec3 v) {
return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + v * q.w);
}
vec3 mulBasis(vec4 rot, vec3 pos, vec3 v) {
return mulQuat(rot, v) + pos;
}
void main() {
vTexCoord = aTexCoord.xy;
vec4 rBasisRot = uBasis[0];
vec4 rBasisPos = uBasis[1];
vec3 coord =
#ifdef TYPE_SPRITE
mulBasis(rBasisRot, rBasisPos.xyz + aCoord.xyz, vec3(aTexCoord.z, aTexCoord.w, 0.0) * 32767.0);
#else
mulBasis(rBasisRot, rBasisPos.xyz, aCoord.xyz);
#endif
vDiffuse.xyz = aColor.xyz * aLight.xyz * uMaterial.xyz;
float fog = length(uViewPos.xyz - coord.xyz) * uFogParams.w;
vDiffuse.w = clamp(1.0 / exp(fog), 0.0, 1.0);
gl_Position = uViewProj * vec4(coord, 1.0);
}
#else
uniform sampler2D sDiffuse;
void main() {
vec4 color = texture2D(sDiffuse, vTexCoord);
#ifdef ALPHA_TEST
if (color.w <= 0.5)
discard;
#endif
color.xyz *= vDiffuse.xyz;
color.xyz = mix(uFogParams.xyz, color.xyz, vDiffuse.w);
color.xyz *= color.w;
fragColor = color;
}
#endif
)===="

View File

@@ -8,16 +8,6 @@ R"====(
#define SHADOW_NORMAL_BIAS 16.0
#define SHADOW_CONST_BIAS 0.05
#if (defined(PASS_AMBIENT) || defined(PASS_COMPOSE)) && !defined(TYPE_FLASH)
varying vec3 vCoord;
#endif
varying vec4 vTexCoord; // xy - atlas coords, zw - trapezoidal correction
#ifdef OPT_VLIGHTVEC
varying vec3 vLightVec;
#endif
#ifdef OPT_CAUSTICS
uniform vec4 uRoomSize; // xy - minXZ, zw - maxXZ
#endif
@@ -40,21 +30,25 @@ uniform vec4 uLightColor[MAX_LIGHTS]; // xyz - color, w - radius * intensity
uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
uniform vec4 uFogParams;
#ifndef PASS_SHADOW
varying vec4 vViewVec; // xyz - dir * dist, w - coord.y * clipPlaneSign
varying vec4 vDiffuse;
varying vec4 vNormal; // xyz - normal dir, w - fog factor
#ifndef TYPE_FLASH
#ifdef PASS_COMPOSE
varying vec3 vCoord;
varying vec4 vNormal; // xyz - normal dir, w - fog factor
#ifdef OPT_SHADOW
varying vec3 vAmbient;
varying vec3 vLightMap;
#endif
#endif
varying vec4 vLight; // lights intensity (MAX_LIGHTS == 4)
#endif
varying vec4 vTexCoord; // xy - atlas coords, zw - trapezoidal correction
#ifdef OPT_VLIGHTVEC
varying vec3 vLightVec;
#endif
#ifdef OPT_SHADOW
@@ -89,10 +83,8 @@ uniform vec4 uFogParams;
attribute vec4 aTexCoord;
attribute vec4 aNormal;
#ifndef PASS_SHADOW
attribute vec4 aColor;
attribute vec4 aLight;
#endif
vec3 mulQuat(vec4 q, vec3 v) {
return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + v * q.w);
@@ -112,23 +104,16 @@ uniform vec4 uFogParams;
vec4 rBasisPos = uBasis[1];
#endif
vec4 coord;
coord.w = rBasisPos.w; // visible flag
#if defined(TYPE_SPRITE)
coord.xyz = mulBasis(rBasisRot, rBasisPos.xyz + aCoord.xyz, vec3(aTexCoord.z, aTexCoord.w, 0.0) * 32767.0);
vec3 coord =
#ifdef TYPE_SPRITE
mulBasis(rBasisRot, rBasisPos.xyz + aCoord.xyz, vec3(aTexCoord.z, aTexCoord.w, 0.0) * 32767.0);
#else
coord.xyz = mulBasis(rBasisRot, rBasisPos.xyz, aCoord.xyz);
mulBasis(rBasisRot, rBasisPos.xyz, aCoord.xyz);
#endif
#ifndef PASS_SHADOW
vViewVec = vec4((uViewPos.xyz - coord.xyz) * uFogParams.w, coord.y * uParam.z);
#endif
vViewVec = vec4((uViewPos.xyz - coord) * uFogParams.w, coord.y * uParam.z);
#ifdef PASS_AMBIENT
vNormal = aNormal;
#endif
#if defined(PASS_COMPOSE) && !defined(TYPE_FLASH)
#ifndef TYPE_FLASH
#ifdef TYPE_SPRITE
vNormal.xyz = normalize(vViewVec.xyz);
#else
@@ -136,31 +121,28 @@ uniform vec4 uFogParams;
#endif
float fog;
#if defined(UNDERWATER) && defined(OPT_UNDERWATER_FOG)
#if defined(UNDERWATER) && !defined(OPT_UNDERWATER_FOG)
float d;
if (uViewPos.y < uParam.y) // TODO: fix for mediump
d = abs((coord.y - uParam.y) / normalize(uViewPos.xyz - coord.xyz).y);
d = abs((coord.y - uParam.y) / normalize(uViewPos.xyz - coord).y);
else
d = length(uViewPos.xyz - coord.xyz);
d = length(uViewPos.xyz - coord);
fog = d * WATER_FOG_DIST;
fog *= step(uParam.y, coord.y);
vNormal.w = fog;
vNormal.w = clamp(1.0 / exp(fog), 0.0, 1.0);
#else
fog = length(vViewVec.xyz);
vNormal.w = clamp(1.0 / exp(fog), 0.0, 1.0);
#endif
vCoord = coord.xyz;
vCoord = coord;
#endif
return coord;
return vec4(coord, rBasisPos.w);
}
void _diffuse() {
#ifndef PASS_SHADOW
vDiffuse = vec4(aColor.xyz * uMaterial.x, 1.0);
#ifdef PASS_COMPOSE
vDiffuse.xyz *= 2.0;
#endif
#ifdef TYPE_MIRROR
vDiffuse.xyz = uMaterial.xyz;
@@ -175,12 +157,10 @@ uniform vec4 uFogParams;
#ifdef TYPE_SPRITE
vDiffuse *= aLight.w;
#endif
#endif
}
void _lighting(vec3 coord) {
#ifndef TYPE_FLASH
#ifdef PASS_COMPOSE
vec3 lv0 = (uLightPos[0].xyz - coord) * uLightColor[0].w;
vec3 lv1 = (uLightPos[1].xyz - coord) * uLightColor[1].w;
vec3 lv2 = (uLightPos[2].xyz - coord) * uLightColor[2].w;
@@ -242,19 +222,14 @@ uniform vec4 uFogParams;
#else
vLight.xyz += aLight.xyz * light.x;
#endif
#endif
#endif
#ifdef PASS_AMBIENT
vLight = vec4(aLight.xyz, 1.0);
#endif
#endif
}
void _uv(vec3 coord) {
vTexCoord = aTexCoord;
#if defined(PASS_COMPOSE) && !defined(TYPE_SPRITE)
#ifndef TYPE_SPRITE
#ifdef OPT_TRAPEZOID
vTexCoord.xy *= vTexCoord.zw;
#endif
@@ -264,27 +239,22 @@ uniform vec4 uFogParams;
void main() {
vec4 coord = _transform();
#ifndef PASS_SHADOW
_diffuse();
_lighting(coord.xyz);
#endif
_uv(coord.xyz);
gl_Position = uViewProj * coord;
}
#else
uniform sampler2D sDiffuse;
#if defined(PASS_COMPOSE) && defined(TYPE_MIRROR)
#ifdef TYPE_MIRROR
uniform samplerCube sEnvironment;
#endif
vec4 pack(float value) {
vec4 v = fract(value * vec4(1.0, 255.0, 65025.0, 16581375.0));
return v - v.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
}
float unpack(vec4 value) {
return dot(value, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
}
@@ -392,14 +362,10 @@ uniform vec4 uFogParams;
vec2 uv = vTexCoord.xy;
vec4 color;
#ifdef TYPE_MIRROR
#ifdef PASS_COMPOSE
vec3 rv = reflect(-normalize(vViewVec.xyz), normalize(vNormal.xyz));
color = textureCube(sEnvironment, normalize(rv));
#else
color = vec4(1.0);
#endif
#else
#if defined(PASS_COMPOSE) && !defined(TYPE_SPRITE)
#ifndef TYPE_SPRITE
#ifdef OPT_TRAPEZOID
uv /= vTexCoord.zw;
#endif
@@ -413,25 +379,10 @@ uniform vec4 uFogParams;
discard;
#endif
#ifdef PASS_SHADOW
#ifdef SHADOW_COLOR
fragColor = pack(gl_FragCoord.z);
#else
fragColor = vec4(1.0);
#endif
#else
color *= vDiffuse;
#if !defined(TYPE_FLASH) && !defined(TYPE_MIRROR)
#ifdef PASS_AMBIENT
color.xyz *= vLight.xyz;
#endif
#ifdef PASS_COMPOSE
#ifndef OPT_VLIGHTVEC
vec3 vLightVec = (uLightPos[0].xyz - vCoord) * uLightColor[0].w;
#endif
@@ -504,16 +455,15 @@ uniform vec4 uFogParams;
color.xyz = mix(UNDERWATER_COLOR * 0.2, color.xyz, fog);
#else
color.xyz = mix(color.xyz, color.xyz * UNDERWATER_COLOR, uwSign);
color.xyz = mix(uFogParams.xyz, color.xyz, vNormal.w);
color.xyz = mix(UNDERWATER_COLOR * 0.2, color.xyz, vNormal.w);
#endif
#else
color.xyz = mix(uFogParams.xyz, color.xyz, vNormal.w);
#endif
#endif
#endif
fragColor = color;
#endif
}
#endif
)===="

60
src/shaders/shadow.glsl Normal file
View File

@@ -0,0 +1,60 @@
R"====(
#ifdef ALPHA_TEST
varying vec2 vTexCoord;
#endif
#ifdef VERTEX
uniform mat4 uViewProj;
uniform vec4 uBasis[32 * 2];
attribute vec4 aCoord;
#ifdef ALPHA_TEST
attribute vec4 aTexCoord;
#endif
vec3 mulQuat(vec4 q, vec3 v) {
return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + v * q.w);
}
vec3 mulBasis(vec4 rot, vec3 pos, vec3 v) {
return mulQuat(rot, v) + pos;
}
void main() {
int index = int(aCoord.w * 2.0);
vec4 rBasisRot = uBasis[index];
vec4 rBasisPos = uBasis[index + 1];
#ifdef ALPHA_TEST
vTexCoord = aTexCoord.xy;
#endif
vec3 coord = mulBasis(rBasisRot, rBasisPos.xyz, aCoord.xyz);
gl_Position = uViewProj * vec4(coord, rBasisPos.w);
}
#else
#ifdef ALPHA_TEST
uniform sampler2D sDiffuse;
#endif
vec4 pack(float value) {
vec4 v = fract(value * vec4(1.0, 255.0, 65025.0, 16581375.0));
return v - v.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
}
void main() {
#ifdef ALPHA_TEST
if (texture2D(sDiffuse, vTexCoord).w <= 0.5)
discard;
#endif
#ifdef SHADOW_COLOR
fragColor = pack(gl_FragCoord.z);
#else
fragColor = vec4(1.0);
#endif
}
#endif
)===="