mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 12:28:02 +02:00
Quarter resolution with split rendering
This commit is contained in:
parent
3493d40fd7
commit
8a11d18f0d
11 changed files with 194 additions and 91 deletions
|
@ -35,6 +35,7 @@ gpu::PipelinePointer AmbientOcclusionEffect::_hBlurPipeline;
|
||||||
gpu::PipelinePointer AmbientOcclusionEffect::_vBlurPipeline;
|
gpu::PipelinePointer AmbientOcclusionEffect::_vBlurPipeline;
|
||||||
gpu::PipelinePointer AmbientOcclusionEffect::_mipCreationPipeline;
|
gpu::PipelinePointer AmbientOcclusionEffect::_mipCreationPipeline;
|
||||||
gpu::PipelinePointer AmbientOcclusionEffect::_gatherPipeline;
|
gpu::PipelinePointer AmbientOcclusionEffect::_gatherPipeline;
|
||||||
|
gpu::PipelinePointer AmbientOcclusionEffect::_buildNormalsPipeline;
|
||||||
|
|
||||||
AmbientOcclusionFramebuffer::AmbientOcclusionFramebuffer() {
|
AmbientOcclusionFramebuffer::AmbientOcclusionFramebuffer() {
|
||||||
}
|
}
|
||||||
|
@ -66,6 +67,8 @@ void AmbientOcclusionFramebuffer::clear() {
|
||||||
_occlusionTexture.reset();
|
_occlusionTexture.reset();
|
||||||
_occlusionBlurredFramebuffer.reset();
|
_occlusionBlurredFramebuffer.reset();
|
||||||
_occlusionBlurredTexture.reset();
|
_occlusionBlurredTexture.reset();
|
||||||
|
_normalFramebuffer.reset();
|
||||||
|
_normalTexture.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::TexturePointer AmbientOcclusionFramebuffer::getLinearDepthTexture() {
|
gpu::TexturePointer AmbientOcclusionFramebuffer::getLinearDepthTexture() {
|
||||||
|
@ -73,18 +76,21 @@ gpu::TexturePointer AmbientOcclusionFramebuffer::getLinearDepthTexture() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmbientOcclusionFramebuffer::allocate() {
|
void AmbientOcclusionFramebuffer::allocate() {
|
||||||
|
|
||||||
auto width = _frameSize.x;
|
auto width = _frameSize.x;
|
||||||
auto height = _frameSize.y;
|
auto height = _frameSize.y;
|
||||||
auto format = gpu::Element::COLOR_R_8;
|
auto format = gpu::Element::COLOR_R_8;
|
||||||
|
|
||||||
_occlusionTexture = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT, gpu::Sampler::WRAP_CLAMP));
|
_occlusionTexture = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR, gpu::Sampler::WRAP_CLAMP));
|
||||||
_occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusion"));
|
_occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusion"));
|
||||||
_occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture);
|
_occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture);
|
||||||
|
|
||||||
_occlusionBlurredTexture = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT, gpu::Sampler::WRAP_CLAMP));
|
_occlusionBlurredTexture = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR, gpu::Sampler::WRAP_CLAMP));
|
||||||
_occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusionBlurred"));
|
_occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusionBlurred"));
|
||||||
_occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture);
|
_occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture);
|
||||||
|
|
||||||
|
_normalTexture = gpu::Texture::createRenderBuffer(gpu::Element::COLOR_R11G11B10, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT, gpu::Sampler::WRAP_CLAMP));
|
||||||
|
_normalFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("ssaoNormals"));
|
||||||
|
_normalFramebuffer->setRenderBuffer(0, _normalTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::FramebufferPointer AmbientOcclusionFramebuffer::getOcclusionFramebuffer() {
|
gpu::FramebufferPointer AmbientOcclusionFramebuffer::getOcclusionFramebuffer() {
|
||||||
|
@ -115,6 +121,19 @@ gpu::TexturePointer AmbientOcclusionFramebuffer::getOcclusionBlurredTexture() {
|
||||||
return _occlusionBlurredTexture;
|
return _occlusionBlurredTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gpu::FramebufferPointer AmbientOcclusionFramebuffer::getNormalFramebuffer() {
|
||||||
|
if (!_normalFramebuffer) {
|
||||||
|
allocate();
|
||||||
|
}
|
||||||
|
return _normalFramebuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu::TexturePointer AmbientOcclusionFramebuffer::getNormalTexture() {
|
||||||
|
if (!_normalTexture) {
|
||||||
|
allocate();
|
||||||
|
}
|
||||||
|
return _normalTexture;
|
||||||
|
}
|
||||||
|
|
||||||
class GaussianDistribution {
|
class GaussianDistribution {
|
||||||
public:
|
public:
|
||||||
|
@ -189,11 +208,11 @@ AmbientOcclusionEffectConfig::AmbientOcclusionEffectConfig() :
|
||||||
blurDeviation{ 2.5f },
|
blurDeviation{ 2.5f },
|
||||||
numSpiralTurns{ 7.0f },
|
numSpiralTurns{ 7.0f },
|
||||||
#if SSAO_USE_HORIZON_BASED
|
#if SSAO_USE_HORIZON_BASED
|
||||||
numSamples{ 1 },
|
numSamples{ 2 },
|
||||||
#else
|
#else
|
||||||
numSamples{ 16 },
|
numSamples{ 16 },
|
||||||
#endif
|
#endif
|
||||||
resolutionLevel{ 1 },
|
resolutionLevel{ 2 },
|
||||||
blurRadius{ 4 },
|
blurRadius{ 4 },
|
||||||
ditheringEnabled{ true },
|
ditheringEnabled{ true },
|
||||||
borderingEnabled{ true },
|
borderingEnabled{ true },
|
||||||
|
@ -262,8 +281,8 @@ void AmbientOcclusionEffect::configure(const Config& config) {
|
||||||
current.x = config.numSamples;
|
current.x = config.numSamples;
|
||||||
current.y = 1.0f / config.numSamples;
|
current.y = 1.0f / config.numSamples;
|
||||||
|
|
||||||
// Regenerate halton sequence
|
// Regenerate offsets
|
||||||
const int B = config.numSamples + 1;
|
const int B = 3;
|
||||||
const float invB = 1.0f / (float)B;
|
const float invB = 1.0f / (float)B;
|
||||||
|
|
||||||
for (int i = 0; i < _randomSamples.size(); i++) {
|
for (int i = 0; i < _randomSamples.size(); i++) {
|
||||||
|
@ -276,7 +295,7 @@ void AmbientOcclusionEffect::configure(const Config& config) {
|
||||||
r = r + f * (float)(index % B);
|
r = r + f * (float)(index % B);
|
||||||
index = index / B;
|
index = index / B;
|
||||||
}
|
}
|
||||||
_randomSamples[i] = r;
|
_randomSamples[i] = r * M_PI / config.numSamples;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +315,7 @@ void AmbientOcclusionEffect::configure(const Config& config) {
|
||||||
|
|
||||||
if (config.resolutionLevel != _aoParametersBuffer->getResolutionLevel()) {
|
if (config.resolutionLevel != _aoParametersBuffer->getResolutionLevel()) {
|
||||||
auto& current = _aoParametersBuffer.edit()._resolutionInfo;
|
auto& current = _aoParametersBuffer.edit()._resolutionInfo;
|
||||||
current.x = (float) config.resolutionLevel;
|
current.x = (float)config.resolutionLevel;
|
||||||
shouldUpdateBlurs = true;
|
shouldUpdateBlurs = true;
|
||||||
|
|
||||||
_aoFrameParametersBuffer[0].edit()._pixelOffsets = { 0, 0, 0, 0 };
|
_aoFrameParametersBuffer[0].edit()._pixelOffsets = { 0, 0, 0, 0 };
|
||||||
|
@ -307,7 +326,7 @@ void AmbientOcclusionEffect::configure(const Config& config) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.blurRadius != _aoParametersBuffer->getBlurRadius()) {
|
if (config.blurRadius != _aoParametersBuffer.get().getBlurRadius()) {
|
||||||
auto& current = _aoParametersBuffer.edit()._blurInfo;
|
auto& current = _aoParametersBuffer.edit()._blurInfo;
|
||||||
current.y = (float)config.blurRadius;
|
current.y = (float)config.blurRadius;
|
||||||
shouldUpdateGaussian = true;
|
shouldUpdateGaussian = true;
|
||||||
|
@ -361,7 +380,6 @@ const gpu::PipelinePointer& AmbientOcclusionEffect::getOcclusionPipeline() {
|
||||||
return _occlusionPipeline;
|
return _occlusionPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const gpu::PipelinePointer& AmbientOcclusionEffect::getHBlurPipeline() {
|
const gpu::PipelinePointer& AmbientOcclusionEffect::getHBlurPipeline() {
|
||||||
if (!_hBlurPipeline) {
|
if (!_hBlurPipeline) {
|
||||||
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::ssao_makeHorizontalBlur);
|
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::ssao_makeHorizontalBlur);
|
||||||
|
@ -409,9 +427,24 @@ const gpu::PipelinePointer& AmbientOcclusionEffect::getGatherPipeline() {
|
||||||
return _gatherPipeline;
|
return _gatherPipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const gpu::PipelinePointer& AmbientOcclusionEffect::getBuildNormalsPipeline() {
|
||||||
|
if (!_buildNormalsPipeline) {
|
||||||
|
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::ssao_buildNormals);
|
||||||
|
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||||
|
|
||||||
|
state->setColorWriteMask(true, true, true, false);
|
||||||
|
|
||||||
|
// Good to go add the brand new pipeline
|
||||||
|
_buildNormalsPipeline = gpu::Pipeline::create(program, state);
|
||||||
|
}
|
||||||
|
return _buildNormalsPipeline;
|
||||||
|
}
|
||||||
|
|
||||||
void AmbientOcclusionEffect::updateGaussianDistribution() {
|
void AmbientOcclusionEffect::updateGaussianDistribution() {
|
||||||
auto coefs = _aoParametersBuffer.edit()._gaussianCoefs;
|
auto filterTaps = _aoParametersBuffer.edit()._blurFilterTaps;
|
||||||
GaussianDistribution::evalSampling(coefs, SSAO_BLUR_GAUSSIAN_COEFS_COUNT, _aoParametersBuffer->getBlurRadius(), _aoParametersBuffer->getBlurDeviation());
|
auto blurRadius = _aoParametersBuffer.get().getBlurRadius();
|
||||||
|
|
||||||
|
GaussianDistribution::evalSampling(filterTaps, SSAO_BLUR_GAUSSIAN_COEFS_COUNT, blurRadius, _aoParametersBuffer->getBlurDeviation() * 4.0f / blurRadius);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) {
|
void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderContext, const Inputs& inputs, Outputs& outputs) {
|
||||||
|
@ -436,7 +469,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
||||||
if (!_framebuffer) {
|
if (!_framebuffer) {
|
||||||
_framebuffer = std::make_shared<AmbientOcclusionFramebuffer>();
|
_framebuffer = std::make_shared<AmbientOcclusionFramebuffer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto resolutionScale = powf(0.5f, _aoParametersBuffer->getResolutionLevel());
|
const auto resolutionScale = powf(0.5f, _aoParametersBuffer->getResolutionLevel());
|
||||||
if (_aoParametersBuffer->getResolutionLevel() > 0) {
|
if (_aoParametersBuffer->getResolutionLevel() > 0) {
|
||||||
occlusionViewport = occlusionViewport >> _aoParametersBuffer->getResolutionLevel();
|
occlusionViewport = occlusionViewport >> _aoParametersBuffer->getResolutionLevel();
|
||||||
|
@ -464,15 +497,19 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
||||||
#endif
|
#endif
|
||||||
#if SSAO_USE_QUAD_SPLIT
|
#if SSAO_USE_QUAD_SPLIT
|
||||||
auto gatherPipeline = getGatherPipeline();
|
auto gatherPipeline = getGatherPipeline();
|
||||||
|
auto buildNormalsPipeline = getBuildNormalsPipeline();
|
||||||
|
auto occlusionNormalFramebuffer = _framebuffer->getNormalFramebuffer();
|
||||||
|
auto occlusionNormalTexture = _framebuffer->getNormalTexture();
|
||||||
#endif
|
#endif
|
||||||
|
auto fullNormalTexture = linearDepthFramebuffer->getNormalTexture();
|
||||||
|
|
||||||
// Update sample rotation
|
// Update sample rotation
|
||||||
const int SSAO_RANDOM_SAMPLE_COUNT = int(_randomSamples.size() / SSAO_SPLIT_COUNT);
|
const int SSAO_RANDOM_SAMPLE_COUNT = int(_randomSamples.size() / SSAO_SPLIT_COUNT);
|
||||||
for (int splitId=0 ; splitId < SSAO_SPLIT_COUNT ; splitId++) {
|
for (int splitId=0 ; splitId < SSAO_SPLIT_COUNT ; splitId++) {
|
||||||
auto& sample = _aoFrameParametersBuffer[splitId].edit();
|
auto& sample = _aoFrameParametersBuffer[splitId].edit();
|
||||||
sample._angleInfo.x = _randomSamples[_frameId + SSAO_RANDOM_SAMPLE_COUNT * splitId] * M_PI;
|
sample._angleInfo.x = _randomSamples[splitId + SSAO_RANDOM_SAMPLE_COUNT * _frameId];
|
||||||
}
|
}
|
||||||
_frameId = (_frameId + 1) % SSAO_RANDOM_SAMPLE_COUNT;
|
// TEMPO OP _frameId = (_frameId + 1) % SSAO_RANDOM_SAMPLE_COUNT;
|
||||||
|
|
||||||
gpu::doInBatch("AmbientOcclusionEffect::run", args->_context, [=](gpu::Batch& batch) {
|
gpu::doInBatch("AmbientOcclusionEffect::run", args->_context, [=](gpu::Batch& batch) {
|
||||||
PROFILE_RANGE_BATCH(batch, "AmbientOcclusion");
|
PROFILE_RANGE_BATCH(batch, "AmbientOcclusion");
|
||||||
|
@ -480,7 +517,6 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
||||||
|
|
||||||
_gpuTimer->begin(batch);
|
_gpuTimer->begin(batch);
|
||||||
|
|
||||||
batch.setProjectionTransform(glm::mat4());
|
|
||||||
batch.resetViewTransform();
|
batch.resetViewTransform();
|
||||||
|
|
||||||
Transform model;
|
Transform model;
|
||||||
|
@ -490,53 +526,67 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
||||||
// We need this with the mips levels
|
// We need this with the mips levels
|
||||||
batch.pushProfileRange("Depth mip creation");
|
batch.pushProfileRange("Depth mip creation");
|
||||||
#if SSAO_USE_HORIZON_BASED
|
#if SSAO_USE_HORIZON_BASED
|
||||||
batch.setPipeline(mipCreationPipeline);
|
batch.setPipeline(mipCreationPipeline);
|
||||||
batch.generateTextureMipsWithPipeline(occlusionDepthTexture);
|
batch.generateTextureMipsWithPipeline(occlusionDepthTexture);
|
||||||
#else
|
#else
|
||||||
batch.generateTextureMips(occlusionDepthTexture);
|
batch.generateTextureMips(occlusionDepthTexture);
|
||||||
#endif
|
#endif
|
||||||
batch.popProfileRange();
|
batch.popProfileRange();
|
||||||
|
|
||||||
|
#if SSAO_USE_QUAD_SPLIT
|
||||||
|
// Build derivative normals pass
|
||||||
|
batch.pushProfileRange("Build Normals");
|
||||||
|
batch.setViewportTransform(sourceViewport);
|
||||||
|
batch.setPipeline(buildNormalsPipeline);
|
||||||
|
batch.setUniformBuffer(render_utils::slot::buffer::DeferredFrameTransform, frameTransform->getFrameTransformBuffer());
|
||||||
|
batch.setUniformBuffer(render_utils::slot::buffer::SsaoParams, _aoParametersBuffer);
|
||||||
|
batch.setFramebuffer(occlusionNormalFramebuffer);
|
||||||
|
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, linearDepthTexture);
|
||||||
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
|
batch.popProfileRange();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Occlusion pass
|
// Occlusion pass
|
||||||
batch.pushProfileRange("Occlusion");
|
batch.pushProfileRange("Occlusion");
|
||||||
|
|
||||||
batch.setUniformBuffer(render_utils::slot::buffer::DeferredFrameTransform, frameTransform->getFrameTransformBuffer());
|
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);
|
||||||
#if SSAO_USE_QUAD_SPLIT
|
#if SSAO_USE_QUAD_SPLIT
|
||||||
batch.setFramebuffer(occlusionBlurredFBO);
|
batch.setFramebuffer(occlusionBlurredFBO);
|
||||||
#else
|
#else
|
||||||
batch.setFramebuffer(occlusionFBO);
|
batch.setFramebuffer(occlusionFBO);
|
||||||
#endif
|
#endif
|
||||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(1.0f));
|
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(1.0f));
|
||||||
batch.setPipeline(occlusionPipeline);
|
batch.setPipeline(occlusionPipeline);
|
||||||
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, occlusionDepthTexture);
|
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, occlusionDepthTexture);
|
||||||
|
|
||||||
#if SSAO_USE_QUAD_SPLIT
|
#if SSAO_USE_QUAD_SPLIT
|
||||||
{
|
batch.setResourceTexture(render_utils::slot::texture::SsaoNormal, occlusionNormalTexture);
|
||||||
auto splitViewport = occlusionViewport >> SSAO_USE_QUAD_SPLIT;
|
{
|
||||||
|
auto splitViewport = occlusionViewport >> SSAO_USE_QUAD_SPLIT;
|
||||||
|
|
||||||
batch.setViewportTransform(splitViewport);
|
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.setUniformBuffer(render_utils::slot::buffer::SsaoFrameParams, _aoFrameParametersBuffer[0]);
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
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
|
#endif
|
||||||
|
|
||||||
batch.popProfileRange();
|
batch.popProfileRange();
|
||||||
|
@ -544,11 +594,11 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
||||||
#if SSAO_USE_QUAD_SPLIT
|
#if SSAO_USE_QUAD_SPLIT
|
||||||
// Gather back the four separate renders into one interleaved one
|
// Gather back the four separate renders into one interleaved one
|
||||||
batch.pushProfileRange("Gather");
|
batch.pushProfileRange("Gather");
|
||||||
batch.setViewportTransform(occlusionViewport);
|
batch.setViewportTransform(occlusionViewport);
|
||||||
batch.setFramebuffer(occlusionFBO);
|
batch.setFramebuffer(occlusionFBO);
|
||||||
batch.setPipeline(gatherPipeline);
|
batch.setPipeline(gatherPipeline);
|
||||||
batch.setResourceTexture(render_utils::slot::texture::SsaoOcclusion, occlusionBlurredFBO->getRenderBuffer(0));
|
batch.setResourceTexture(render_utils::slot::texture::SsaoOcclusion, occlusionBlurredFBO->getRenderBuffer(0));
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
batch.popProfileRange();
|
batch.popProfileRange();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -561,6 +611,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
|
||||||
batch.setFramebuffer(occlusionBlurredFBO);
|
batch.setFramebuffer(occlusionBlurredFBO);
|
||||||
// Use full resolution depth and normal for bilateral upscaling and blur
|
// Use full resolution depth and normal for bilateral upscaling and blur
|
||||||
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, linearDepthTexture);
|
batch.setResourceTexture(render_utils::slot::texture::SsaoDepth, linearDepthTexture);
|
||||||
|
batch.setResourceTexture(render_utils::slot::texture::SsaoNormal, fullNormalTexture);
|
||||||
batch.setUniformBuffer(render_utils::slot::buffer::SsaoBlurParams, _hblurParametersBuffer);
|
batch.setUniformBuffer(render_utils::slot::buffer::SsaoBlurParams, _hblurParametersBuffer);
|
||||||
batch.setPipeline(firstHBlurPipeline);
|
batch.setPipeline(firstHBlurPipeline);
|
||||||
batch.setResourceTexture(render_utils::slot::texture::SsaoOcclusion, occlusionFBO->getRenderBuffer(0));
|
batch.setResourceTexture(render_utils::slot::texture::SsaoOcclusion, occlusionFBO->getRenderBuffer(0));
|
||||||
|
|
|
@ -30,7 +30,10 @@ public:
|
||||||
|
|
||||||
gpu::FramebufferPointer getOcclusionBlurredFramebuffer();
|
gpu::FramebufferPointer getOcclusionBlurredFramebuffer();
|
||||||
gpu::TexturePointer getOcclusionBlurredTexture();
|
gpu::TexturePointer getOcclusionBlurredTexture();
|
||||||
|
|
||||||
|
gpu::FramebufferPointer getNormalFramebuffer();
|
||||||
|
gpu::TexturePointer getNormalTexture();
|
||||||
|
|
||||||
// Update the source framebuffer size which will drive the allocation of all the other resources.
|
// Update the source framebuffer size which will drive the allocation of all the other resources.
|
||||||
bool updateLinearDepth(const gpu::TexturePointer& linearDepthBuffer);
|
bool updateLinearDepth(const gpu::TexturePointer& linearDepthBuffer);
|
||||||
gpu::TexturePointer getLinearDepthTexture();
|
gpu::TexturePointer getLinearDepthTexture();
|
||||||
|
@ -44,10 +47,13 @@ protected:
|
||||||
|
|
||||||
gpu::FramebufferPointer _occlusionFramebuffer;
|
gpu::FramebufferPointer _occlusionFramebuffer;
|
||||||
gpu::TexturePointer _occlusionTexture;
|
gpu::TexturePointer _occlusionTexture;
|
||||||
|
|
||||||
gpu::FramebufferPointer _occlusionBlurredFramebuffer;
|
gpu::FramebufferPointer _occlusionBlurredFramebuffer;
|
||||||
gpu::TexturePointer _occlusionBlurredTexture;
|
gpu::TexturePointer _occlusionBlurredTexture;
|
||||||
|
|
||||||
|
gpu::FramebufferPointer _normalFramebuffer;
|
||||||
|
gpu::TexturePointer _normalTexture;
|
||||||
|
|
||||||
|
|
||||||
glm::ivec2 _frameSize;
|
glm::ivec2 _frameSize;
|
||||||
};
|
};
|
||||||
|
@ -168,12 +174,14 @@ private:
|
||||||
static const gpu::PipelinePointer& getVBlurPipeline(); // second
|
static const gpu::PipelinePointer& getVBlurPipeline(); // second
|
||||||
static const gpu::PipelinePointer& getMipCreationPipeline();
|
static const gpu::PipelinePointer& getMipCreationPipeline();
|
||||||
static const gpu::PipelinePointer& getGatherPipeline();
|
static const gpu::PipelinePointer& getGatherPipeline();
|
||||||
|
static const gpu::PipelinePointer& getBuildNormalsPipeline();
|
||||||
|
|
||||||
static gpu::PipelinePointer _occlusionPipeline;
|
static gpu::PipelinePointer _occlusionPipeline;
|
||||||
static gpu::PipelinePointer _hBlurPipeline;
|
static gpu::PipelinePointer _hBlurPipeline;
|
||||||
static gpu::PipelinePointer _vBlurPipeline;
|
static gpu::PipelinePointer _vBlurPipeline;
|
||||||
static gpu::PipelinePointer _mipCreationPipeline;
|
static gpu::PipelinePointer _mipCreationPipeline;
|
||||||
static gpu::PipelinePointer _gatherPipeline;
|
static gpu::PipelinePointer _gatherPipeline;
|
||||||
|
static gpu::PipelinePointer _buildNormalsPipeline;
|
||||||
|
|
||||||
AmbientOcclusionFramebufferPointer _framebuffer;
|
AmbientOcclusionFramebufferPointer _framebuffer;
|
||||||
std::array<float, 16 * SSAO_SPLIT_COUNT> _randomSamples;
|
std::array<float, 16 * SSAO_SPLIT_COUNT> _randomSamples;
|
||||||
|
|
|
@ -28,11 +28,12 @@ namespace ru {
|
||||||
LinearDepthFramebuffer::LinearDepthFramebuffer() {
|
LinearDepthFramebuffer::LinearDepthFramebuffer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinearDepthFramebuffer::update(const gpu::TexturePointer& depthBuffer) {
|
void LinearDepthFramebuffer::update(const gpu::TexturePointer& depthBuffer, const gpu::TexturePointer& normalTexture) {
|
||||||
//If the depth buffer or size changed, we need to delete our FBOs
|
//If the depth buffer or size changed, we need to delete our FBOs
|
||||||
bool reset = false;
|
bool reset = false;
|
||||||
if (_primaryDepthTexture != depthBuffer) {
|
if (_primaryDepthTexture != depthBuffer || _normalTexture != normalTexture) {
|
||||||
_primaryDepthTexture = depthBuffer;
|
_primaryDepthTexture = depthBuffer;
|
||||||
|
_normalTexture = normalTexture;
|
||||||
reset = true;
|
reset = true;
|
||||||
}
|
}
|
||||||
if (_primaryDepthTexture) {
|
if (_primaryDepthTexture) {
|
||||||
|
@ -100,6 +101,10 @@ gpu::TexturePointer LinearDepthFramebuffer::getLinearDepthTexture() {
|
||||||
return _linearDepthTexture;
|
return _linearDepthTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gpu::TexturePointer LinearDepthFramebuffer::getNormalTexture() {
|
||||||
|
return _normalTexture;
|
||||||
|
}
|
||||||
|
|
||||||
gpu::FramebufferPointer LinearDepthFramebuffer::getDownsampleFramebuffer() {
|
gpu::FramebufferPointer LinearDepthFramebuffer::getDownsampleFramebuffer() {
|
||||||
if (!_downsampleFramebuffer) {
|
if (!_downsampleFramebuffer) {
|
||||||
allocate();
|
allocate();
|
||||||
|
@ -148,7 +153,7 @@ void LinearDepthPass::run(const render::RenderContextPointer& renderContext, con
|
||||||
auto depthBuffer = deferredFramebuffer->getPrimaryDepthTexture();
|
auto depthBuffer = deferredFramebuffer->getPrimaryDepthTexture();
|
||||||
auto normalTexture = deferredFramebuffer->getDeferredNormalTexture();
|
auto normalTexture = deferredFramebuffer->getDeferredNormalTexture();
|
||||||
|
|
||||||
_linearDepthFramebuffer->update(depthBuffer);
|
_linearDepthFramebuffer->update(depthBuffer, normalTexture);
|
||||||
|
|
||||||
auto linearDepthFBO = _linearDepthFramebuffer->getLinearDepthFramebuffer();
|
auto linearDepthFBO = _linearDepthFramebuffer->getLinearDepthFramebuffer();
|
||||||
auto linearDepthTexture = _linearDepthFramebuffer->getLinearDepthTexture();
|
auto linearDepthTexture = _linearDepthFramebuffer->getLinearDepthTexture();
|
||||||
|
|
|
@ -28,13 +28,14 @@ public:
|
||||||
|
|
||||||
gpu::FramebufferPointer getLinearDepthFramebuffer();
|
gpu::FramebufferPointer getLinearDepthFramebuffer();
|
||||||
gpu::TexturePointer getLinearDepthTexture();
|
gpu::TexturePointer getLinearDepthTexture();
|
||||||
|
gpu::TexturePointer getNormalTexture();
|
||||||
|
|
||||||
gpu::FramebufferPointer getDownsampleFramebuffer();
|
gpu::FramebufferPointer getDownsampleFramebuffer();
|
||||||
gpu::TexturePointer getHalfLinearDepthTexture();
|
gpu::TexturePointer getHalfLinearDepthTexture();
|
||||||
gpu::TexturePointer getHalfNormalTexture();
|
gpu::TexturePointer getHalfNormalTexture();
|
||||||
|
|
||||||
// Update the depth buffer which will drive the allocation of all the other resources according to its size.
|
// Update the depth buffer which will drive the allocation of all the other resources according to its size.
|
||||||
void update(const gpu::TexturePointer& depthBuffer);
|
void update(const gpu::TexturePointer& depthBuffer, const gpu::TexturePointer& normalTexture);
|
||||||
const glm::ivec2& getDepthFrameSize() const { return _frameSize; }
|
const glm::ivec2& getDepthFrameSize() const { return _frameSize; }
|
||||||
|
|
||||||
void setResolutionLevel(int level) { _resolutionLevel = std::max(0, level); }
|
void setResolutionLevel(int level) { _resolutionLevel = std::max(0, level); }
|
||||||
|
@ -48,6 +49,7 @@ protected:
|
||||||
|
|
||||||
gpu::FramebufferPointer _linearDepthFramebuffer;
|
gpu::FramebufferPointer _linearDepthFramebuffer;
|
||||||
gpu::TexturePointer _linearDepthTexture;
|
gpu::TexturePointer _linearDepthTexture;
|
||||||
|
gpu::TexturePointer _normalTexture;
|
||||||
|
|
||||||
gpu::FramebufferPointer _downsampleFramebuffer;
|
gpu::FramebufferPointer _downsampleFramebuffer;
|
||||||
gpu::TexturePointer _halfLinearDepthTexture;
|
gpu::TexturePointer _halfLinearDepthTexture;
|
||||||
|
|
|
@ -89,6 +89,7 @@
|
||||||
#define RENDER_UTILS_BUFFER_SSAO_BLUR_PARAMS 4
|
#define RENDER_UTILS_BUFFER_SSAO_BLUR_PARAMS 4
|
||||||
#define RENDER_UTILS_BUFFER_SSAO_FRAME_PARAMS 5
|
#define RENDER_UTILS_BUFFER_SSAO_FRAME_PARAMS 5
|
||||||
#define RENDER_UTILS_TEXTURE_SSAO_DEPTH 1
|
#define RENDER_UTILS_TEXTURE_SSAO_DEPTH 1
|
||||||
|
#define RENDER_UTILS_TEXTURE_SSAO_NORMAL 2
|
||||||
#define RENDER_UTILS_TEXTURE_SSAO_OCCLUSION 0
|
#define RENDER_UTILS_TEXTURE_SSAO_OCCLUSION 0
|
||||||
|
|
||||||
// Temporal anti-aliasing
|
// Temporal anti-aliasing
|
||||||
|
@ -196,6 +197,7 @@ enum Texture {
|
||||||
TaaNext = RENDER_UTILS_TEXTURE_TAA_NEXT,
|
TaaNext = RENDER_UTILS_TEXTURE_TAA_NEXT,
|
||||||
SsaoOcclusion = RENDER_UTILS_TEXTURE_SSAO_OCCLUSION,
|
SsaoOcclusion = RENDER_UTILS_TEXTURE_SSAO_OCCLUSION,
|
||||||
SsaoDepth = RENDER_UTILS_TEXTURE_SSAO_DEPTH,
|
SsaoDepth = RENDER_UTILS_TEXTURE_SSAO_DEPTH,
|
||||||
|
SsaoNormal = RENDER_UTILS_TEXTURE_SSAO_NORMAL,
|
||||||
HighlightSceneDepth = RENDER_UTILS_TEXTURE_HIGHLIGHT_SCENE_DEPTH,
|
HighlightSceneDepth = RENDER_UTILS_TEXTURE_HIGHLIGHT_SCENE_DEPTH,
|
||||||
HighlightDepth = RENDER_UTILS_TEXTURE_HIGHLIGHT_DEPTH,
|
HighlightDepth = RENDER_UTILS_TEXTURE_HIGHLIGHT_DEPTH,
|
||||||
SurfaceGeometryDepth = RENDER_UTILS_TEXTURE_SG_DEPTH,
|
SurfaceGeometryDepth = RENDER_UTILS_TEXTURE_SG_DEPTH,
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
VERTEX gpu::vertex::DrawViewportQuadTransformTexcoord
|
|
@ -98,32 +98,13 @@ float getBlurEdgeSharpness() {
|
||||||
return params._blurInfo.x;
|
return params._blurInfo.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONSTANT_GAUSSIAN
|
|
||||||
const int BLUR_RADIUS = 4;
|
|
||||||
const float gaussian[BLUR_RADIUS + 1] =
|
|
||||||
// KEEP this dead code for eventual performance improvment
|
|
||||||
// float[](0.356642, 0.239400, 0.072410, 0.009869);
|
|
||||||
// float[](0.398943, 0.241971, 0.053991, 0.004432, 0.000134); // stddev = 1.0
|
|
||||||
float[](0.153170, 0.144893, 0.122649, 0.092902, 0.062970); // stddev = 2.0
|
|
||||||
//float[](0.197413, 0.17467, 0.12098,0.065591,0.040059);
|
|
||||||
// float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // stddev = 3.0
|
|
||||||
|
|
||||||
int getBlurRadius() {
|
|
||||||
return BLUR_RADIUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getBlurCoef(int c) {
|
|
||||||
return gaussian[c];
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int getBlurRadius() {
|
int getBlurRadius() {
|
||||||
return int(params._blurInfo.y);
|
return int(params._blurInfo.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
float getBlurCoef(int c) {
|
float getBlurCoef(int c) {
|
||||||
return params._gaussianCoefs[c];
|
return params._blurFilterTaps[c];
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
|
@ -219,6 +200,7 @@ vec3 getTapLocationClampedSSAO(int sampleNumber, float spinAngle, float outerRad
|
||||||
|
|
||||||
// the depth pyramid texture
|
// the depth pyramid texture
|
||||||
layout(binding=RENDER_UTILS_TEXTURE_SSAO_DEPTH) uniform sampler2D depthPyramidTex;
|
layout(binding=RENDER_UTILS_TEXTURE_SSAO_DEPTH) uniform sampler2D depthPyramidTex;
|
||||||
|
layout(binding=RENDER_UTILS_TEXTURE_SSAO_NORMAL) uniform sampler2D normalTex;
|
||||||
|
|
||||||
float getZEyeAtPixel(ivec2 pixel, int level) {
|
float getZEyeAtPixel(ivec2 pixel, int level) {
|
||||||
return -texelFetch(depthPyramidTex, pixel, level).x;
|
return -texelFetch(depthPyramidTex, pixel, level).x;
|
||||||
|
@ -228,8 +210,12 @@ float getZEyeAtUV(vec2 texCoord, int level) {
|
||||||
return -texture(depthPyramidTex, texCoord, level).x;
|
return -texture(depthPyramidTex, texCoord, level).x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 getNormalEyeAtUV(vec2 texCoord, int level) {
|
||||||
|
return normalize(texture(normalTex, texCoord, level).xyz*2.0 - vec3(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
int evalMipFromRadius(float radius) {
|
int evalMipFromRadius(float radius) {
|
||||||
const int LOG_MAX_OFFSET = 1;
|
const int LOG_MAX_OFFSET = 2;
|
||||||
const int MAX_MIP_LEVEL = 5;
|
const int MAX_MIP_LEVEL = 5;
|
||||||
return clamp(findMSB(int(radius)) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL);
|
return clamp(findMSB(int(radius)) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL);
|
||||||
}
|
}
|
||||||
|
@ -406,24 +392,22 @@ float fetchOcclusion(vec2 coords) {
|
||||||
return raw.x;
|
return raw.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float BLUR_WEIGHT_OFFSET = 0.01;
|
|
||||||
const float BLUR_EDGE_DISTANCE_SCALE = 300.0;
|
const float BLUR_EDGE_DISTANCE_SCALE = 300.0;
|
||||||
|
|
||||||
vec2 evalTapWeightedValue(ivec3 side, int r, ivec2 destPixelCoord, vec2 scaledTexCoord, vec2 fullTexCoord, float fragDepth) {
|
vec2 evalTapWeightedValue(ivec3 side, int r, ivec2 destPixelCoord, vec2 scaledTexCoord, vec2 fullTexCoord, float fragDepth) {
|
||||||
ivec2 tapOffset = <$axis$> * r;
|
ivec2 tapOffset = <$axis$> * r;
|
||||||
ivec2 tapPixelCoord = destPixelCoord + tapOffset;
|
ivec2 tapPixelCoord = destPixelCoord + ivec2(tapOffset);
|
||||||
|
|
||||||
if ((tapPixelCoord.x < side.y || tapPixelCoord.x >= side.z + side.y) || (tapPixelCoord.y < 0 || tapPixelCoord.y >= getBlurImageHeight())) {
|
if ((tapPixelCoord.x < side.y || tapPixelCoord.x >= side.z + side.y) || (tapPixelCoord.y < 0 || tapPixelCoord.y >= getBlurImageHeight())) {
|
||||||
return vec2(0.0);
|
return vec2(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 tapTexCoord = scaledTexCoord + tapOffset * getOcclusionBlurScale();
|
vec2 tapTexCoord = scaledTexCoord + tapOffset * getOcclusionBlurScale();
|
||||||
float tapOcclusion = fetchOcclusion(tapTexCoord);
|
float tapOcclusion = fetchOcclusion(tapTexCoord);
|
||||||
|
|
||||||
tapTexCoord = fullTexCoord + tapOffset * getDepthBlurScale();
|
tapTexCoord = fullTexCoord + tapOffset * getDepthBlurScale();
|
||||||
float tapDepth = getZEyeAtUV(tapTexCoord, 0);
|
float tapDepth = getZEyeAtUV(tapTexCoord, 0);
|
||||||
|
float weight = getBlurCoef(abs(r));
|
||||||
// spatial domain: offset gaussian tap
|
|
||||||
float weight = BLUR_WEIGHT_OFFSET + getBlurCoef(abs(r));
|
|
||||||
|
|
||||||
// range domain (the "bilateral" weight). As depth difference increases, decrease weight.
|
// range domain (the "bilateral" weight). As depth difference increases, decrease weight.
|
||||||
float zDistance = tapDepth - fragDepth;
|
float zDistance = tapDepth - fragDepth;
|
||||||
|
@ -441,6 +425,7 @@ vec3 getBlurredOcclusion(ivec2 destPixelCoord, vec2 scaledTexCoord, vec2 fullTex
|
||||||
|
|
||||||
// Accumulate weighted contributions along the bluring axis in the [-radius, radius] range
|
// Accumulate weighted contributions along the bluring axis in the [-radius, radius] range
|
||||||
int blurRadius = getBlurRadius();
|
int blurRadius = getBlurRadius();
|
||||||
|
|
||||||
// negative side first
|
// negative side first
|
||||||
for (int r = -blurRadius; r <= -1; ++r) {
|
for (int r = -blurRadius; r <= -1; ++r) {
|
||||||
weightedSums += evalTapWeightedValue(side.xyz, r, destPixelCoord, scaledTexCoord, fullTexCoord, fragDepth);
|
weightedSums += evalTapWeightedValue(side.xyz, r, destPixelCoord, scaledTexCoord, fullTexCoord, fragDepth);
|
||||||
|
|
45
libraries/render-utils/src/ssao_buildNormals.slf
Normal file
45
libraries/render-utils/src/ssao_buildNormals.slf
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// ssao_buildNormals.frag
|
||||||
|
//
|
||||||
|
// Created by Olivier Prat on 09/19/18.
|
||||||
|
// Copyright 2018 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
<@include ssao.slh@>
|
||||||
|
<$declareAmbientOcclusion()$>
|
||||||
|
<$declareFetchDepthPyramidMap()$>
|
||||||
|
|
||||||
|
layout(location=0) out vec4 outFragColor;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec2 sideImageSize = getSideImageSize(0);
|
||||||
|
|
||||||
|
// Pixel being shaded
|
||||||
|
vec2 fragCoord = gl_FragCoord.xy;
|
||||||
|
ivec2 fragPixelPos = ivec2(fragCoord.xy);
|
||||||
|
|
||||||
|
// Stereo side info
|
||||||
|
ivec4 side = getStereoSideInfo(fragPixelPos.x, 0);
|
||||||
|
|
||||||
|
// From now on, fragPixelPos is the pixel pos in the side
|
||||||
|
fragPixelPos.x -= side.y;
|
||||||
|
vec2 fragUVPos = (vec2(fragPixelPos) + vec2(0.5)) / sideImageSize;
|
||||||
|
|
||||||
|
// Fetch the z under the pixel (stereo or not)
|
||||||
|
float Zeye = getZEyeAtUV(fragUVPos, 0);
|
||||||
|
|
||||||
|
// The position and normal of the pixel fragment in Eye space
|
||||||
|
vec3 fragPositionES = evalEyePositionFromZeye(side.x, Zeye, fragUVPos);
|
||||||
|
vec3 fragNormalES = evalEyeNormal(fragPositionES);
|
||||||
|
vec3 absFragNormalES = abs(fragNormalES);
|
||||||
|
|
||||||
|
// Maximize encoding precision
|
||||||
|
fragNormalES /= max(max(absFragNormalES.x, absFragNormalES.y), absFragNormalES.z);
|
||||||
|
outFragColor = vec4(vec3(fragNormalES)*0.5 + vec3(0.5), 1.0);
|
||||||
|
}
|
|
@ -46,7 +46,11 @@ void main(void) {
|
||||||
|
|
||||||
// The position and normal of the pixel fragment in Eye space
|
// The position and normal of the pixel fragment in Eye space
|
||||||
vec3 fragPositionES = evalEyePositionFromZeye(side.x, Zeye, fragUVPos);
|
vec3 fragPositionES = evalEyePositionFromZeye(side.x, Zeye, fragUVPos);
|
||||||
|
#if SSAO_USE_QUAD_SPLIT
|
||||||
|
vec3 fragNormalES = getNormalEyeAtUV(fragUVPos, 0);
|
||||||
|
#else
|
||||||
vec3 fragNormalES = evalEyeNormal(fragPositionES);
|
vec3 fragNormalES = evalEyeNormal(fragPositionES);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Choose the screen-space sample radius
|
// Choose the screen-space sample radius
|
||||||
float diskPixelRadius = evalDiskRadius(fragPositionES.z, sideImageSize);
|
float diskPixelRadius = evalDiskRadius(fragPositionES.z, sideImageSize);
|
||||||
|
|
|
@ -39,7 +39,7 @@ struct AmbientOcclusionParams {
|
||||||
SSAO_VEC4 _ditheringInfo;
|
SSAO_VEC4 _ditheringInfo;
|
||||||
SSAO_VEC4 _sampleInfo;
|
SSAO_VEC4 _sampleInfo;
|
||||||
SSAO_VEC4 _blurInfo;
|
SSAO_VEC4 _blurInfo;
|
||||||
float _gaussianCoefs[SSAO_BLUR_GAUSSIAN_COEFS_COUNT];
|
float _blurFilterTaps[SSAO_BLUR_GAUSSIAN_COEFS_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AmbientOcclusionFrameParams {
|
struct AmbientOcclusionFrameParams {
|
||||||
|
|
|
@ -35,11 +35,12 @@ Rectangle {
|
||||||
model: [
|
model: [
|
||||||
"Radius:radius:2.0:false",
|
"Radius:radius:2.0:false",
|
||||||
"Level:obscuranceLevel:1.0:false",
|
"Level:obscuranceLevel:1.0:false",
|
||||||
"Num Taps:numSamples:32:true",
|
"Num Taps:numSamples:16:true",
|
||||||
"Taps Spiral:numSpiralTurns:10.0:false",
|
"Taps Spiral:numSpiralTurns:10.0:false",
|
||||||
"Falloff Angle:falloffAngle:0.5:false",
|
"Falloff Angle:falloffAngle:0.5:false",
|
||||||
"Blur Edge Sharpness:edgeSharpness:1.0:false",
|
"Blur Edge Sharpness:edgeSharpness:1.0:false",
|
||||||
"Blur Radius:blurRadius:15.0:false",
|
"Blur Radius:blurRadius:15.0:true",
|
||||||
|
"Resolution Downscale:resolutionLevel:2:true",
|
||||||
]
|
]
|
||||||
ConfigSlider {
|
ConfigSlider {
|
||||||
label: qsTr(modelData.split(":")[0])
|
label: qsTr(modelData.split(":")[0])
|
||||||
|
@ -57,7 +58,6 @@ Rectangle {
|
||||||
Column {
|
Column {
|
||||||
Repeater {
|
Repeater {
|
||||||
model: [
|
model: [
|
||||||
"resolutionLevel:resolutionLevel",
|
|
||||||
"ditheringEnabled:ditheringEnabled",
|
"ditheringEnabled:ditheringEnabled",
|
||||||
"fetchMipsEnabled:fetchMipsEnabled",
|
"fetchMipsEnabled:fetchMipsEnabled",
|
||||||
"borderingEnabled:borderingEnabled"
|
"borderingEnabled:borderingEnabled"
|
||||||
|
|
Loading…
Reference in a new issue