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:
36
src/cache.h
36
src/cache.h
@@ -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);
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user