Can now process the AO at lower resolution in orer to gsave performances

This commit is contained in:
samcake 2016-01-19 12:12:51 -08:00
parent df496b065c
commit 6f93fb3114
16 changed files with 146 additions and 67 deletions

View file

@ -12,7 +12,7 @@
Script.include("cookies.js"); Script.include("cookies.js");
var MENU = "Developer>Render>Debug Deferred Buffer"; 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"; var SETTINGS_KEY = "EngineDebugScript.DebugMode";
Number.prototype.clamp = function(min, max) { Number.prototype.clamp = function(min, max) {
@ -99,6 +99,11 @@ panel.newSlider("Tone Mapping Exposure", -10, 10,
function() { return Render.tone.exposure; }, function() { return Render.tone.exposure; },
function (value) { return (value); }); 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, panel.newSlider("Ambient Occlusion Radius", 0.0, 2.0,
function (value) { Render.ambientOcclusion.radius = value; }, function (value) { Render.ambientOcclusion.radius = value; },
function() { return Render.ambientOcclusion.radius; }, function() { return Render.ambientOcclusion.radius; },

View file

@ -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)); 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 // 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 // Good to go add the brand new pipeline
_vBlurPipeline = gpu::Pipeline::create(program, state); _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); _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) { void AmbientOcclusionEffect::setRadius(float radius) {
radius = std::max(0.01f, radius); radius = std::max(0.01f, radius);
if (radius != getRadius()) { if (radius != getRadius()) {
@ -294,7 +305,6 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
auto pyramidFBO = framebufferCache->getDepthPyramidFramebuffer(); auto pyramidFBO = framebufferCache->getDepthPyramidFramebuffer();
auto occlusionFBO = framebufferCache->getOcclusionFramebuffer(); auto occlusionFBO = framebufferCache->getOcclusionFramebuffer();
auto occlusionBlurredFBO = framebufferCache->getOcclusionBlurredFramebuffer(); auto occlusionBlurredFBO = framebufferCache->getOcclusionBlurredFramebuffer();
auto occlusionFinalFBO = framebufferCache->getDeferredFramebufferDepthColor();
QSize framebufferSize = framebufferCache->getFrameBufferSize(); QSize framebufferSize = framebufferCache->getFrameBufferSize();
float sMin = args->_viewport.x / (float)framebufferSize.width(); 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 tMin = args->_viewport.y / (float)framebufferSize.height();
float tHeight = args->_viewport.w / (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) // Update the depth info with near and far (same for stereo)
setDepthInfo(args->_viewFrustum->getNearClip(), args->_viewFrustum->getFarClip()); setDepthInfo(args->_viewFrustum->getNearClip(), args->_viewFrustum->getFarClip());
@ -367,6 +379,12 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext
// Make pyramid mips // Make pyramid mips
batch.generateTextureMips(pyramidFBO->getRenderBuffer(0)); 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 // Occlusion pass
batch.setFramebuffer(occlusionFBO); batch.setFramebuffer(occlusionFBO);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(1.0f)); 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.draw(gpu::TRIANGLE_STRIP, 4);
batch.setResourceTexture(AmbientOcclusionEffect_PyramidMapSlot + 1, gpu::TexturePointer()); batch.setResourceTexture(AmbientOcclusionEffect_PyramidMapSlot + 1, gpu::TexturePointer());
// Blur 1 pass // Blur 1st pass
batch.setFramebuffer(occlusionBlurredFBO); batch.setFramebuffer(occlusionBlurredFBO);
batch.setPipeline(firstHBlurPipeline); batch.setPipeline(firstHBlurPipeline);
batch.setResourceTexture(AmbientOcclusionEffect_OcclusionMapSlot, occlusionFBO->getRenderBuffer(0)); batch.setResourceTexture(AmbientOcclusionEffect_OcclusionMapSlot, occlusionFBO->getRenderBuffer(0));
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);
// Blur 2 pass // Blur 2nd pass
batch.setFramebuffer(occlusionFinalFBO); batch.setFramebuffer(occlusionFBO);
batch.setPipeline(lastVBlurPipeline); batch.setPipeline(lastVBlurPipeline);
batch.setResourceTexture(AmbientOcclusionEffect_OcclusionMapSlot, occlusionBlurredFBO->getRenderBuffer(0)); batch.setResourceTexture(AmbientOcclusionEffect_OcclusionMapSlot, occlusionBlurredFBO->getRenderBuffer(0));
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);

View file

@ -24,6 +24,9 @@ public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); 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); void setRadius(float radius);
float getRadius() const { return _parametersBuffer.get<Parameters>()._radiusInfo.x; } 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 describing the uniform buffer with all the parameters common to the AO shaders
class Parameters { class Parameters {
public: public:
// Resolution info
glm::vec4 _resolutionInfo{ 1.0, 1.0, 1.0, 1.0 };
// radius info is { R, R^2, 1 / R^6, ObscuranceScale} // 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 }; glm::vec4 _radiusInfo{ 0.5, 0.5 * 0.5, 1.0 / (0.25 * 0.25 * 0.25), 1.0 };
// Dithering info // Dithering info

View file

@ -35,8 +35,8 @@ enum Slots {
Lighting, Lighting,
Shadow, Shadow,
Pyramid, Pyramid,
OcclusionRaw, AmbientOcclusion,
OcclusionBlurred AmbientOcclusionBlurred
}; };
static const std::string DEFAULT_DIFFUSE_SHADER { 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 { static const std::string DEFAULT_PYRAMID_DEPTH_SHADER {
"vec4 getFragmentColor() {" "vec4 getFragmentColor() {"
" return vec4(vec3(1.0 - texture(pyramidMap, uv).x * 0.01), 1.0);" " 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);" //" 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() {" "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() {" "vec4 getFragmentColor() {"
" return vec4(vec3(texture(occlusionBlurredMap, uv).x), 1.0);" " 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; return DEFAULT_PYRAMID_DEPTH_SHADER;
case AmbientOcclusionMode: case AmbientOcclusionMode:
return DEFAULT_AMBIENT_OCCLUSION_SHADER; return DEFAULT_AMBIENT_OCCLUSION_SHADER;
case OcclusionRawMode: case AmbientOcclusionBlurredMode:
return DEFAULT_OCCLUSION_RAW_SHADER; return DEFAULT_AMBIENT_OCCLUSION_BLURRED_SHADER;
case OcclusionBlurredMode:
return DEFAULT_OCCLUSION_BLURRED_SHADER;
case CustomMode: case CustomMode:
return getFileContent(customFile, DEFAULT_CUSTOM_SHADER); 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("lightingMap", Lighting));
slotBindings.insert(gpu::Shader::Binding("shadowMapColor", Shadow)); slotBindings.insert(gpu::Shader::Binding("shadowMapColor", Shadow));
slotBindings.insert(gpu::Shader::Binding("pyramidMap", Pyramid)); slotBindings.insert(gpu::Shader::Binding("pyramidMap", Pyramid));
slotBindings.insert(gpu::Shader::Binding("occlusionRawMap", OcclusionRaw)); slotBindings.insert(gpu::Shader::Binding("occlusionMap", AmbientOcclusion));
slotBindings.insert(gpu::Shader::Binding("occlusionBlurredMap", OcclusionBlurred)); slotBindings.insert(gpu::Shader::Binding("occlusionBlurredMap", AmbientOcclusionBlurred));
gpu::Shader::makeProgram(*program, slotBindings); gpu::Shader::makeProgram(*program, slotBindings);
auto pipeline = gpu::Pipeline::create(program, std::make_shared<gpu::State>()); 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(Lighting, framebufferCache->getLightingTexture());
batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getRenderBuffer(0)); batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getRenderBuffer(0));
batch.setResourceTexture(Pyramid, framebufferCache->getDepthPyramidTexture()); batch.setResourceTexture(Pyramid, framebufferCache->getDepthPyramidTexture());
batch.setResourceTexture(OcclusionRaw, framebufferCache->getOcclusionTexture()); batch.setResourceTexture(AmbientOcclusion, framebufferCache->getOcclusionTexture());
batch.setResourceTexture(OcclusionBlurred, framebufferCache->getOcclusionBlurredTexture()); batch.setResourceTexture(AmbientOcclusionBlurred, framebufferCache->getOcclusionBlurredTexture());
const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
const glm::vec2 bottomLeft(renderContext->_deferredDebugSize.x, renderContext->_deferredDebugSize.y); const glm::vec2 bottomLeft(renderContext->_deferredDebugSize.x, renderContext->_deferredDebugSize.y);

View file

@ -35,8 +35,7 @@ private:
ShadowMode, ShadowMode,
PyramidDepthMode, PyramidDepthMode,
AmbientOcclusionMode, AmbientOcclusionMode,
OcclusionRawMode, AmbientOcclusionBlurredMode,
OcclusionBlurredMode,
CustomMode // Needs to stay last CustomMode // Needs to stay last
}; };
struct CustomPipeline { struct CustomPipeline {

View file

@ -24,6 +24,9 @@ uniform sampler2D specularMap;
// the depth texture // the depth texture
uniform sampler2D depthMap; uniform sampler2D depthMap;
// the obscurance texture
uniform sampler2D obscuranceMap;
// the lighting texture // the lighting texture
uniform sampler2D lightingMap; uniform sampler2D lightingMap;
@ -82,6 +85,7 @@ DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec
frag.normalVal = texture(normalMap, texcoord); frag.normalVal = texture(normalMap, texcoord);
frag.diffuseVal = texture(diffuseMap, texcoord); frag.diffuseVal = texture(diffuseMap, texcoord);
frag.specularVal = texture(specularMap, texcoord); frag.specularVal = texture(specularMap, texcoord);
frag.obscurance = texture(obscuranceMap, texcoord).x;
if (getStereoMode(deferredTransform)) { if (getStereoMode(deferredTransform)) {
if (texcoord.x > 0.5) { if (texcoord.x > 0.5) {
@ -100,10 +104,10 @@ DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec
} }
frag.diffuse = frag.diffuseVal.xyz; frag.diffuse = frag.diffuseVal.xyz;
frag.obscurance = frag.diffuseVal.w;
frag.specular = frag.specularVal.xyz; frag.specular = frag.specularVal.xyz;
frag.gloss = frag.specularVal.w; frag.gloss = frag.specularVal.w;
return frag; return frag;
} }

View file

@ -49,6 +49,15 @@ struct LightLocations {
int shadowTransformBuffer; 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); static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations);
void DeferredLightingEffect::init() { void DeferredLightingEffect::init() {
@ -172,16 +181,17 @@ void DeferredLightingEffect::render(RenderArgs* args) {
batch.setStateScissorRect(args->_viewport); batch.setStateScissorRect(args->_viewport);
// BInd the G-Buffer surfaces // BInd the G-Buffer surfaces
batch.setResourceTexture(0, framebufferCache->getDeferredColorTexture()); batch.setResourceTexture(DEFERRED_BUFFER_COLOR_UNIT, framebufferCache->getDeferredColorTexture());
batch.setResourceTexture(1, framebufferCache->getDeferredNormalTexture()); batch.setResourceTexture(DEFERRED_BUFFER_NORMAL_UNIT, framebufferCache->getDeferredNormalTexture());
batch.setResourceTexture(2, framebufferCache->getDeferredSpecularTexture()); batch.setResourceTexture(DEFERRED_BUFFER_EMISSIVE_UNIT, framebufferCache->getDeferredSpecularTexture());
batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture()); batch.setResourceTexture(DEFERRED_BUFFER_DEPTH_UNIT, framebufferCache->getPrimaryDepthTexture());
batch.setResourceTexture(DEFERRED_BUFFER_OBSCURANCE_UNIT, framebufferCache->getOcclusionTexture());
assert(_lightStage.lights.size() > 0); assert(_lightStage.lights.size() > 0);
const auto& globalShadow = _lightStage.lights[0]->shadow; const auto& globalShadow = _lightStage.lights[0]->shadow;
// Bind the shadow buffer // 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) // 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; auto monoViewport = args->_viewport;
@ -323,7 +333,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
} }
if (useSkyboxCubemap) { if (useSkyboxCubemap) {
batch.setResourceTexture(5, _skybox->getCubemap()); batch.setResourceTexture(SKYBOX_MAP_UNIT, _skybox->getCubemap());
} }
if (locations->lightBufferUnit >= 0) { if (locations->lightBufferUnit >= 0) {
@ -345,7 +355,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
} }
if (useSkyboxCubemap) { 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 // 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(DEFERRED_BUFFER_COLOR_UNIT, nullptr);
batch.setResourceTexture(1, nullptr); batch.setResourceTexture(DEFERRED_BUFFER_NORMAL_UNIT, nullptr);
batch.setResourceTexture(2, nullptr); batch.setResourceTexture(DEFERRED_BUFFER_EMISSIVE_UNIT, nullptr);
batch.setResourceTexture(3, 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); 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::ShaderPointer program = gpu::Shader::createProgram(VS, PS);
gpu::Shader::BindingSet slotBindings; gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), 0)); slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), DEFERRED_BUFFER_COLOR_UNIT));
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), 1)); slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), DEFERRED_BUFFER_NORMAL_UNIT));
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2)); slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), DEFERRED_BUFFER_EMISSIVE_UNIT));
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), 3)); slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), DEFERRED_BUFFER_DEPTH_UNIT));
slotBindings.insert(gpu::Shader::Binding(std::string("shadowMap"), 4)); slotBindings.insert(gpu::Shader::Binding(std::string("obscuranceMap"), DEFERRED_BUFFER_OBSCURANCE_UNIT));
slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), 5)); 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 LIGHT_GPU_SLOT = 3;
static const int ATMOSPHERE_GPU_SLOT = 4; static const int ATMOSPHERE_GPU_SLOT = 4;

