Use texture instead of image in SSAO.

This commit is contained in:
Vincent Lejeune 2014-09-16 01:26:04 +02:00
parent 546cbabf3e
commit b769e46a00
6 changed files with 80 additions and 45 deletions

View File

@ -1,7 +1,8 @@
// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html // From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html
uniform layout(size1x16) restrict readonly image2D source; uniform sampler2D source;
uniform layout(size1x32) restrict readonly image2D depth; uniform sampler2D depth;
uniform vec2 pixel;
uniform layout(size1x16) volatile restrict writeonly image2D dest; uniform layout(size1x16) volatile restrict writeonly image2D dest;
uniform float sigma = 5.; uniform float sigma = 5.;
@ -13,13 +14,17 @@ shared float local_depth[8 + 2 * 8][8];
void main() void main()
{ {
int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y); int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
ivec2 uv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y); ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
local_src[x][y] = imageLoad(source, ivec2(uv) - ivec2(8, 0)).x; vec2 uv_m = (iuv - ivec2(8, 0)) * pixel;
local_depth[x][y] = imageLoad(depth, ivec2(uv) - ivec2(8, 0)).x; vec2 uv = iuv * pixel;
local_src[x + 8][y] = imageLoad(source, ivec2(uv)).x; vec2 uv_p = (iuv + ivec2(8, 0)) * pixel;
local_depth[x + 8][y] = imageLoad(depth, ivec2(uv)).x;
local_src[x + 16][y] = imageLoad(source, ivec2(uv) + ivec2(8, 0)).x; local_src[x][y] = texture(source, uv_m).x;
local_depth[x + 16][y] = imageLoad(depth, ivec2(uv) + ivec2(8, 0)).x; local_depth[x][y] = texture(depth, uv_m).x;
local_src[x + 8][y] = texture(source, uv).x;
local_depth[x + 8][y] = texture(depth, uv).x;
local_src[x + 16][y] = texture(source, uv_p).x;
local_depth[x + 16][y] = texture(depth, uv_p).x;
barrier(); barrier();
@ -42,6 +47,6 @@ void main()
g0 *= g1; g0 *= g1;
g1 *= g2; g1 *= g2;
} }
imageStore(dest, ivec2(uv), vec4(sum / total_weight)); imageStore(dest, iuv, vec4(sum / total_weight));
} }

View File

@ -1,7 +1,8 @@
// From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html // From http://http.developer.nvidia.com/GPUGems3/gpugems3_ch40.html
uniform layout(size1x16) restrict readonly image2D source; uniform sampler2D source;
uniform layout(size1x32) restrict readonly image2D depth; uniform sampler2D depth;
uniform vec2 pixel;
uniform layout(size1x16) volatile restrict writeonly image2D dest; uniform layout(size1x16) volatile restrict writeonly image2D dest;
uniform float sigma = 5.; uniform float sigma = 5.;
@ -13,13 +14,17 @@ shared float local_depth[8][8 + 2 * 8];
void main() void main()
{ {
int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y); int x = int(gl_LocalInvocationID.x), y = int(gl_LocalInvocationID.y);
ivec2 uv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y); ivec2 iuv = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
local_src[x][y] = imageLoad(source, ivec2(uv) - ivec2(0, 8)).x; vec2 uv_m = (iuv - ivec2(0, 8)) * pixel;
local_depth[x][y] = imageLoad(depth, ivec2(uv) - ivec2(0, 8)).x; vec2 uv = iuv * pixel;
local_src[x][y + 8] = imageLoad(source, ivec2(uv)).x; vec2 uv_p = (iuv + ivec2(0, 8)) * pixel;
local_depth[x][y + 8] = imageLoad(depth, ivec2(uv)).x;
local_src[x][y + 16] = imageLoad(source, ivec2(uv) + ivec2(0, 8)).x; local_src[x][y] = texture(source, uv_m).x;
local_depth[x][y + 16] = imageLoad(depth, ivec2(uv) + ivec2(0, 8)).x; local_depth[x][y] = texture(depth, uv_m).x;
local_src[x][y + 8] = texture(source, uv).x;
local_depth[x][y + 8] = texture(depth, uv).x;
local_src[x][y + 16] = texture(source, uv_p).x;
local_depth[x][y + 16] = texture(depth, uv_p).x;
barrier(); barrier();
@ -43,6 +48,6 @@ void main()
g1 *= g2; g1 *= g2;
} }
imageStore(dest, ivec2(uv), vec4(sum / total_weight)); imageStore(dest, iuv, vec4(sum / total_weight));
} }

View File

