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

update d3d9 shaders (water, caustics, filter)

This commit is contained in:
XProger
2018-10-18 06:30:26 +03:00
parent 6f39bdd045
commit 621c0495e7
3 changed files with 66 additions and 21 deletions

View File

@@ -52,10 +52,11 @@ float4 uContacts[MAX_CONTACTS] : register( c94 );
#define FILTER_EQUIRECTANGULAR uFlags[4]
#define WATER_DROP uFlags[0]
#define WATER_STEP uFlags[1]
#define WATER_SIMULATE uFlags[1]
#define WATER_CAUSTICS uFlags[2]
#define WATER_MASK uFlags[3]
#define WATER_COMPOSE uFlags[4]
#define WATER_RAYS uFlags[3]
#define WATER_MASK uFlags[4]
#define WATER_COMPOSE uFlags[5]
// options for compose, shadow, ambient passes
#define UNDERWATER uFlags[5]

View File

@@ -45,14 +45,14 @@ float4 downsample(float2 uv) { // uParam (1 / textureSize, unused, unused, unuse
float4 grayscale(float2 uv) { // uParam (factor, unused, unused, unused)
float4 color = tex2D(sDiffuse, uv);
float3 gray = dot(color, float4(0.299, 0.587, 0.114, 0.0));
return float4(lerp(color.xyz, gray, uParam.x), color.w);
return float4(lerp(color.xyz, gray, uParam.w) * uParam.bgr, color.w);
}
float4 blur(float2 uv) { // uParam (dirX, dirY, 1 / textureSize, unused)
const float3 offset = float3( 0.0, 1.3846153846, 3.2307692308);
const float3 weight = float3(0.2270270270, 0.3162162162, 0.0702702703);
float2 dir = uParam.xy * uParam.z;
float2 dir = uParam.xy;
float4 color = tex2D(sDiffuse, uv) * weight[0];
color += tex2D(sDiffuse, uv + dir * offset[1]) * weight[1];
color += tex2D(sDiffuse, uv - dir * offset[1]) * weight[1];
@@ -79,7 +79,7 @@ float4 main(VS_OUTPUT In) : COLOR0 {
return grayscale(In.texCoord.xy);
if (FILTER_BLUR)
rreturn blur(In.texCoord.xy);
return blur(In.texCoord.xy);
return upscale(In.texCoord.xy) * In.diffuse;
}

View File

@@ -27,15 +27,15 @@ VS_OUTPUT main(VS_INPUT In) {
if (WATER_COMPOSE) {
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.pos = mul(uViewProj, float4(Out.coord, 1.0));
Out.viewVec = uViewPos.xyz - Out.coord.xyz;
Out.lightVec = uLightPos[0].xyz - Out.coord.xyz;
Out.oldPos = getInvUV(coord.xy, uTexParam);
} else if (WATER_DROP) {
Out.pos = float4(coord.xyz, 1.0);
Out.oldPos = getInvUV(coord.xy, uTexParam);
} else if (WATER_STEP) {
Out.pos = float4(coord.xyz, 1.0);
} else if (WATER_SIMULATE) {
Out.pos = float4(coord.xyz, 1.0);
Out.oldPos = getInvUV(coord.xy, uTexParam);
} else if (WATER_CAUSTICS) {
float3 rCoord = float3(coord.x, coord.y, 0.0) * uPosScale[1].xzy;
@@ -54,7 +54,11 @@ VS_OUTPUT main(VS_INPUT In) {
} else if (WATER_MASK) {
Out.coord = float3(coord.x, 0.0, coord.y) * uPosScale[1].xyz + uPosScale[0].xyz;
Out.pos = mul(uViewProj, float4(Out.coord, 1.0));
}
} else if (WATER_RAYS) {
Out.coord = In.aCoord.xyz + uParam.xyz;
Out.viewVec = uViewPos.xyz - Out.coord.xyz;
Out.pos = mul(uViewProj, float4(Out.coord, 1.0));
}
Out.texCoord = (coord.xy * 0.5 + 0.5) * uTexParam.zw + 0.5 * uTexParam.xy; // + half texel offset
Out.hpos = Out.pos;
@@ -64,9 +68,9 @@ VS_OUTPUT main(VS_INPUT In) {
#else // PIXEL
float calcFresnel(float NdotL, float fbias) {
float f = 1.0 - NdotL;
return saturate(fbias + (1.0 - fbias) * (f * f));
float calcFresnel(float VoH, float f0) {
float f = pow(1.0 - VoH, 5.0);
return f + f0 * (1.0f - f);
}
float3 applyFog(float3 color, float3 fogColor, float factor) {
@@ -118,7 +122,7 @@ float h(float2 tc) {
return simplex_noise(float3(tc * 16.0, uParam.w)) * 0.0005;
}
float4 calc(VS_OUTPUT In) {
float4 simulate(VS_OUTPUT In) {
float2 iuv = In.oldPos.xy;
float2 uv = In.texCoord;
@@ -157,6 +161,43 @@ float4 caustics(VS_OUTPUT In) {
return float4(value, 0.0, 0.0, 0.0);
}
float boxIntersect(float3 rayPos, float3 rayDir, float3 center, float3 hsize) {
center -= rayPos;
float3 bMin = (center - hsize) / rayDir;
float3 bMax = (center + hsize) / rayDir;
float3 m = min(bMin, bMax);
return max(0.0, max(m.x, max(m.y, m.z)));
}
float4 rays(VS_OUTPUT In, float4 pixelCoord) {
#define RAY_STEPS 16.0
float3 viewVec = normalize(In.viewVec);
float t = boxIntersect(uViewPos.xyz, -viewVec, uPosScale[0].xyz, uPosScale[1].xyz);
float3 p0 = uViewPos.xyz - viewVec * t;
float3 p1 = In.coord.xyz;
float dither = tex2D(sMask, pixelCoord.xy * (1.0 / 8.0)).x;
float3 step = (p1 - p0) / RAY_STEPS;
float3 pos = p0 + step * dither;
float sum = 0.0;
for (float i = 0.0; i < RAY_STEPS; i++) {
float3 wpos = (pos - uPosScale[0].xyz) / uPosScale[1].xyz;
float2 tc = wpos.xz * 0.5 + 0.5;
float light = tex2D(sReflect, tc).x;
sum += light * (1.0 - (clamp(wpos.y, -1.0, 1.0) * 0.5 + 0.5));
pos += step;
}
sum /= RAY_STEPS;
sum *= uParam.w;
return float4(UNDERWATER_COLOR * sum, 1.0);
}
float4 mask(VS_OUTPUT In) {
return 0.0;
}
@@ -167,7 +208,7 @@ float4 compose(VS_OUTPUT In) {
float4 value = tex2D(sNormal, iuv);
float3 normal = float3(value.z, sqrt(1.0 - dot(value.zw, value.zw)) * sign(viewVec.y), value.w);
float2 dudv = mul(uViewProj, float4(normal.x, 0.0, normal.z, 0.0)).xy;
float2 dudv = mul(uViewProj, float4(normal.x, 0.0, normal.z, 0.0)).xy;
float3 rv = reflect(-viewVec, normal);
float3 lv = normalize(In.lightVec);
@@ -178,10 +219,10 @@ float4 compose(VS_OUTPUT In) {
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);
float4 refr = float4(lerp(refrA.xyz, refrB.xyz, refrA.w), 1.0);
float4 refl = tex2D(sReflect, tc.xy + dudv * uParam.w);
float fresnel = calcFresnel(dot(normal, viewVec), 0.04);
float fresnel = calcFresnel(max(0.0, dot(normal, viewVec)), 0.12);
float4 color = lerp(refr, refl, fresnel) + spec * 1.5;
@@ -192,15 +233,18 @@ float4 compose(VS_OUTPUT In) {
return color;
}
float4 main(VS_OUTPUT In) : COLOR0 {
float4 main(VS_OUTPUT In, float4 pixelCoord: VPOS) : COLOR0 {
if (WATER_DROP)
return drop(In);
if (WATER_STEP)
return calc(In);
if (WATER_SIMULATE)
return simulate(In);
if (WATER_CAUSTICS)
return caustics(In);
if (WATER_RAYS)
return rays(In, pixelCoord);
if (WATER_MASK)
return mask(In);