DS buffer is not linear and cant be mipmapped

Use the method provided by SAO paper (ie convert to linear and then
mipmap)
This commit is contained in:
Vincent Lejeune 2014-05-13 19:40:30 +02:00
parent 20959f970a
commit 59484ea09a
7 changed files with 84 additions and 25 deletions

View File

@ -0,0 +1,13 @@
uniform sampler2D tex;
uniform float zn;
uniform float zf;
in vec2 uv;
out float Depth;
void main()
{
float d = texture(tex, uv).x;
float c0 = zn * zf, c1 = zn - zf, c2 = zf;
Depth = c0 / (d * c1 + c2);
}

View File

@ -1,9 +1,7 @@
// From paper http://graphics.cs.williams.edu/papers/AlchemyHPG11/
// and improvements here http://graphics.cs.williams.edu/papers/SAOHPG12/
uniform sampler2D ntex;
uniform sampler2D dtex;
uniform sampler2D noise_texture;
uniform vec4 samplePoints[16];
uniform vec2 screen;
@ -37,24 +35,25 @@ const float k = 1.;
const float invSamples = 1. / SAMPLES;
vec3 DecodeNormal(vec2 n);
vec4 getPosFromUVDepth(vec3 uvDepth, mat4 InverseProjectionMatrix);
vec3 getXcYcZc(int x, int y, float zC)
{
// We use perspective symetric projection matrix hence P(0,2) = P(1, 2) = 0
float xC= (1. - 2 * (float(x) + 0.5) / screen.x) * zC / ProjectionMatrix[0][0];
float yC= (1. + 2 * (float(y) + 0.5) / screen.y) * zC / ProjectionMatrix[1][1];
return vec3(xC, yC, zC);
}
void main(void)
{
vec4 cur = texture(ntex, uv);
float curdepth = texture(dtex, uv).x;
vec4 FragPos = getPosFromUVDepth(vec3(uv, curdepth), InverseProjectionMatrix);
float lineardepth = textureLod(dtex, uv, 0.).x;
int x = int(gl_FragCoord.x), y = int(gl_FragCoord.y);
vec3 FragPos = getXcYcZc(x, y, lineardepth);
// get the normal of current fragment
vec3 ddx = dFdx(FragPos.xyz);
vec3 ddy = dFdy(FragPos.xyz);
vec3 norm = normalize(cross(ddy, ddx));
// Workaround for nvidia and skyboxes
float len = dot(vec3(1.0), abs(cur.xyz));
if (len < 0.2) discard;
vec3 ddx = dFdx(FragPos);
vec3 ddy = dFdy(FragPos);
vec3 norm = -normalize(cross(ddy, ddx));
int x = int(gl_FragCoord.x), y = int(gl_FragCoord.y);
float r = radius / FragPos.z;
float phi = 30. * (x ^ y) + 10. * x * y;
float bl = 0.0;
@ -63,20 +62,18 @@ void main(void)
float alpha = (i + .5) * invSamples;
float theta = 2. * 3.14 * tau * alpha + phi;
float h = r * alpha;
vec2 occluder_uv = h * vec2(cos(theta), sin(theta)) * screen;
occluder_uv += gl_FragCoord.xy;
vec2 offset = h * vec2(cos(theta), sin(theta)) * screen;
float m = round(log2(h)) + 7;
ivec2 ioccluder_uv = ivec2(occluder_uv);
occluder_uv = (ioccluder_uv >> int(m)) << int(m);
occluder_uv /= screen;
float m = round(log2(h) + 7);
ivec2 ioccluder_uv = ivec2(x, y) + ivec2(offset);
ioccluder_uv = (ioccluder_uv << int(m)) >> int(m);
if (occluder_uv.x < 0. || occluder_uv.x > 1. || occluder_uv.y < 0. || occluder_uv.y > 1.) continue;
if (ioccluder_uv.x < 0 || ioccluder_uv.x > screen.x || ioccluder_uv.y < 0 || ioccluder_uv.y > screen.y) continue;
float occluderFragmentDepth = textureLod(dtex, occluder_uv, m).x;
vec4 OccluderPos = getPosFromUVDepth(vec3(occluder_uv, occluderFragmentDepth), InverseProjectionMatrix);
float LinearoccluderFragmentDepth = textureLod(dtex, vec2(ioccluder_uv) / screen, m).x;
vec3 OccluderPos = getXcYcZc(ioccluder_uv.x, ioccluder_uv.y, LinearoccluderFragmentDepth);
vec3 vi = (OccluderPos - FragPos).xyz;
vec3 vi = OccluderPos - FragPos;
bl += max(0, dot(vi, norm) - FragPos.z * beta) / (dot(vi, vi) + epsilon);
}

View File

