Preparing for split rendering of HBAO directions

This commit is contained in:
Olivier Prat 2018-09-18 18:33:28 +02:00
parent 3d096d0644
commit 03814e7653
6 changed files with 99 additions and 8 deletions

View file

@ -260,6 +260,23 @@ void AmbientOcclusionEffect::configure(const Config& config) {
auto& current = _aoParametersBuffer.edit()._sampleInfo;
current.x = config.numSamples;
current.y = 1.0f / config.numSamples;
// Regenerate halton sequence
const int B = config.numSamples + 1;
const float invB = 1.0f / (float)B;
for (int i = 0; i < _randomSamples.size(); i++) {
int index = i+1; // Indices start at 1, not 0
float f = 1.0f;
float r = 0.0f;
while (index > 0) {
f = f * invB;
r = r + f * (float)(index % B);
index = index / B;
}
_randomSamples[i] = r;
}
}
if (config.fetchMipsEnabled != _aoParametersBuffer->isFetchMipsEnabled()) {
@ -280,6 +297,13 @@ void AmbientOcclusionEffect::configure(const Config& config) {
auto& current = _aoParametersBuffer.edit()._resolutionInfo;
current.x = (float) config.resolutionLevel;
shouldUpdateBlurs = true;
_aoFrameParametersBuffer[0].edit()._pixelOffsets = { 0, 0, 0, 0 };
#if SSAO_USE_QUAD_SPLIT
_aoFrameParametersBuffer[1].edit()._pixelOffsets = { 1, 0, 0, 0 };
_aoFrameParametersBuffer[2].edit()._pixelOffsets = { 1, 1, 0, 0 };
_aoFrameParametersBuffer[3].edit()._pixelOffsets = { 0, 1, 0, 0 };
#endif
}
if (config.blurRadius != _aoParametersBuffer->getBlurRadius()) {
@ -425,21 +449,29 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
auto mipCreationPipeline = getMipCreationPipeline();
#endif
// Update sample rotation
const int SSAO_RANDOM_SAMPLE_COUNT = int(_randomSamples.size() / SSAO_SPLIT_COUNT);
for (int splitId=0 ; splitId < SSAO_SPLIT_COUNT ; splitId++) {
auto& sample = _aoFrameParametersBuffer[splitId].edit();
sample._angleInfo.x = _randomSamples[_frameId + SSAO_RANDOM_SAMPLE_COUNT * splitId] * M_PI;
}
_frameId = (_frameId + 1) % SSAO_RANDOM_SAMPLE_COUNT;
gpu::doInBatch("AmbientOcclusionEffect::run", args->_context, [=](gpu::Batch& batch) {
PROFILE_RANGE_BATCH(batch, "AmbientOcclusion");
batch.enableStereo(false);
_gpuTimer->begin(batch);
batch.setViewportTransform(occlusionViewport);
batch.setProjectionTransform(glm::mat4());
batch.resetViewTransform();
Transform model;
batch.setProjectionTransform(glm::mat4());
batch.setModelTransform(model);
// We need this with the mips levels
batch.pushProfileRange("Depth mip creation");
batch.setModelTransform(model);
#if SSAO_USE_HORIZON_BASED
batch.setPipeline(mipCreationPipeline);
batch.generateTextureMipsWithPipeline(occlusionDepthTexture);
@ -450,13 +482,42 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
// Occlusion pass
batch.pushProfileRange("Occlusion");
batch.setUniformBuffer(render_utils::slot::buffer::DeferredFrameTransform, frameTransform->getFrameTransformBuffer());
batch.setUniformBuffer(render_utils::slot::buffer::SsaoParams, _aoParametersBuffer);
batch.setUniformBuffer(render_utils::slot::buffer::SsaoParams, _aoParametersBuffer);
batch.setFramebuffer(occlusionFBO);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(1.0f));
batch.setPipeline(occlusionPipeline);
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, occlusionDepthTexture);
#if SSAO_USE_QUAD_SPLIT
{
auto splitViewport = occlusionViewport >> SSAO_USE_QUAD_SPLIT;
batch.setViewportTransform(splitViewport);
batch.setUniformBuffer(render_utils::slot::buffer::SsaoFrameParams, _aoFrameParametersBuffer[0]);
batch.draw(gpu::TRIANGLE_STRIP, 4);
splitViewport.x += splitViewport.z;
batch.setViewportTransform(splitViewport);
batch.setUniformBuffer(render_utils::slot::buffer::SsaoFrameParams, _aoFrameParametersBuffer[1]);
batch.draw(gpu::TRIANGLE_STRIP, 4);
splitViewport.y += splitViewport.w;
batch.setViewportTransform(splitViewport);
batch.setUniformBuffer(render_utils::slot::buffer::SsaoFrameParams, _aoFrameParametersBuffer[2]);
batch.draw(gpu::TRIANGLE_STRIP, 4);
splitViewport.x = 0;
batch.setViewportTransform(splitViewport);
batch.setUniformBuffer(render_utils::slot::buffer::SsaoFrameParams, _aoFrameParametersBuffer[3]);
batch.draw(gpu::TRIANGLE_STRIP, 4);
}
#else
batch.setUniformBuffer(render_utils::slot::buffer::SsaoFrameParams, _aoFrameParametersBuffer[0]);
batch.draw(gpu::TRIANGLE_STRIP, 4);
#endif
batch.popProfileRange();
{
@ -552,7 +613,6 @@ void DebugAmbientOcclusion::run(const render::RenderContextPointer& renderContex
linearDepthTexture = linearDepthFramebuffer->getHalfLinearDepthTexture();
occlusionViewport = occlusionViewport >> ambientOcclusionUniforms->getResolutionLevel();
}
auto framebufferSize = glm::ivec2(linearDepthTexture->getDimensions());

View file

@ -153,11 +153,13 @@ private:
};
using BlurParametersBuffer = gpu::StructBuffer<BlurParameters>;
using FrameParametersBuffer = gpu::StructBuffer< AmbientOcclusionFrameParams>;
void updateGaussianDistribution();
void updateBlurParameters();
AOParametersBuffer _aoParametersBuffer;
FrameParametersBuffer _aoFrameParametersBuffer[SSAO_SPLIT_COUNT];
BlurParametersBuffer _vblurParametersBuffer;
BlurParametersBuffer _hblurParametersBuffer;
@ -172,6 +174,8 @@ private:
static gpu::PipelinePointer _mipCreationPipeline;
AmbientOcclusionFramebufferPointer _framebuffer;
std::array<float, 16 * SSAO_SPLIT_COUNT> _randomSamples;
int _frameId{ 0 };
gpu::RangeTimerPointer _gpuTimer;

View file

@ -87,6 +87,7 @@
#define RENDER_UTILS_BUFFER_SSAO_PARAMS 2
#define RENDER_UTILS_BUFFER_SSAO_DEBUG_PARAMS 3
#define RENDER_UTILS_BUFFER_SSAO_BLUR_PARAMS 4
#define RENDER_UTILS_BUFFER_SSAO_FRAME_PARAMS 5
#define RENDER_UTILS_TEXTURE_SSAO_DEPTH 1
#define RENDER_UTILS_TEXTURE_SSAO_OCCLUSION 0
@ -153,6 +154,7 @@ enum Buffer {
LightClusterContent = RENDER_UTILS_BUFFER_LIGHT_CLUSTER_CONTENT,
SsscParams = RENDER_UTILS_BUFFER_SSSC_PARAMS,
SsaoParams = RENDER_UTILS_BUFFER_SSAO_PARAMS,
SsaoFrameParams = RENDER_UTILS_BUFFER_SSAO_FRAME_PARAMS,
SsaoDebugParams = RENDER_UTILS_BUFFER_SSAO_DEBUG_PARAMS,
SsaoBlurParams = RENDER_UTILS_BUFFER_SSAO_BLUR_PARAMS,
LightIndex = RENDER_UTILS_BUFFER_LIGHT_INDEX,

View file

@ -40,9 +40,11 @@ layout(binding=RENDER_UTILS_BUFFER_SSAO_PARAMS) uniform ambientOcclusionParamsBu
AmbientOcclusionParams params;
};
layout(binding=RENDER_UTILS_BUFFER_SSAO_FRAME_PARAMS) uniform ambientOcclusionFrameParamsBuffer {
AmbientOcclusionFrameParams frameParams;
};
float getPerspectiveScale() {
return (params._resolutionInfo.z);
}
int getResolutionLevel() {
@ -136,8 +138,16 @@ float getAngleDitheringWorldPos(in vec3 pixelWorldPos) {
}
float getAngleDithering(in ivec2 pixelPos) {
#if SSAO_USE_QUAD_SPLIT
return isDitheringEnabled() * frameParams._angleInfo.x;
#else
// Hash function used in the AlchemyAO paper
return isDitheringEnabled() * float((3 * pixelPos.x ^ pixelPos.y + pixelPos.x * pixelPos.y) * 10);
return isDitheringEnabled() * float((3 * pixelPos.x ^ pixelPos.y + pixelPos.x * pixelPos.y) * 10);
#endif
}
ivec2 getPixelOffset() {
return frameParams._pixelOffsets.xy;
}
float evalDiskRadius(float Zeye, vec2 sideImageSize) {

View file

@ -25,10 +25,11 @@ layout(location=0) out vec4 outFragColor;
void main(void) {
vec2 sideImageSize = getSideImageSize(getResolutionLevel());
ivec2 splitImageSize = ivec2(getWidthHeight(getResolutionLevel() + SSAO_USE_QUAD_SPLIT));
// Pixel being shaded
vec2 fragCoord = gl_FragCoord.xy;
ivec2 fragPixelPos = ivec2(fragCoord.xy);
ivec2 fragPixelPos = ((ivec2(fragCoord.xy) - getPixelOffset()*splitImageSize) << SSAO_USE_QUAD_SPLIT) + getPixelOffset();
// Stereo side info
ivec4 side = getStereoSideInfo(fragPixelPos.x, getResolutionLevel());

View file

@ -15,13 +15,22 @@
#define RENDER_UTILS_SSAO_SHARED_H
#define SSAO_USE_HORIZON_BASED 1
#define SSAO_USE_QUAD_SPLIT 1
#define SSAO_BLUR_GAUSSIAN_COEFS_COUNT 16
// glsl / C++ compatible source as interface for Shadows
#if SSAO_USE_QUAD_SPLIT
#define SSAO_SPLIT_COUNT 4
#else
#define SSAO_SPLIT_COUNT 1
#endif
// glsl / C++ compatible source as interface for ambient occlusion
#ifdef __cplusplus
# define SSAO_VEC4 glm::vec4
# define SSAO_IVEC4 glm::ivec4
#else
# define SSAO_VEC4 vec4
# define SSAO_IVEC4 ivec4
#endif
struct AmbientOcclusionParams {
@ -33,6 +42,11 @@ struct AmbientOcclusionParams {
float _gaussianCoefs[SSAO_BLUR_GAUSSIAN_COEFS_COUNT];
};
struct AmbientOcclusionFrameParams {
SSAO_VEC4 _angleInfo;
SSAO_IVEC4 _pixelOffsets;
};
#endif // RENDER_UTILS_SHADER_CONSTANTS_H
// <@if 1@>