mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
Can now process the AO at lower resolution in orer to gsave performances
This commit is contained in:
parent
df496b065c
commit
6f93fb3114
16 changed files with 146 additions and 67 deletions
|
@ -12,7 +12,7 @@
|
|||
Script.include("cookies.js");
|
||||
|
||||
var MENU = "Developer>Render>Debug Deferred Buffer";
|
||||
var ACTIONS = ["Off", "Diffuse", "Metallic", "Roughness", "Normal", "Depth", "Lighting", "PyramidDepth", "AmbientOcclusion", "OcclusionRaw", "OcclusionBlurred", "Custom"];
|
||||
var ACTIONS = ["Off", "Diffuse", "Metallic", "Roughness", "Normal", "Depth", "Lighting", "Shadow", "PyramidDepth", "AmbientOcclusion", "OcclusionBlurred", "Custom"];
|
||||
var SETTINGS_KEY = "EngineDebugScript.DebugMode";
|
||||
|
||||
Number.prototype.clamp = function(min, max) {
|
||||
|
@ -99,6 +99,11 @@ panel.newSlider("Tone Mapping Exposure", -10, 10,
|
|||
function() { return Render.tone.exposure; },
|
||||
function (value) { return (value); });
|
||||
|
||||
panel.newSlider("Ambient Occlusion Resolution Level", 0.0, 4.0,
|
||||
function (value) { Render.ambientOcclusion.resolutionLevel = value; },
|
||||
function() { return Render.ambientOcclusion.resolutionLevel; },
|
||||
function (value) { return (value); });
|
||||
|
||||
panel.newSlider("Ambient Occlusion Radius", 0.0, 2.0,
|
||||
function (value) { Render.ambientOcclusion.radius = value; },
|
||||
function() { return Render.ambientOcclusion.radius; },
|
||||
|
|
|
@ -197,8 +197,8 @@ const gpu::PipelinePointer& AmbientOcclusionEffect::getVBlurPipeline() {
|
|||
state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
|
||||
|
||||
// Vertical blur write just the final result Occlusion value in the alpha channel
|
||||
state->setColorWriteMask(false, false, false, true);
|
||||
|
||||
state->setColorWriteMask(true, true, true, false);
|
||||
|
||||
// Good to go add the brand new pipeline
|
||||
_vBlurPipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
@ -210,6 +210,17 @@ void AmbientOcclusionEffect::setDepthInfo(float nearZ, float farZ) {
|
|||
_frameTransformBuffer.edit<FrameTransform>()._depthInfo = glm::vec4(nearZ*farZ, farZ -nearZ, -farZ, 0.0f);
|
||||
}
|
||||
|
||||
void AmbientOcclusionEffect::setResolutionLevel(int level) {
|
||||
level = std::max(0, std::min(level, 4));
|
||||
if (level != getResolutionLevel()) {
|
||||
auto& current = _parametersBuffer.edit<Parameters>()._resolutionInfo;
|
||||
current.x = (float)level;
|
||||
|
||||
// Communicate the change to the Framebuffer cache
|
||||
DependencyManager::get<FramebufferCache>()->setAmbientOcclusionResolutionLevel(level);
|
||||
}
|
||||
}
|
||||
|
||||
void AmbientOcclusionEffect::setRadius(float radius) {
|
||||
radius = std::max(0.01f, radius);
|
||||
if (radius != getRadius()) {
|
||||
|
@ -294,7 +305,6 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
auto pyramidFBO = framebufferCache->getDepthPyramidFramebuffer();
|
||||
auto occlusionFBO = framebufferCache->getOcclusionFramebuffer();
|
||||
auto occlusionBlurredFBO = framebufferCache->getOcclusionBlurredFramebuffer();
|
||||
auto occlusionFinalFBO = framebufferCache->getDeferredFramebufferDepthColor();
|
||||
|
||||
QSize framebufferSize = framebufferCache->getFrameBufferSize();
|
||||
float sMin = args->_viewport.x / (float)framebufferSize.width();
|
||||
|
@ -302,6 +312,8 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
float tMin = args->_viewport.y / (float)framebufferSize.height();
|
||||
float tHeight = args->_viewport.w / (float)framebufferSize.height();
|
||||
|
||||
auto resolutionLevel = getResolutionLevel();
|
||||
|
||||
// Update the depth info with near and far (same for stereo)
|
||||
setDepthInfo(args->_viewFrustum->getNearClip(), args->_viewFrustum->getFarClip());
|
||||
|
||||
|
@ -367,6 +379,12 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
// Make pyramid mips
|
||||
batch.generateTextureMips(pyramidFBO->getRenderBuffer(0));
|
||||
|
||||
// Adjust Viewport for rendering resolution
|
||||
if (resolutionLevel > 0) {
|
||||
glm::ivec4 viewport(args->_viewport.x, args->_viewport.y, args->_viewport.z >> resolutionLevel, args->_viewport.w >> resolutionLevel);
|
||||
batch.setViewportTransform(viewport);
|
||||
}
|
||||
|
||||
// Occlusion pass
|
||||
batch.setFramebuffer(occlusionFBO);
|
||||
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(1.0f));
|
||||
|
@ -375,14 +393,14 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
|
|||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
batch.setResourceTexture(AmbientOcclusionEffect_PyramidMapSlot + 1, gpu::TexturePointer());
|
||||
|
||||
// Blur 1 pass
|
||||
// Blur 1st pass
|
||||
batch.setFramebuffer(occlusionBlurredFBO);
|
||||
batch.setPipeline(firstHBlurPipeline);
|
||||
batch.setResourceTexture(AmbientOcclusionEffect_OcclusionMapSlot, occlusionFBO->getRenderBuffer(0));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
// Blur 2 pass
|
||||
batch.setFramebuffer(occlusionFinalFBO);
|
||||
// Blur 2nd pass
|
||||
batch.setFramebuffer(occlusionFBO);
|
||||
batch.setPipeline(lastVBlurPipeline);
|
||||
batch.setResourceTexture(AmbientOcclusionEffect_OcclusionMapSlot, occlusionBlurredFBO->getRenderBuffer(0));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
|
|
@ -24,6 +24,9 @@ public:
|
|||
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
||||
void setResolutionLevel(int level);
|
||||
int getResolutionLevel() const { return _parametersBuffer.get<Parameters>()._resolutionInfo.x; }
|
||||
|
||||
void setRadius(float radius);
|
||||
float getRadius() const { return _parametersBuffer.get<Parameters>()._radiusInfo.x; }
|
||||
|
||||
|
@ -87,6 +90,8 @@ private:
|
|||
// Class describing the uniform buffer with all the parameters common to the AO shaders
|
||||
class Parameters {
|
||||
public:
|
||||
// Resolution info
|
||||
glm::vec4 _resolutionInfo{ 1.0, 1.0, 1.0, 1.0 };
|
||||
// radius info is { R, R^2, 1 / R^6, ObscuranceScale}
|
||||
glm::vec4 _radiusInfo{ 0.5, 0.5 * 0.5, 1.0 / (0.25 * 0.25 * 0.25), 1.0 };
|
||||
// Dithering info
|
||||
|
|
|
@ -35,8 +35,8 @@ enum Slots {
|
|||
Lighting,
|
||||
Shadow,
|
||||
Pyramid,
|
||||
OcclusionRaw,
|
||||
OcclusionBlurred
|
||||
AmbientOcclusion,
|
||||
AmbientOcclusionBlurred
|
||||
};
|
||||
|
||||
static const std::string DEFAULT_DIFFUSE_SHADER {
|
||||
|
@ -79,24 +79,19 @@ static const std::string DEFAULT_SHADOW_SHADER{
|
|||
" }"
|
||||
};
|
||||
|
||||
static const std::string DEFAULT_AMBIENT_OCCLUSION_SHADER{
|
||||
"vec4 getFragmentColor() {"
|
||||
" return vec4(vec3(texture(diffuseMap, uv).a), 1.0);"
|
||||
" }"
|
||||
};
|
||||
|
||||
static const std::string DEFAULT_PYRAMID_DEPTH_SHADER {
|
||||
"vec4 getFragmentColor() {"
|
||||
" return vec4(vec3(1.0 - texture(pyramidMap, uv).x * 0.01), 1.0);"
|
||||
//" return vec4(vec3(1.0 - textureLod(pyramidMap, uv, 3).x * 0.01), 1.0);"
|
||||
" }"
|
||||
};
|
||||
static const std::string DEFAULT_OCCLUSION_RAW_SHADER {
|
||||
|
||||
static const std::string DEFAULT_AMBIENT_OCCLUSION_SHADER{
|
||||
"vec4 getFragmentColor() {"
|
||||
" return vec4(vec3(texture(occlusionRawMap, uv).x), 1.0);"
|
||||
" return vec4(vec3(texture(occlusionMap, uv).x), 1.0);"
|
||||
" }"
|
||||
};
|
||||
static const std::string DEFAULT_OCCLUSION_BLURRED_SHADER {
|
||||
static const std::string DEFAULT_AMBIENT_OCCLUSION_BLURRED_SHADER{
|
||||
"vec4 getFragmentColor() {"
|
||||
" return vec4(vec3(texture(occlusionBlurredMap, uv).x), 1.0);"
|
||||
" }"
|
||||
|
@ -148,10 +143,8 @@ std::string DebugDeferredBuffer::getShaderSourceCode(Modes mode, std::string cus
|
|||
return DEFAULT_PYRAMID_DEPTH_SHADER;
|
||||
case AmbientOcclusionMode:
|
||||
return DEFAULT_AMBIENT_OCCLUSION_SHADER;
|
||||
case OcclusionRawMode:
|
||||
return DEFAULT_OCCLUSION_RAW_SHADER;
|
||||
case OcclusionBlurredMode:
|
||||
return DEFAULT_OCCLUSION_BLURRED_SHADER;
|
||||
case AmbientOcclusionBlurredMode:
|
||||
return DEFAULT_AMBIENT_OCCLUSION_BLURRED_SHADER;
|
||||
case CustomMode:
|
||||
return getFileContent(customFile, DEFAULT_CUSTOM_SHADER);
|
||||
}
|
||||
|
@ -201,8 +194,8 @@ const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Modes mode, std::st
|
|||
slotBindings.insert(gpu::Shader::Binding("lightingMap", Lighting));
|
||||
slotBindings.insert(gpu::Shader::Binding("shadowMapColor", Shadow));
|
||||
slotBindings.insert(gpu::Shader::Binding("pyramidMap", Pyramid));
|
||||
slotBindings.insert(gpu::Shader::Binding("occlusionRawMap", OcclusionRaw));
|
||||
slotBindings.insert(gpu::Shader::Binding("occlusionBlurredMap", OcclusionBlurred));
|
||||
slotBindings.insert(gpu::Shader::Binding("occlusionMap", AmbientOcclusion));
|
||||
slotBindings.insert(gpu::Shader::Binding("occlusionBlurredMap", AmbientOcclusionBlurred));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
auto pipeline = gpu::Pipeline::create(program, std::make_shared<gpu::State>());
|
||||
|
@ -260,8 +253,8 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
|
|||
batch.setResourceTexture(Lighting, framebufferCache->getLightingTexture());
|
||||
batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getRenderBuffer(0));
|
||||
batch.setResourceTexture(Pyramid, framebufferCache->getDepthPyramidTexture());
|
||||
batch.setResourceTexture(OcclusionRaw, framebufferCache->getOcclusionTexture());
|
||||
batch.setResourceTexture(OcclusionBlurred, framebufferCache->getOcclusionBlurredTexture());
|
||||
batch.setResourceTexture(AmbientOcclusion, framebufferCache->getOcclusionTexture());
|
||||
batch.setResourceTexture(AmbientOcclusionBlurred, framebufferCache->getOcclusionBlurredTexture());
|
||||
|
||||
const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
const glm::vec2 bottomLeft(renderContext->_deferredDebugSize.x, renderContext->_deferredDebugSize.y);
|
||||
|
|
|
@ -35,8 +35,7 @@ private:
|
|||
ShadowMode,
|
||||
PyramidDepthMode,
|
||||
AmbientOcclusionMode,
|
||||
OcclusionRawMode,
|
||||
OcclusionBlurredMode,
|
||||
AmbientOcclusionBlurredMode,
|
||||
CustomMode // Needs to stay last
|
||||
};
|
||||
struct CustomPipeline {
|
||||
|
|
|
@ -24,6 +24,9 @@ uniform sampler2D specularMap;
|
|||
// the depth texture
|
||||
uniform sampler2D depthMap;
|
||||
|
||||
// the obscurance texture
|
||||
uniform sampler2D obscuranceMap;
|
||||
|
||||
// the lighting texture
|
||||
uniform sampler2D lightingMap;
|
||||
|
||||
|
@ -82,6 +85,7 @@ DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec
|
|||
frag.normalVal = texture(normalMap, texcoord);
|
||||
frag.diffuseVal = texture(diffuseMap, texcoord);
|
||||
frag.specularVal = texture(specularMap, texcoord);
|
||||
frag.obscurance = texture(obscuranceMap, texcoord).x;
|
||||
|
||||
if (getStereoMode(deferredTransform)) {
|
||||
if (texcoord.x > 0.5) {
|
||||
|
@ -100,10 +104,10 @@ DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec
|
|||
}
|
||||
|
||||
frag.diffuse = frag.diffuseVal.xyz;
|
||||
frag.obscurance = frag.diffuseVal.w;
|
||||
frag.specular = frag.specularVal.xyz;
|
||||
frag.gloss = frag.specularVal.w;
|
||||
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,15 @@ struct LightLocations {
|
|||
int shadowTransformBuffer;
|
||||
};
|
||||
|
||||
enum {
|
||||
DEFERRED_BUFFER_COLOR_UNIT = 0,
|
||||
DEFERRED_BUFFER_NORMAL_UNIT = 1,
|
||||
DEFERRED_BUFFER_EMISSIVE_UNIT = 2,
|
||||
DEFERRED_BUFFER_DEPTH_UNIT = 3,
|
||||
DEFERRED_BUFFER_OBSCURANCE_UNIT = 4,
|
||||
SHADOW_MAP_UNIT = 5,
|
||||
SKYBOX_MAP_UNIT = 6,
|
||||
};
|
||||
static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations);
|
||||
|
||||
void DeferredLightingEffect::init() {
|
||||
|
@ -172,16 +181,17 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
|||
batch.setStateScissorRect(args->_viewport);
|
||||
|
||||
// BInd the G-Buffer surfaces
|
||||
batch.setResourceTexture(0, framebufferCache->getDeferredColorTexture());
|
||||
batch.setResourceTexture(1, framebufferCache->getDeferredNormalTexture());
|
||||
batch.setResourceTexture(2, framebufferCache->getDeferredSpecularTexture());
|
||||
batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture());
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_COLOR_UNIT, framebufferCache->getDeferredColorTexture());
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_NORMAL_UNIT, framebufferCache->getDeferredNormalTexture());
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_EMISSIVE_UNIT, framebufferCache->getDeferredSpecularTexture());
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_DEPTH_UNIT, framebufferCache->getPrimaryDepthTexture());
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_OBSCURANCE_UNIT, framebufferCache->getOcclusionTexture());
|
||||
|
||||
assert(_lightStage.lights.size() > 0);
|
||||
const auto& globalShadow = _lightStage.lights[0]->shadow;
|
||||
|
||||
// Bind the shadow buffer
|
||||
batch.setResourceTexture(4, globalShadow.map);
|
||||
batch.setResourceTexture(SHADOW_MAP_UNIT, globalShadow.map);
|
||||
|
||||
// THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport)
|
||||
auto monoViewport = args->_viewport;
|
||||
|
@ -323,7 +333,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
if (useSkyboxCubemap) {
|
||||
batch.setResourceTexture(5, _skybox->getCubemap());
|
||||
batch.setResourceTexture(SKYBOX_MAP_UNIT, _skybox->getCubemap());
|
||||
}
|
||||
|
||||
if (locations->lightBufferUnit >= 0) {
|
||||
|
@ -345,7 +355,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
if (useSkyboxCubemap) {
|
||||
batch.setResourceTexture(5, nullptr);
|
||||
batch.setResourceTexture(SKYBOX_MAP_UNIT, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -461,10 +471,14 @@ void DeferredLightingEffect::render(RenderArgs* args) {
|
|||
}
|
||||
|
||||
// Probably not necessary in the long run because the gpu layer would unbound this texture if used as render target
|
||||
batch.setResourceTexture(0, nullptr);
|
||||
batch.setResourceTexture(1, nullptr);
|
||||
batch.setResourceTexture(2, nullptr);
|
||||
batch.setResourceTexture(3, nullptr);
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_COLOR_UNIT, nullptr);
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_NORMAL_UNIT, nullptr);
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_EMISSIVE_UNIT, nullptr);
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_DEPTH_UNIT, nullptr);
|
||||
batch.setResourceTexture(DEFERRED_BUFFER_OBSCURANCE_UNIT, nullptr);
|
||||
batch.setResourceTexture(SHADOW_MAP_UNIT, nullptr);
|
||||
batch.setResourceTexture(SKYBOX_MAP_UNIT, nullptr);
|
||||
|
||||
batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, nullptr);
|
||||
});
|
||||
|
||||
|
@ -489,12 +503,13 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
|
|||
gpu::ShaderPointer program = gpu::Shader::createProgram(VS, PS);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), 0));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), 1));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), 3));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("shadowMap"), 4));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), 5));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), DEFERRED_BUFFER_COLOR_UNIT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), DEFERRED_BUFFER_NORMAL_UNIT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), DEFERRED_BUFFER_EMISSIVE_UNIT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), DEFERRED_BUFFER_DEPTH_UNIT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("obscuranceMap"), DEFERRED_BUFFER_OBSCURANCE_UNIT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("shadowMap"), SHADOW_MAP_UNIT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), SKYBOX_MAP_UNIT));
|
||||
|
||||
static const int LIGHT_GPU_SLOT = 3;
|
||||
static const int ATMOSPHERE_GPU_SLOT = 4;
|
||||
|
|
|
@ -111,17 +111,32 @@ void FramebufferCache::createPrimaryFramebuffer() {
|
|||
_depthPyramidFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
|
||||
|
||||
|
||||
_occlusionTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGB), width, height, defaultSampler));
|
||||
resizeAmbientOcclusionBuffers();
|
||||
}
|
||||
|
||||
|
||||
void FramebufferCache::resizeAmbientOcclusionBuffers() {
|
||||
_occlusionFramebuffer.reset();
|
||||
_occlusionTexture.reset();
|
||||
_occlusionBlurredFramebuffer.reset();
|
||||
_occlusionBlurredTexture.reset();
|
||||
|
||||
|
||||
auto width = _frameBufferSize.width() >> _AOResolutionLevel;
|
||||
auto height = _frameBufferSize.height() >> _AOResolutionLevel;
|
||||
auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGB);
|
||||
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_POINT_MAG_LINEAR);
|
||||
auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format
|
||||
|
||||
_occlusionTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
|
||||
_occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||
_occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture);
|
||||
_occlusionFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
|
||||
|
||||
|
||||
_occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGB), width, height, defaultSampler));
|
||||
|
||||
_occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
|
||||
_occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||
_occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture);
|
||||
_occlusionBlurredFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
|
||||
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer FramebufferCache::getPrimaryFramebuffer() {
|
||||
|
@ -230,30 +245,38 @@ gpu::TexturePointer FramebufferCache::getDepthPyramidTexture() {
|
|||
return _depthPyramidTexture;
|
||||
}
|
||||
|
||||
void FramebufferCache::setAmbientOcclusionResolutionLevel(int level) {
|
||||
level = std::max(0, std::min(level, 4));
|
||||
if (level != _AOResolutionLevel) {
|
||||
_AOResolutionLevel = level;
|
||||
resizeAmbientOcclusionBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer FramebufferCache::getOcclusionFramebuffer() {
|
||||
if (!_occlusionFramebuffer) {
|
||||
createPrimaryFramebuffer();
|
||||
resizeAmbientOcclusionBuffers();
|
||||
}
|
||||
return _occlusionFramebuffer;
|
||||
}
|
||||
|
||||
gpu::TexturePointer FramebufferCache::getOcclusionTexture() {
|
||||
if (!_occlusionTexture) {
|
||||
createPrimaryFramebuffer();
|
||||
resizeAmbientOcclusionBuffers();
|
||||
}
|
||||
return _occlusionTexture;
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer FramebufferCache::getOcclusionBlurredFramebuffer() {
|
||||
if (!_occlusionBlurredFramebuffer) {
|
||||
createPrimaryFramebuffer();
|
||||
resizeAmbientOcclusionBuffers();
|
||||
}
|
||||
return _occlusionBlurredFramebuffer;
|
||||
}
|
||||
|
||||
gpu::TexturePointer FramebufferCache::getOcclusionBlurredTexture() {
|
||||
if (!_occlusionBlurredTexture) {
|
||||
createPrimaryFramebuffer();
|
||||
resizeAmbientOcclusionBuffers();
|
||||
}
|
||||
return _occlusionBlurredTexture;
|
||||
}
|
|
@ -46,7 +46,8 @@ public:
|
|||
|
||||
gpu::FramebufferPointer getDepthPyramidFramebuffer();
|
||||
gpu::TexturePointer getDepthPyramidTexture();
|
||||
|
||||
|
||||
void setAmbientOcclusionResolutionLevel(int level);
|
||||
gpu::FramebufferPointer getOcclusionFramebuffer();
|
||||
gpu::TexturePointer getOcclusionTexture();
|
||||
gpu::FramebufferPointer getOcclusionBlurredFramebuffer();
|
||||
|
@ -102,6 +103,11 @@ private:
|
|||
gpu::TexturePointer _occlusionBlurredTexture;
|
||||
|
||||
QSize _frameBufferSize{ 100, 100 };
|
||||
int _AOResolutionLevel = 0;
|
||||
|
||||
// Resize/reallocate the buffers used for AO
|
||||
// the size of the AO buffers is scaled by the AOResolutionScale;
|
||||
void resizeAmbientOcclusionBuffers();
|
||||
};
|
||||
|
||||
#endif // hifi_FramebufferCache_h
|
||||
|
|
|
@ -172,6 +172,7 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
|
|||
setOcclusionStatus(renderContext->getOcclusionStatus());
|
||||
|
||||
if (_occlusionJobIndex >= 0) {
|
||||
_jobs[_occlusionJobIndex].edit<AmbientOcclusionEffect>().setResolutionLevel(renderContext->getAmbientOcclusion().resolutionLevel);
|
||||
_jobs[_occlusionJobIndex].edit<AmbientOcclusionEffect>().setRadius(renderContext->getAmbientOcclusion().radius);
|
||||
_jobs[_occlusionJobIndex].edit<AmbientOcclusionEffect>().setLevel(renderContext->getAmbientOcclusion().level);
|
||||
_jobs[_occlusionJobIndex].edit<AmbientOcclusionEffect>().setNumSamples(renderContext->getAmbientOcclusion().numSamples);
|
||||
|
|
|
@ -70,6 +70,7 @@ namespace RenderScripting {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_PROPERTY(int resolutionLevel MEMBER resolutionLevel)
|
||||
Q_PROPERTY(float radius MEMBER radius)
|
||||
Q_PROPERTY(float level MEMBER level)
|
||||
Q_PROPERTY(int numSamples MEMBER numSamples)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<@include DeferredBuffer.slh@>
|
||||
|
||||
uniform sampler2D pyramidMap;
|
||||
uniform sampler2D occlusionRawMap;
|
||||
uniform sampler2D occlusionMap;
|
||||
uniform sampler2D occlusionBlurredMap;
|
||||
|
||||
in vec2 uv;
|
||||
|
|
|
@ -39,6 +39,7 @@ struct AmbientOcclusionFrameTransform {
|
|||
};
|
||||
|
||||
struct AmbientOcclusionParams {
|
||||
vec4 _resolutionInfo;
|
||||
vec4 _radiusInfo;
|
||||
vec4 _ditheringInfo;
|
||||
vec4 _sampleInfo;
|
||||
|
@ -53,8 +54,13 @@ uniform ambientOcclusionParamsBuffer {
|
|||
AmbientOcclusionParams params;
|
||||
};
|
||||
|
||||
|
||||
int getResolutionLevel() {
|
||||
return int(params._resolutionInfo.x);
|
||||
}
|
||||
|
||||
vec2 getWidthHeight() {
|
||||
return frameTransform._pixelInfo.zw;
|
||||
return vec2(ivec2(frameTransform._pixelInfo.zw) >> getResolutionLevel());
|
||||
}
|
||||
float getProjScale() {
|
||||
return getWidthHeight().y * frameTransform._projection[0][1][1] * 0.5;
|
||||
|
@ -67,14 +73,16 @@ bool isStereo() {
|
|||
return frameTransform._stereoInfo.x > 0.0f;
|
||||
}
|
||||
|
||||
ivec2 getStereoSideInfo(int xPos) {
|
||||
return (xPos < frameTransform._stereoInfo.y ? ivec2(0, 0) : ivec2(1, int(frameTransform._stereoInfo.y)) );
|
||||
float getStereoSideWidth() {
|
||||
return float(int(frameTransform._stereoInfo.y) >> getResolutionLevel());
|
||||
}
|
||||
|
||||
float getStereoSideWidth() {
|
||||
return (frameTransform._stereoInfo.y);
|
||||
ivec2 getStereoSideInfo(int xPos) {
|
||||
int sideWidth = int(getStereoSideWidth());
|
||||
return (xPos < sideWidth ? ivec2(0, 0) : ivec2(1, sideWidth) );
|
||||
}
|
||||
|
||||
|
||||
float evalZeyeFromZdb(float depth) {
|
||||
return frameTransform._depthInfo.x / (depth * frameTransform._depthInfo.y + frameTransform._depthInfo.z);
|
||||
}
|
||||
|
@ -199,7 +207,7 @@ vec3 getBlurredOcclusion(vec2 coord) {
|
|||
for (int r = -blurRadius; r <= -1; ++r) {
|
||||
weightedSums += evalTapWeightedValue(r, ssC, key);
|
||||
}
|
||||
// then possitive side
|
||||
// then positive side
|
||||
for (int r = 1; r <= blurRadius; ++r) {
|
||||
weightedSums += evalTapWeightedValue(r, ssC, key);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ const int MAX_MIP_LEVEL = 5;
|
|||
uniform sampler2D pyramidMap;
|
||||
|
||||
float getZEye(ivec2 pixel) {
|
||||
return -texelFetch(pyramidMap, pixel, 0).x;
|
||||
return -texelFetch(pyramidMap, pixel, getResolutionLevel()).x;
|
||||
}
|
||||
|
||||
vec3 evalEyePositionFromZeye(ivec2 side, float Zeye, vec2 texcoord) {
|
||||
|
@ -62,8 +62,8 @@ vec3 getOffsetPosition(ivec2 side, ivec2 ssC, vec2 unitOffset, float ssR) {
|
|||
|
||||
// We need to divide by 2^mipLevel to read the appropriately scaled coordinate from a MIP-map.
|
||||
// Manually clamp to the texture size because texelFetch bypasses the texture unit
|
||||
ivec2 mipP = clamp(ssPFull >> mipLevel, ivec2(0), textureSize(pyramidMap, mipLevel) - ivec2(1));
|
||||
P.z = -texelFetch(pyramidMap, mipP, mipLevel).r;
|
||||
ivec2 mipP = clamp(ssPFull >> mipLevel, ivec2(0), textureSize(pyramidMap, getResolutionLevel() + mipLevel) - ivec2(1));
|
||||
P.z = -texelFetch(pyramidMap, mipP, getResolutionLevel() + mipLevel).r;
|
||||
// P.z = -texelFetch(pyramidMap, ssPFull, 0).r;
|
||||
|
||||
// Offset to pixel center
|
||||
|
|
|
@ -18,5 +18,5 @@ out vec4 outFragColor;
|
|||
|
||||
void main(void) {
|
||||
float occlusion = getBlurredOcclusion(gl_FragCoord.xy).x;
|
||||
outFragColor = vec4(0.0, 0.0, 0.0, occlusion);
|
||||
outFragColor = vec4(occlusion, 0.0, 0.0, occlusion);
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
|
||||
class AmbientOcclusion {
|
||||
public:
|
||||
int resolutionLevel = 0;
|
||||
float radius = 0.5f; // radius in meters of the AO effect
|
||||
float level = 0.5f; // Level of the obscrance value
|
||||
int numSamples = 11; // Num Samples per pixel
|
||||
|
|
Loading…
Reference in a new issue