@ -451,12 +451,22 @@ void PostProcessing::renderSSAO()
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
// Generate linear depth buffer
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_LINEAR_DEPTH));
glUseProgram(FullScreenShader::LinearizeDepthShader::Program);
glBindVertexArray(FullScreenShader::LinearizeDepthShader::vao);
setTexture(0, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR);
FullScreenShader::LinearizeDepthShader::setUniforms(irr_driver->getSceneManager()->getActiveCamera()->getNearValue(), irr_driver->getSceneManager()->getActiveCamera()->getFarValue(), 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindFramebuffer(GL_FRAMEBUFFER, irr_driver->getFBO(FBO_SSAO));
if (!noise_tex)
noise_tex = irr_driver->getTexture(file_manager->getAsset("textures/noise.png").c_str());
glUseProgram(FullScreenShader::SSAOShader::Program);
glBindVertexArray(FullScreenShader::SSAOShader::vao);
setTexture(0, irr_driver->getDepthStencilTexture(), GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST);
setTexture(0, irr_driver->getRenderTargetTexture(RTT_LINEAR_DEPTH), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
setTexture(1, getTextureGLuint(noise_tex), GL_LINEAR, GL_LINEAR);

View File

@ -83,6 +83,7 @@ RTT::RTT()
RenderTargetTextures[RTT_TMP2] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_TMP3] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_TMP4] = generateRTT(res, GL_R16F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_LINEAR_DEPTH] = generateRTT(res, GL_R32F, GL_RED, GL_FLOAT);
RenderTargetTextures[RTT_NORMAL_AND_DEPTH] = generateRTT(res, GL_RGBA16F, GL_RGBA, GL_FLOAT);
RenderTargetTextures[RTT_COLOR] = generateRTT(res, GL_RGBA16F, GL_BGRA, GL_FLOAT);
RenderTargetTextures[RTT_MLAA_COLORS] = generateRTT(res, GL_SRGB, GL_BGR, GL_UNSIGNED_BYTE);
@ -118,6 +119,7 @@ RTT::RTT()
FrameBuffers[FBO_TMP1_WITH_DS] = generateFBO(RenderTargetTextures[RTT_TMP1], DepthStencilTexture);
FrameBuffers[FBO_TMP2_WITH_DS] = generateFBO(RenderTargetTextures[RTT_TMP2], DepthStencilTexture);
FrameBuffers[FBO_TMP4] = generateFBO(RenderTargetTextures[RTT_TMP4], DepthStencilTexture);
FrameBuffers[FBO_LINEAR_DEPTH] = generateFBO(RenderTargetTextures[RTT_LINEAR_DEPTH]);
FrameBuffers[FBO_DISPLACE] = generateFBO(RenderTargetTextures[RTT_DISPLACE], DepthStencilTexture);
FrameBuffers[FBO_HALF1] = generateFBO(RenderTargetTextures[RTT_HALF1]);
FrameBuffers[FBO_HALF2] = generateFBO(RenderTargetTextures[RTT_HALF2]);

View File

@ -31,6 +31,7 @@ enum TypeRTT
RTT_TMP2,
RTT_TMP3,
RTT_TMP4,
RTT_LINEAR_DEPTH,
RTT_NORMAL_AND_DEPTH,
RTT_COLOR,
RTT_LOG_LUMINANCE,
@ -87,6 +88,7 @@ enum TypeFBO
FBO_TMP1_WITH_DS,
FBO_TMP2_WITH_DS,
FBO_TMP4,
FBO_LINEAR_DEPTH,
FBO_HALF1,
FBO_HALF2,
FBO_QUARTER1,

View File

@ -311,6 +311,7 @@ void Shaders::loadShaders()
FullScreenShader::PenumbraVShader::init();
FullScreenShader::GlowShader::init();
FullScreenShader::PassThroughShader::init();
FullScreenShader::LinearizeDepthShader::init();
FullScreenShader::SSAOShader::init();
FullScreenShader::SunLightShader::init();
FullScreenShader::DiffuseEnvMapShader::init();
@ -2510,6 +2511,29 @@ namespace FullScreenShader
vao = createVAO(Program);
}
GLuint LinearizeDepthShader::Program;
GLuint LinearizeDepthShader::uniform_zn;
GLuint LinearizeDepthShader::uniform_zf;
GLuint LinearizeDepthShader::uniform_texture;
GLuint LinearizeDepthShader::vao;
void LinearizeDepthShader::init()
{
Program = LoadProgram(
GL_VERTEX_SHADER, file_manager->getAsset("shaders/screenquad.vert").c_str(),
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/linearizedepth.frag").c_str());
uniform_texture = glGetUniformLocation(Program, "texture");
uniform_zf = glGetUniformLocation(Program, "zf");
uniform_zn = glGetUniformLocation(Program, "zn");
vao = createVAO(Program);
}
void LinearizeDepthShader::setUniforms(float zn, float zf, unsigned TU_tex)
{
glUniform1f(uniform_zn, zn);
glUniform1f(uniform_zf, zf);
glUniform1i(uniform_texture, TU_tex);
}
GLuint GlowShader::Program;
GLuint GlowShader::uniform_tex;
GLuint GlowShader::vao;

View File

@ -713,6 +713,17 @@ public:
static void init();
};
class LinearizeDepthShader
{
public:
static GLuint Program;
static GLuint uniform_zn, uniform_zf, uniform_texture;
static GLuint vao;
static void init();
static void setUniforms(float zn, float zf, unsigned TU_tex);
};
class GlowShader
{
public: