mirror of
https://github.com/overte-org/overte.git
synced 2025-04-24 03:33:35 +02:00
Preparing for split rendering of HBAO directions
This commit is contained in:
parent
3d096d0644
commit
03814e7653
6 changed files with 99 additions and 8 deletions
|
@ -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());
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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@>
|
||||
|
|
Loading…
Reference in a new issue