1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-09 06:36:59 +02:00

#15 optimize water_compose shader

This commit is contained in:
XProger
2019-01-20 16:43:26 +03:00
parent 337ed5370c
commit dfb03065b3
6 changed files with 89 additions and 74 deletions

View File

@@ -837,7 +837,11 @@ struct WaterCache {
if (screen) {
Core::setTarget(refract, NULL, RT_LOAD_DEPTH | RT_STORE_COLOR | RT_STORE_DEPTH);
blitTexture(screen);
bool flip = false;
#if defined(_GAPI_D3D9) || defined(_GAPI_GXM)
flip = true;
#endif
blitTexture(screen, flip);
Core::setTarget(screen, NULL, RT_LOAD_COLOR | RT_LOAD_DEPTH | RT_STORE_COLOR);
} else {
Core::copyTarget(refract, 0, 0, x, y, Core::viewportDef.width, Core::viewportDef.height); // copy framebuffer into refraction texture
@@ -947,7 +951,7 @@ struct WaterCache {
game->setShader(Core::passWater, Shader::WATER_COMPOSE);
Core::updateLights();
Core::active.shader->setParam(uParam, vec4(float(refract->origWidth) / refract->width, float(refract->origHeight) / refract->height, 0.05f, 0.03f));
Core::active.shader->setParam(uParam, vec4(float(refract->origWidth) / refract->width, float(refract->origHeight) / refract->height, 0.05f, 0.0f));
float sx = item.size.x * DETAIL / (item.data[0]->width / 2);
float sz = item.size.z * DETAIL / (item.data[0]->height / 2);
@@ -976,7 +980,7 @@ struct WaterCache {
dropCount = 0;
}
void blitTexture(Texture *tex) {
void blitTexture(Texture *tex, bool flip = false) {
ASSERT(tex);
game->setShader(Core::passGUI, Shader::DEFAULT);
@@ -1001,17 +1005,21 @@ struct WaterCache {
vertices[2].light =
vertices[3].light = ubyte4(255, 255, 255, 255);
#if defined(_GAPI_D3D9) || defined(_GAPI_GXM)
vertices[0].texCoord = short4( 0, 0, 0, 0);
vertices[1].texCoord = short4(32767, 0, 0, 0);
vertices[2].texCoord = short4(32767, 32767, 0, 0);
vertices[3].texCoord = short4( 0, 32767, 0, 0);
#else
vertices[0].texCoord = short4( 0, 32767, 0, 0);
vertices[1].texCoord = short4(32767, 32767, 0, 0);
vertices[2].texCoord = short4(32767, 0, 0, 0);
vertices[3].texCoord = short4( 0, 0, 0, 0);
#endif
#if defined(_GAPI_D3D9) || defined(_GAPI_GXM)
flip = !flip;
#endif
if (flip) {
vertices[0].texCoord = short4( 0, 0, 0, 0);
vertices[1].texCoord = short4(32767, 0, 0, 0);
vertices[2].texCoord = short4(32767, 32767, 0, 0);
vertices[3].texCoord = short4( 0, 32767, 0, 0);
} else {
vertices[0].texCoord = short4( 0, 32767, 0, 0);
vertices[1].texCoord = short4(32767, 32767, 0, 0);
vertices[2].texCoord = short4(32767, 0, 0, 0);
vertices[3].texCoord = short4( 0, 0, 0, 0);
}
Core::setDepthTest(false);
Core::setBlendMode(bmNone);

View File

@@ -9,6 +9,7 @@
#define WATER_FOG_DIST (1.0 / (6.0 * 1024.0))
#define WATER_COLOR_DIST (1.0 / (2.0 * 1024.0))
#define UNDERWATER_COLOR float3(0.6, 0.9, 0.9)
#define UNDERWATER_COLOR_H half3(0.6, 0.9, 0.9)
#define SHADOW_NORMAL_BIAS 16.0
#define SHADOW_CONST_BIAS 0.05
#define SHADOW_SIZE 1024
@@ -103,12 +104,23 @@ float calcCaustics(float3 coord, float3 n) {
return tex2Dlod(sReflect, float4(cc.x, 1.0 - cc.y, 0, 0)).x * max(0.0, -n.y);
}
half3 calcNormal(float2 tc, half base) {
half3 calcNormalV(float2 tc, half base) {
half dx = (half)tex2Dlod(sNormal, float4(tc.x + uTexParam.x, tc.y, 0, 0)).x - base;
half dz = (half)tex2Dlod(sNormal, float4(tc.x, tc.y + uTexParam.y, 0, 0)).x - base;
return normalize( half3(dx, 64.0 / (1024.0 * 8.0), dz) );
}
float3 calcNormalF(float2 tcR, float2 tcB, float base) {
float dx = tex2D(sNormal, tcR).x - base;
float dz = tex2D(sNormal, tcB).x - base;
return normalize( float3(dx, 64.0 / (1024.0 * 8.0), dz) );
}
half calcFresnel(half VoH, half f0) {
half f = pow(1.0 - VoH, 5.0);
return f + f0 * (1.0f - f);
}
void applyFogUW(inout float3 color, float3 coord, float waterFogDist) {
float dist;
if (uViewPos.y < uParam.y)

View File

@@ -45,8 +45,8 @@ EXIT /B %ERRORLEVEL%
echo compile gxm/%~1%~2 %~3
echo #include "%~1%~2_v.h" >> gxm/shaders.h
echo #include "%~1%~2_f.h" >> gxm/shaders.h
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic %~1.hlsl -o gxm/%~1%~2_v.gxp %~3 -DVERTEX
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic %~1.hlsl -o gxm/%~1%~2_f.gxp %~3 -DPIXEL
psp2cgc -profile sce_vp_psp2 -W4 -Wperf -pedantic %~1.hlsl -cache -o gxm/%~1%~2_v.gxp %~3 -DVERTEX
psp2cgc -profile sce_fp_psp2 -W4 -Wperf -pedantic %~1.hlsl -cache -o gxm/%~1%~2_f.gxp %~3 -DPIXEL
ENDLOCAL
EXIT /B 0

View File

@@ -94,6 +94,11 @@ vec3 calcNormal(vec2 tc, float base) {
#endif
vViewVec = uViewPos.xyz - vCoord.xyz;
vLightVec = uLightPos[0].xyz - vCoord.xyz;
#ifdef WATER_COMPOSE
vViewVec.y = abs(vViewVec.y);
vLightVec.y = abs(vLightVec.y);
#endif
}
#else
uniform sampler2D sDiffuse;
@@ -212,7 +217,6 @@ vec3 calcNormal(vec2 tc, float base) {
vec2 value = texture2D(sNormal, vTexCoord).xy;
vec3 normal = calcNormal(vTexCoord, value.x);
normal.y *= sign(viewVec.y);
vec2 dudv = (uViewProj * vec4(normal.x, 0.0, normal.z, 0.0)).xy;

View File

@@ -31,7 +31,7 @@ VS_OUTPUT main(VS_INPUT In) {
float2 uv = getInvUV(rCoord.xy, uTexParam).xy;
float2 info = tex2Dlod(sNormal, float4(uv, 0, 0)).xy;
float3 normal = calcNormal(uv, info.x).xzy;
float3 normal = calcNormalV(uv, info.x).xzy;
float3 light = float3(0.0, 0.0, 1.0);
float3 refOld = refract(-light, float3(0.0, 0.0, 1.0), 0.75);

View File

@@ -2,86 +2,77 @@
struct VS_OUTPUT {
float4 pos : POSITION;
float3 coord : TEXCOORD0;
float2 texCoord : TEXCOORD1;
float2 maskCoord : TEXCOORD2;
float3 viewVec : TEXCOORD3;
half2 texCoord : TEXCOORD1;
half2 maskCoord : TEXCOORD2;
half2 texCoordR : TEXCOORD6;
half2 texCoordB : TEXCOORD7;
float4 viewVec : TEXCOORD3;
float3 lightVec : TEXCOORD4;
float3 hpos : TEXCOORD5;
};
float2 invUV(float2 uv) {
return float2(uv.x, 1.0 - uv.y);
}
float2 getInvUV(float2 uv, float4 param) {
float2 p = (float2(uv.x, -uv.y) * 0.5 + 0.5) * param.zw;
#ifndef _GAPI_GXM
p.xy += 0.5 * param.xy;
#endif
return p;
}
float2 getUV(float2 uv, float4 param) {
return (uv.xy * 0.5 + 0.5) * param.zw;
}
#ifdef VERTEX
VS_OUTPUT main(VS_INPUT In) {
VS_OUTPUT Out;
float3 coord = In.aCoord.xyz * (1.0 / 32767.0);
Out.coord = float3(coord.x, 0.0, coord.y) * uPosScale[1].xyz + uPosScale[0].xyz;
Out.pos = mul(uViewProj, float4(Out.coord, 1.0));
Out.viewVec = uViewPos.xyz - Out.coord.xyz;
Out.lightVec = uLightPos[0].xyz - Out.coord.xyz;
Out.texCoord = getInvUV(coord.xy, uTexParam);
Out.maskCoord = getUV(coord.xy, uRoomSize);
Out.hpos = Out.pos.xyw;
float4 uv = float4(coord.x, coord.y, coord.x, -coord.y) * 0.5 + 0.5;
Out.maskCoord = uv.xy * uRoomSize.zw;
Out.texCoord = uv.zw * uTexParam.zw;
#ifndef _GAPI_GXM
Out.texCoord += 0.5 * uTexParam.xy;
#endif
coord = float3(coord.x, 0.0, coord.y) * uPosScale[1].xyz + uPosScale[0].xyz;
Out.pos = mul(uViewProj, float4(coord, 1.0));
Out.hpos = Out.pos.xyw;
Out.viewVec.xyz = uViewPos.xyz - coord;
Out.viewVec.y = abs(Out.viewVec.y);
Out.lightVec.y = abs(Out.lightVec.y);
Out.lightVec = uLightPos[0].xyz - coord;
Out.viewVec.w = step(uPosScale[0].y, uViewPos.y) * WATER_COLOR_DIST;
Out.texCoordR = Out.texCoord + float2(uTexParam.x, 0.0);
Out.texCoordB = Out.texCoord + float2(0.0, uTexParam.y);
return Out;
}
#else // PIXEL
float calcFresnel(float VoH, float f0) {
float f = pow(1.0 - VoH, 5.0);
return f + f0 * (1.0f - f);
}
float4 main(VS_OUTPUT In) : COLOR0 {
float3 viewVec = normalize(In.viewVec);
half4 main(VS_OUTPUT In) : COLOR0 {
float3 viewVec = normalize(In.viewVec.xyz);
float2 value = tex2D(sNormal, In.texCoord).xy;
float3 normal = calcNormal(In.texCoord, value.x);
normal.y *= sign(viewVec.y);
float2 dudv = mul(uViewProj, float4(normal.x, 0.0, normal.z, 0.0)).xy;
float base = tex2D(sNormal, In.texCoord).x;
float3 normal = calcNormalF(In.texCoordR, In.texCoordB, base);
float2 dudv = mul(uViewProj, float4(normal.x, 0.0, normal.z, 0.0)).xy * uParam.z;
float3 rv = reflect(-viewVec, normal);
float3 lv = normalize(In.lightVec);
float spec = pow(max(0.0, dot(rv, lv)), 64.0) * 0.5;
half specular = pow(max(0.0, dot(rv, lv)), 64.0) * 0.75;
float2 tc = In.hpos.xy / In.hpos.z * 0.5 + 0.5;
float4 refrA = tex2D(sDiffuse, uParam.xy * invUV(clamp(tc + dudv * uParam.z, 0.0, 0.999)));
float4 refrB = tex2D(sDiffuse, uParam.xy * invUV(tc));
float4 refr = float4(lerp(refrA.xyz, refrB.xyz, refrA.w), 1.0);
float4 refl = tex2D(sReflect, tc.xy + dudv * uParam.w);
half4 refrA = tex2D(sDiffuse, tc - dudv);
half4 refrB = tex2D(sDiffuse, tc);
half3 refr = lerp(refrA.xyz, refrB.xyz, refrA.w);
half3 refl = tex2D(sReflect, tc + dudv).xyz;
float fresnel = calcFresnel(max(0.0, dot(normal, viewVec)), 0.12);
half fresnel = calcFresnel(max(0.0, dot(normal, viewVec)), 0.12);
half4 color = half4(lerp(refr, refl, fresnel), tex2D(sMask, In.maskCoord).a);
color.xyz += specular;
float dist = (In.viewVec.y / viewVec.y) * In.viewVec.w;
color.xyz *= lerp((half3)1.0, UNDERWATER_COLOR_H, (half)clamp(dist, 0.0, 2.0));
half fog = saturate(1.0h / exp(dist));
color.xyz = lerp(UNDERWATER_COLOR_H * 0.2, color.xyz, fog);
float4 color = lerp(refr, refl, fresnel) + spec * 1.5;
color.w *= tex2D(sMask, In.maskCoord).a;
float dist = In.viewVec.y / viewVec.y;
dist *= step(In.coord.y, uViewPos.y);
color.xyz *= lerp(float3(1.0, 1.0, 1.0), UNDERWATER_COLOR, clamp(dist * WATER_COLOR_DIST, 0.0, 2.0));
float fog = saturate(1.0 / exp(dist * WATER_FOG_DIST));
color.xyz = lerp(UNDERWATER_COLOR * 0.2, color.xyz, fog);
return color;
}