@ -348,42 +348,32 @@ void PostProcessing::renderGaussian17TapBlur(FrameBuffer &in_fbo, FrameBuffer &a
else else
{ {
glUseProgram(FullScreenShader::ComputeGaussian17TapHShader::getInstance()->Program); glUseProgram(FullScreenShader::ComputeGaussian17TapHShader::getInstance()->Program);
glBindSampler(FullScreenShader::ComputeGaussian17TapHShader::getInstance()->TU_source, 0);
glBindSampler(FullScreenShader::ComputeGaussian17TapHShader::getInstance()->TU_depth, 0);
glBindSampler(FullScreenShader::ComputeGaussian17TapHShader::getInstance()->TU_dest, 0); glBindSampler(FullScreenShader::ComputeGaussian17TapHShader::getInstance()->TU_dest, 0);
glBindImageTexture(FullScreenShader::ComputeGaussian17TapHShader::getInstance()->TU_source, in_fbo.getRTT()[0], 0, false, 0, GL_READ_ONLY, GL_R16F); FullScreenShader::ComputeGaussian17TapHShader::getInstance()->SetTextureUnits({ in_fbo.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0] });
glBindImageTexture(FullScreenShader::ComputeGaussian17TapHShader::getInstance()->TU_depth, irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0], 1, false, 0, GL_READ_ONLY, GL_R32F);
glBindImageTexture(FullScreenShader::ComputeGaussian17TapHShader::getInstance()->TU_dest, auxiliary.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_R16F); glBindImageTexture(FullScreenShader::ComputeGaussian17TapHShader::getInstance()->TU_dest, auxiliary.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_R16F);
FullScreenShader::ComputeGaussian17TapHShader::getInstance()->setUniforms(); FullScreenShader::ComputeGaussian17TapHShader::getInstance()->setUniforms(core::vector2df(inv_width, inv_height));
glDispatchCompute(in_fbo.getWidth() / 8, in_fbo.getHeight() / 8, 1); glDispatchCompute(in_fbo.getWidth() / 8, in_fbo.getHeight() / 8, 1);
} }
} }
if (irr_driver->hasARBComputeShaders()) if (irr_driver->hasARBComputeShaders())
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
{ {
#ifdef WIN32
if (!irr_driver->hasARBComputeShaders()) if (!irr_driver->hasARBComputeShaders())
#endif
{ {
in_fbo.Bind(); in_fbo.Bind();
FullScreenShader::Gaussian17TapVShader::getInstance()->SetTextureUnits(createVector<GLuint>(auxiliary.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0])); FullScreenShader::Gaussian17TapVShader::getInstance()->SetTextureUnits(createVector<GLuint>(auxiliary.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0]));
DrawFullScreenEffect<FullScreenShader::Gaussian17TapVShader>(core::vector2df(inv_width, inv_height)); DrawFullScreenEffect<FullScreenShader::Gaussian17TapVShader>(core::vector2df(inv_width, inv_height));
} }
#ifdef WIN32
else else
{ {
glUseProgram(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->Program); glUseProgram(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->Program);
glBindSampler(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->TU_source, 0);
glBindSampler(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->TU_depth, 0);
glBindSampler(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->TU_dest, 0); glBindSampler(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->TU_dest, 0);
glBindImageTexture(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->TU_source, auxiliary.getRTT()[0], 0, false, 0, GL_READ_ONLY, GL_R16F); FullScreenShader::ComputeGaussian17TapVShader::getInstance()->SetTextureUnits({ auxiliary.getRTT()[0], irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0] });
glBindImageTexture(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->TU_depth, irr_driver->getFBO(FBO_LINEAR_DEPTH).getRTT()[0], 1, false, 0, GL_READ_ONLY, GL_R32F);
glBindImageTexture(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->TU_dest, in_fbo.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_R16F); glBindImageTexture(FullScreenShader::ComputeGaussian17TapVShader::getInstance()->TU_dest, in_fbo.getRTT()[0], 0, false, 0, GL_WRITE_ONLY, GL_R16F);
FullScreenShader::ComputeGaussian17TapVShader::getInstance()->setUniforms(); FullScreenShader::ComputeGaussian17TapVShader::getInstance()->setUniforms(core::vector2df(inv_width, inv_height));
glDispatchCompute(in_fbo.getWidth() / 8, in_fbo.getHeight() / 8, 1); glDispatchCompute(in_fbo.getWidth() / 8, in_fbo.getHeight() / 8, 1);
} }
#endif
} }
if (irr_driver->hasARBComputeShaders()) if (irr_driver->hasARBComputeShaders())
glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);

View File

