Apply patch by vlj to improve rendering, thanks a lot!
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14739 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
73f9779324
commit
c6fd5cde1c
@ -1,78 +1,59 @@
|
||||
#version 120
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D oldtex;
|
||||
uniform sampler2D normals_and_depth;
|
||||
uniform sampler2D depth;
|
||||
uniform mat4 invprojm;
|
||||
uniform mat4 projm;
|
||||
uniform vec4 samplePoints[16];
|
||||
|
||||
const float totStrength = 2.38;
|
||||
const float strength = 0.07;
|
||||
const float falloff = 0.000002;
|
||||
const float strengh = 1.;
|
||||
const float radius = 0.1f;
|
||||
const float threshold = 0.1;
|
||||
|
||||
#define SAMPLES 16
|
||||
|
||||
const float invSamples = 1.0 / SAMPLES;
|
||||
const float invSamples = strengh / SAMPLES;
|
||||
|
||||
float decdepth(vec4 rgba) {
|
||||
return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
// A set of Random(tm) vec2's. 8 1s, 6 0.7s, 2 0.4
|
||||
// Again not using const because of broken Intel Windows drivers
|
||||
vec2 vecs[16] = vec2[](vec2(0.43589, -0.9), vec2(-0.9, 0.43589),
|
||||
vec2(-0.8, -0.6), vec2(0.6, 0.8),
|
||||
vec2(0.866025, -0.5), vec2(-0.5, 0.866025),
|
||||
vec2(-0.3, -0.953939), vec2(0.953939, 0.3),
|
||||
vec2(0.3, -0.781025), vec2(-0.781025, 0.3),
|
||||
vec2(-0.56, -0.621611), vec2(0.621611, 0.56),
|
||||
vec2(0.734847, -0.4), vec2(-0.4, 0.734847),
|
||||
vec2(-0.2, -0.6), vec2(0.6, 0.2));
|
||||
|
||||
|
||||
vec2 uv = gl_TexCoord[0].xy;
|
||||
|
||||
vec4 cur = texture2D(tex, uv);
|
||||
float curdepth = cur.a;
|
||||
|
||||
// Will we skip this pixel? (if it's the sky)
|
||||
float len = dot(vec3(1.0), abs(cur.xyz));
|
||||
if (len < 0.2 || curdepth > 0.8) discard;
|
||||
|
||||
float mytotstrength = 3.0 * totStrength * curdepth * (1.0 - curdepth);
|
||||
vec4 cur = texture2D(normals_and_depth, uv);
|
||||
float curdepth = decdepth(vec4(texture2D(depth, uv).xyz, 0.0));
|
||||
vec4 FragPos = invprojm * (2.0f * vec4(uv, curdepth, 1.0f) - 1.0f);
|
||||
FragPos /= FragPos.w;
|
||||
|
||||
// get the normal of current fragment
|
||||
vec3 norm = normalize(cur.xyz * vec3(2.0) - vec3(1.0));
|
||||
if (curdepth > 0.99) discard;
|
||||
vec3 tangent = normalize(cross(norm, norm.yzx));
|
||||
vec3 bitangent = cross(norm, tangent);
|
||||
|
||||
float bl = 0.0;
|
||||
|
||||
// adjust for the depth, 0.1 close, 0.01 far
|
||||
float radD = 0.10 - 0.09 * smoothstep(0.0, 0.2, curdepth);
|
||||
|
||||
for(int i = 0; i < SAMPLES; ++i) {
|
||||
|
||||
vec2 ray = uv + radD * vecs[i];
|
||||
vec3 sampleDir = samplePoints[i].x * tangent + samplePoints[i].y * bitangent + samplePoints[i].z * norm;
|
||||
vec4 samplePos = FragPos + radius * vec4(sampleDir, 0.0);
|
||||
vec4 sampleProj = projm * samplePos;
|
||||
sampleProj /= sampleProj.w;
|
||||
|
||||
// get the depth of the occluder fragment
|
||||
vec4 occluderFragment = texture2D(tex, ray);
|
||||
float normAcceptable = step(0.2, dot(vec3(1.0), abs(occluderFragment.xyz)));
|
||||
float occluderFragmentDepth = decdepth(vec4(texture2D(depth, (sampleProj.xy * 0.5) + 0.5).xyz, 0.0));
|
||||
|
||||
// get the normal of the occluder fragment
|
||||
vec3 occNorm = normalize(occluderFragment.xyz * vec3(2.0) - vec3(1.0));
|
||||
|
||||
// if depthDifference is negative = occluder is behind current fragment
|
||||
float depthDifference = curdepth - occluderFragment.a;
|
||||
|
||||
// calculate the difference between the normals as a weight
|
||||
float normDiff = 1.0 - max(dot(occNorm, norm), 0.0);
|
||||
normDiff = smoothstep(0.1, 0.3, normDiff);
|
||||
|
||||
// the falloff equation, starts at falloff and is kind of 1/x^2 falling
|
||||
bl += step(falloff, depthDifference) * normDiff * normAcceptable *
|
||||
(1.0 - smoothstep(falloff, strength, depthDifference));
|
||||
float depthDifference = sampleProj.z - (2. * occluderFragmentDepth - 1.0);
|
||||
bl += (abs(depthDifference) < threshold) ? step(0., depthDifference) : 0.0;
|
||||
}
|
||||
|
||||
// output the result
|
||||
float ao = 1.0 - mytotstrength * bl * invSamples;
|
||||
|
||||
// Mix with old result to avoid flicker
|
||||
float oldao = texture2D(oldtex, uv).x;
|
||||
|
||||
ao = mix(ao, oldao, 0.3);
|
||||
float ao = 1.0 - bl * invSamples;
|
||||
|
||||
gl_FragColor = vec4(vec3(ao), curdepth + 0.05); // offset so that the alpha test doesn't kill us
|
||||
}
|
||||
|
@ -521,13 +521,36 @@ void MLAANeigh3Provider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
|
||||
void SSAOProvider::OnSetConstants(IMaterialRendererServices *srv, int)
|
||||
{
|
||||
static const float array[64] = {
|
||||
0.43589, -0.9, 0.667945, 0.,
|
||||
-0.9, 0.43589, 0.667945, 0.,
|
||||
-0.8, -0.6, 0.7, 0.,
|
||||
0.6, 0.8, 0.7, 0.,
|
||||
0.866025, -0.5, 0.6830125, 0.,
|
||||
-0.5, 0.866025, 0.6830125, 0.,
|
||||
-0.3, -0.953939, 0.6269695, 0.,
|
||||
0.953939, 0.3, 0.6269695, 0.,
|
||||
0.3, -0.781025, 0.5405125, 0.,
|
||||
-0.781025, 0.3, 0.5405125, 0.,
|
||||
-0.56, -0.621611, 0.5908055, 0.,
|
||||
0.621611, 0.56, 0.5908055, 0.,
|
||||
0.734847, -0.4, 0.5674235, 0.,
|
||||
-0.4, 0.734847, 0.5674235, 0.,
|
||||
-0.2, -0.6, 0.4, 0.,
|
||||
0.6, 0.2, 0.4, 0.,
|
||||
};
|
||||
|
||||
srv->setPixelShaderConstant("invprojm", invprojm.pointer(), 16);
|
||||
srv->setPixelShaderConstant("projm", projm.pointer(), 16);
|
||||
srv->setPixelShaderConstant("samplePoints[0]", array, 64);
|
||||
|
||||
if (!firstdone)
|
||||
{
|
||||
int tex = 0;
|
||||
srv->setPixelShaderConstant("tex", &tex, 1);
|
||||
srv->setPixelShaderConstant("normals_and_depth", &tex, 1);
|
||||
|
||||
tex = 1;
|
||||
srv->setPixelShaderConstant("oldtex", &tex, 1);
|
||||
srv->setPixelShaderConstant("depth", &tex, 1);
|
||||
|
||||
firstdone = true;
|
||||
}
|
||||
|
@ -539,8 +539,18 @@ public:
|
||||
|
||||
class SSAOProvider: public CallBase
|
||||
{
|
||||
private:
|
||||
core::matrix4 projm, invprojm;
|
||||
public:
|
||||
virtual void OnSetConstants(video::IMaterialRendererServices *srv, int);
|
||||
void updateIPVMatrix()
|
||||
{
|
||||
// Update the IPV matrix, only once per frame since it's costly
|
||||
const video::IVideoDriver * const drv = irr_driver->getVideoDriver();
|
||||
|
||||
projm = drv->getTransform(video::ETS_PROJECTION);
|
||||
projm.getInverse(invprojm);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -224,7 +224,7 @@ void PostProcessing::renderSolid(const u32 cam)
|
||||
{
|
||||
m_material.MaterialType = irr_driver->getShader(ES_SSAO);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL));
|
||||
m_material.setTexture(1, irr_driver->getRTT(tick ? RTT_SSAO1 : RTT_SSAO2));
|
||||
m_material.setTexture(1, irr_driver->getRTT(RTT_DEPTH));
|
||||
|
||||
drv->setRenderTarget(irr_driver->getRTT(curssao), true, false,
|
||||
SColor(255, 255, 255, 255));
|
||||
@ -265,7 +265,7 @@ void PostProcessing::renderSolid(const u32 cam)
|
||||
{
|
||||
m_material.MaterialType = irr_driver->getShader(ES_SSAO);
|
||||
m_material.setTexture(0, irr_driver->getRTT(RTT_NORMAL));
|
||||
m_material.setTexture(1, irr_driver->getRTT(tick ? RTT_SSAO1 : RTT_SSAO2));
|
||||
m_material.setTexture(1, irr_driver->getRTT(RTT_DEPTH));
|
||||
|
||||
drv->setRenderTarget(irr_driver->getRTT(curssao), true, false,
|
||||
SColor(255, 255, 255, 255));
|
||||
|
@ -695,6 +695,9 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
|
||||
FogProvider * const fogcb = (FogProvider *) irr_driver->
|
||||
getCallback(ES_FOG);
|
||||
fogcb->updateIPVMatrix();
|
||||
SSAOProvider * const ssaocb = (SSAOProvider *) irr_driver->
|
||||
getCallback(ES_SSAO);
|
||||
ssaocb->updateIPVMatrix();
|
||||
|
||||
|
||||
const u32 lightcount = m_lights.size();
|
||||
|
@ -67,7 +67,7 @@ RTT::RTT()
|
||||
rtts[RTT_TMP3] = drv->addRenderTargetTexture(res, "rtt.tmp3", ECF_A8R8G8B8, stencil);
|
||||
rtts[RTT_TMP4] = drv->addRenderTargetTexture(res, "rtt.tmp4", ECF_A8R8G8B8, stencil);
|
||||
rtts[RTT_DEPTH] = drv->addRenderTargetTexture(res, "rtt.depth", ECF_A8R8G8B8, stencil);
|
||||
rtts[RTT_NORMAL] = drv->addRenderTargetTexture(res, "rtt.normal", ECF_A8R8G8B8, stencil);
|
||||
rtts[RTT_NORMAL] = drv->addRenderTargetTexture(res, "rtt.normal", ECF_A32B32G32R32F, stencil);
|
||||
rtts[RTT_COLOR] = drv->addRenderTargetTexture(res, "rtt.color", ECF_A8R8G8B8, stencil);
|
||||
|
||||
rtts[RTT_HALF1] = drv->addRenderTargetTexture(half, "rtt.half1", ECF_A8R8G8B8, stencil);
|
||||
|
Loading…
Reference in New Issue
Block a user