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:
auria 2013-12-20 00:11:57 +00:00
parent 73f9779324
commit c6fd5cde1c
6 changed files with 70 additions and 53 deletions

View File

@ -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
}

View File

@ -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;
}

View File

@ -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);
}
};
//

View File

@ -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));

View File

@ -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();

View File

@ -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);