@ -1579,11 +1579,10 @@ namespace FullScreenShader
{ {
Program = LoadProgram(OBJECT, Program = LoadProgram(OBJECT,
GL_COMPUTE_SHADER, file_manager->getAsset("shaders/bilateralH.comp").c_str()); GL_COMPUTE_SHADER, file_manager->getAsset("shaders/bilateralH.comp").c_str());
TU_source = 0;
TU_depth = 1;
TU_dest = 2; TU_dest = 2;
AssignUniforms(); AssignUniforms("pixel");
AssignTextureUnit(Program, TexUnit(TU_source, "source"), TexUnit(TU_depth, "depth"), TexUnit(TU_dest, "dest")); AssignSamplerNames(Program, 0, "source", 1, "depth");
AssignTextureUnit(Program, TexUnit(TU_dest, "dest"));
} }
Gaussian6HBlurShader::Gaussian6HBlurShader() Gaussian6HBlurShader::Gaussian6HBlurShader()
@ -1620,10 +1619,10 @@ namespace FullScreenShader
{ {
Program = LoadProgram(OBJECT, Program = LoadProgram(OBJECT,
GL_COMPUTE_SHADER, file_manager->getAsset("shaders/bilateralV.comp").c_str()); GL_COMPUTE_SHADER, file_manager->getAsset("shaders/bilateralV.comp").c_str());
TU_source = 0;
TU_depth = 1;
TU_dest = 2; TU_dest = 2;
AssignTextureUnit(Program, TexUnit(TU_source, "source"), TexUnit(TU_depth, "depth"), TexUnit(TU_dest, "dest")); AssignUniforms("pixel");
AssignSamplerNames(Program, 0, "source", 1, "depth");
AssignTextureUnit(Program, TexUnit(TU_dest, "dest"));
} }
Gaussian6VBlurShader::Gaussian6VBlurShader() Gaussian6VBlurShader::Gaussian6VBlurShader()

View File

@ -451,10 +451,10 @@ public:
Gaussian17TapHShader(); Gaussian17TapHShader();
}; };
class ComputeGaussian17TapHShader : public ShaderHelperSingleton<ComputeGaussian17TapHShader> class ComputeGaussian17TapHShader : public ShaderHelperSingleton<ComputeGaussian17TapHShader, core::vector2df>, public TextureRead<Neared_Clamped_Filtered, Neared_Clamped_Filtered>
{ {
public: public:
GLuint TU_source, TU_dest, TU_depth; GLuint TU_dest;
ComputeGaussian17TapHShader(); ComputeGaussian17TapHShader();
}; };
@ -476,10 +476,10 @@ public:
Gaussian17TapVShader(); Gaussian17TapVShader();
}; };
class ComputeGaussian17TapVShader : public ShaderHelperSingleton<ComputeGaussian17TapVShader> class ComputeGaussian17TapVShader : public ShaderHelperSingleton<ComputeGaussian17TapVShader, core::vector2df>, public TextureRead<Neared_Clamped_Filtered, Neared_Clamped_Filtered>
{ {
public: public:
GLuint TU_source, TU_depth, TU_dest; GLuint TU_dest;
ComputeGaussian17TapVShader(); ComputeGaussian17TapVShader();
}; };

View File

@ -142,6 +142,7 @@ enum SamplerType {
Semi_trilinear, Semi_trilinear,
Bilinear_Filtered, Bilinear_Filtered,
Bilinear_Clamped_Filtered, Bilinear_Clamped_Filtered,
Neared_Clamped_Filtered,
Nearest_Filtered, Nearest_Filtered,
Shadow_Sampler, Shadow_Sampler,
Volume_Linear_Filtered, Volume_Linear_Filtered,
@ -195,6 +196,41 @@ struct BindTexture<Nearest_Filtered, tp...>
} }
}; };
template<SamplerType...tp>
struct CreateSamplers<Neared_Clamped_Filtered, tp...>
{
static void exec(std::vector<unsigned> &v, std::vector<GLenum> &e)
{
unsigned id;
glGenSamplers(1, &id);
glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
v.push_back(createNearestSampler());
e.push_back(GL_TEXTURE_2D);
CreateSamplers<tp...>::exec(v, e);
}
};
template<SamplerType...tp>
struct BindTexture<Neared_Clamped_Filtered, tp...>
{
static void exec(const std::vector<unsigned> &TU, const std::vector<unsigned> &TexId, unsigned N)
{
glActiveTexture(GL_TEXTURE0 + TU[N]);
glBindTexture(GL_TEXTURE_2D, TexId[N]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.);
BindTexture<tp...>::exec(TU, TexId, N + 1);
}
};
GLuint createBilinearSampler(); GLuint createBilinearSampler();
template<SamplerType...tp> template<SamplerType...tp>