View file

@ -111,17 +111,32 @@ void FramebufferCache::createPrimaryFramebuffer() {
_depthPyramidFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); _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 = gpu::FramebufferPointer(gpu::Framebuffer::create());
_occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture); _occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture);
_occlusionFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); _occlusionFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
_occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGB), width, height, defaultSampler));
_occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); _occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
_occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture); _occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture);
_occlusionBlurredFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); _occlusionBlurredFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
} }
gpu::FramebufferPointer FramebufferCache::getPrimaryFramebuffer() { gpu::FramebufferPointer FramebufferCache::getPrimaryFramebuffer() {
@ -230,30 +245,38 @@ gpu::TexturePointer FramebufferCache::getDepthPyramidTexture() {
return _depthPyramidTexture; 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() { gpu::FramebufferPointer FramebufferCache::getOcclusionFramebuffer() {
if (!_occlusionFramebuffer) { if (!_occlusionFramebuffer) {
createPrimaryFramebuffer(); resizeAmbientOcclusionBuffers();
} }
return _occlusionFramebuffer; return _occlusionFramebuffer;
} }
gpu::TexturePointer FramebufferCache::getOcclusionTexture() { gpu::TexturePointer FramebufferCache::getOcclusionTexture() {
if (!_occlusionTexture) { if (!_occlusionTexture) {
createPrimaryFramebuffer(); resizeAmbientOcclusionBuffers();
} }
return _occlusionTexture; return _occlusionTexture;
} }
gpu::FramebufferPointer FramebufferCache::getOcclusionBlurredFramebuffer() { gpu::FramebufferPointer FramebufferCache::getOcclusionBlurredFramebuffer() {
if (!_occlusionBlurredFramebuffer) { if (!_occlusionBlurredFramebuffer) {
createPrimaryFramebuffer(); resizeAmbientOcclusionBuffers();
} }
return _occlusionBlurredFramebuffer; return _occlusionBlurredFramebuffer;
} }
gpu::TexturePointer FramebufferCache::getOcclusionBlurredTexture() { gpu::TexturePointer FramebufferCache::getOcclusionBlurredTexture() {
if (!_occlusionBlurredTexture) { if (!_occlusionBlurredTexture) {
createPrimaryFramebuffer(); resizeAmbientOcclusionBuffers();
} }
return _occlusionBlurredTexture; return _occlusionBlurredTexture;
} }

View file

@ -46,7 +46,8 @@ public:
gpu::FramebufferPointer getDepthPyramidFramebuffer(); gpu::FramebufferPointer getDepthPyramidFramebuffer();
gpu::TexturePointer getDepthPyramidTexture(); gpu::TexturePointer getDepthPyramidTexture();
void setAmbientOcclusionResolutionLevel(int level);
gpu::FramebufferPointer getOcclusionFramebuffer(); gpu::FramebufferPointer getOcclusionFramebuffer();
gpu::TexturePointer getOcclusionTexture(); gpu::TexturePointer getOcclusionTexture();
gpu::FramebufferPointer getOcclusionBlurredFramebuffer(); gpu::FramebufferPointer getOcclusionBlurredFramebuffer();
@ -102,6 +103,11 @@ private:
gpu::TexturePointer _occlusionBlurredTexture; gpu::TexturePointer _occlusionBlurredTexture;
QSize _frameBufferSize{ 100, 100 }; 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 #endif // hifi_FramebufferCache_h

View file

@ -172,6 +172,7 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
setOcclusionStatus(renderContext->getOcclusionStatus()); setOcclusionStatus(renderContext->getOcclusionStatus());
if (_occlusionJobIndex >= 0) { if (_occlusionJobIndex >= 0) {
_jobs[_occlusionJobIndex].edit<AmbientOcclusionEffect>().setResolutionLevel(renderContext->getAmbientOcclusion().resolutionLevel);
_jobs[_occlusionJobIndex].edit<AmbientOcclusionEffect>().setRadius(renderContext->getAmbientOcclusion().radius); _jobs[_occlusionJobIndex].edit<AmbientOcclusionEffect>().setRadius(renderContext->getAmbientOcclusion().radius);
_jobs[_occlusionJobIndex].edit<AmbientOcclusionEffect>().setLevel(renderContext->getAmbientOcclusion().level); _jobs[_occlusionJobIndex].edit<AmbientOcclusionEffect>().setLevel(renderContext->getAmbientOcclusion().level);
_jobs[_occlusionJobIndex].edit<AmbientOcclusionEffect>().setNumSamples(renderContext->getAmbientOcclusion().numSamples); _jobs[_occlusionJobIndex].edit<AmbientOcclusionEffect>().setNumSamples(renderContext->getAmbientOcclusion().numSamples);

View file

@ -70,6 +70,7 @@ namespace RenderScripting {
Q_OBJECT Q_OBJECT
public: public:
Q_PROPERTY(int resolutionLevel MEMBER resolutionLevel)
Q_PROPERTY(float radius MEMBER radius) Q_PROPERTY(float radius MEMBER radius)
Q_PROPERTY(float level MEMBER level) Q_PROPERTY(float level MEMBER level)
Q_PROPERTY(int numSamples MEMBER numSamples) Q_PROPERTY(int numSamples MEMBER numSamples)

View file

@ -15,7 +15,7 @@
<@include DeferredBuffer.slh@> <@include DeferredBuffer.slh@>
uniform sampler2D pyramidMap; uniform sampler2D pyramidMap;
uniform sampler2D occlusionRawMap; uniform sampler2D occlusionMap;
uniform sampler2D occlusionBlurredMap; uniform sampler2D occlusionBlurredMap;
in vec2 uv; in vec2 uv;

View file

@ -39,6 +39,7 @@ struct AmbientOcclusionFrameTransform {
}; };
struct AmbientOcclusionParams { struct AmbientOcclusionParams {
vec4 _resolutionInfo;
vec4 _radiusInfo; vec4 _radiusInfo;
vec4 _ditheringInfo; vec4 _ditheringInfo;
vec4 _sampleInfo; vec4 _sampleInfo;
@ -53,8 +54,13 @@ uniform ambientOcclusionParamsBuffer {
AmbientOcclusionParams params; AmbientOcclusionParams params;
}; };
int getResolutionLevel() {
return int(params._resolutionInfo.x);
}
vec2 getWidthHeight() { vec2 getWidthHeight() {
return frameTransform._pixelInfo.zw; return vec2(ivec2(frameTransform._pixelInfo.zw) >> getResolutionLevel());
} }
float getProjScale() { float getProjScale() {
return getWidthHeight().y * frameTransform._projection[0][1][1] * 0.5; return getWidthHeight().y * frameTransform._projection[0][1][1] * 0.5;
@ -67,14 +73,16 @@ bool isStereo() {
return frameTransform._stereoInfo.x > 0.0f; return frameTransform._stereoInfo.x > 0.0f;
} }
ivec2 getStereoSideInfo(int xPos) { float getStereoSideWidth() {
return (xPos < frameTransform._stereoInfo.y ? ivec2(0, 0) : ivec2(1, int(frameTransform._stereoInfo.y)) ); return float(int(frameTransform._stereoInfo.y) >> getResolutionLevel());
} }
float getStereoSideWidth() { ivec2 getStereoSideInfo(int xPos) {
return (frameTransform._stereoInfo.y); int sideWidth = int(getStereoSideWidth());
return (xPos < sideWidth ? ivec2(0, 0) : ivec2(1, sideWidth) );
} }
float evalZeyeFromZdb(float depth) { float evalZeyeFromZdb(float depth) {
return frameTransform._depthInfo.x / (depth * frameTransform._depthInfo.y + frameTransform._depthInfo.z); 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) { for (int r = -blurRadius; r <= -1; ++r) {
weightedSums += evalTapWeightedValue(r, ssC, key); weightedSums += evalTapWeightedValue(r, ssC, key);
} }
// then possitive side // then positive side
for (int r = 1; r <= blurRadius; ++r) { for (int r = 1; r <= blurRadius; ++r) {
weightedSums += evalTapWeightedValue(r, ssC, key); weightedSums += evalTapWeightedValue(r, ssC, key);
} }

View file

@ -21,7 +21,7 @@ const int MAX_MIP_LEVEL = 5;
uniform sampler2D pyramidMap; uniform sampler2D pyramidMap;
float getZEye(ivec2 pixel) { float getZEye(ivec2 pixel) {
return -texelFetch(pyramidMap, pixel, 0).x; return -texelFetch(pyramidMap, pixel, getResolutionLevel()).x;
} }
vec3 evalEyePositionFromZeye(ivec2 side, float Zeye, vec2 texcoord) { 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. // 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 // Manually clamp to the texture size because texelFetch bypasses the texture unit
ivec2 mipP = clamp(ssPFull >> mipLevel, ivec2(0), textureSize(pyramidMap, mipLevel) - ivec2(1)); ivec2 mipP = clamp(ssPFull >> mipLevel, ivec2(0), textureSize(pyramidMap, getResolutionLevel() + mipLevel) - ivec2(1));
P.z = -texelFetch(pyramidMap, mipP, mipLevel).r; P.z = -texelFetch(pyramidMap, mipP, getResolutionLevel() + mipLevel).r;
// P.z = -texelFetch(pyramidMap, ssPFull, 0).r; // P.z = -texelFetch(pyramidMap, ssPFull, 0).r;
// Offset to pixel center // Offset to pixel center

View file

@ -18,5 +18,5 @@ out vec4 outFragColor;
void main(void) { void main(void) {
float occlusion = getBlurredOcclusion(gl_FragCoord.xy).x; float occlusion = getBlurredOcclusion(gl_FragCoord.xy).x;
outFragColor = vec4(0.0, 0.0, 0.0, occlusion); outFragColor = vec4(occlusion, 0.0, 0.0, occlusion);
} }

View file

@ -74,6 +74,7 @@ public:
class AmbientOcclusion { class AmbientOcclusion {
public: public:
int resolutionLevel = 0;
float radius = 0.5f; // radius in meters of the AO effect float radius = 0.5f; // radius in meters of the AO effect
float level = 0.5f; // Level of the obscrance value float level = 0.5f; // Level of the obscrance value
int numSamples = 11; // Num Samples per pixel int numSamples = 11; // Num Samples per pixel