introducing the depth aware blur

This commit is contained in:
samcake 2016-06-27 17:04:37 -07:00
parent 938bc77b1f
commit 197d49fc03
12 changed files with 247 additions and 140 deletions

View file

@ -159,7 +159,7 @@ static const std::string DEFAULT_CURVATURE_SHADER{
static const std::string DEFAULT_NORMAL_CURVATURE_SHADER{ static const std::string DEFAULT_NORMAL_CURVATURE_SHADER{
"vec4 getFragmentColor() {" "vec4 getFragmentColor() {"
//" return vec4(pow(vec3(texture(curvatureMap, uv).a), vec3(1.0 / 2.2)), 1.0);" //" return vec4(pow(vec3(texture(curvatureMap, uv).a), vec3(1.0 / 2.2)), 1.0);"
" return vec4(pow(vec3(texture(curvatureMap, uv).xyz), vec3(1.0 / 2.2)), 1.0);" " return vec4(vec3(texture(curvatureMap, uv).xyz), 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);"
" }" " }"
}; };
@ -175,7 +175,7 @@ static const std::string DEFAULT_DIFFUSED_CURVATURE_SHADER{
static const std::string DEFAULT_DIFFUSED_NORMAL_CURVATURE_SHADER{ static const std::string DEFAULT_DIFFUSED_NORMAL_CURVATURE_SHADER{
"vec4 getFragmentColor() {" "vec4 getFragmentColor() {"
//" return vec4(pow(vec3(texture(curvatureMap, uv).a), vec3(1.0 / 2.2)), 1.0);" //" return vec4(pow(vec3(texture(curvatureMap, uv).a), vec3(1.0 / 2.2)), 1.0);"
" return vec4(pow(vec3(texture(diffusedCurvatureMap, uv).xyz), vec3(1.0 / 2.2)), 1.0);" " return vec4(vec3(texture(diffusedCurvatureMap, uv).xyz), 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);"
" }" " }"
}; };

View file

@ -108,7 +108,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
const auto theCurvatureVarying = curvatureFramebufferAndDepth[0]; const auto theCurvatureVarying = curvatureFramebufferAndDepth[0];
#define SIMPLE_BLUR 1 //#define SIMPLE_BLUR 1
#if SIMPLE_BLUR #if SIMPLE_BLUR
const auto curvatureFramebuffer = addJob<render::BlurGaussian>("DiffuseCurvature", curvatureFramebufferAndDepth.get<SurfaceGeometryPass::Outputs>().first); const auto curvatureFramebuffer = addJob<render::BlurGaussian>("DiffuseCurvature", curvatureFramebufferAndDepth.get<SurfaceGeometryPass::Outputs>().first);
const auto diffusedCurvatureFramebuffer = addJob<render::BlurGaussian>("DiffuseCurvature2", curvatureFramebufferAndDepth.get<SurfaceGeometryPass::Outputs>().first, true); const auto diffusedCurvatureFramebuffer = addJob<render::BlurGaussian>("DiffuseCurvature2", curvatureFramebufferAndDepth.get<SurfaceGeometryPass::Outputs>().first, true);

View file

@ -17,6 +17,7 @@
#include "DeferredLightingEffect.h" #include "DeferredLightingEffect.h"
#include "subsurfaceScattering_makeProfile_frag.h"
#include "subsurfaceScattering_makeLUT_frag.h" #include "subsurfaceScattering_makeLUT_frag.h"
#include "subsurfaceScattering_drawScattering_frag.h" #include "subsurfaceScattering_drawScattering_frag.h"
@ -85,8 +86,11 @@ bool SubsurfaceScatteringResource::isShowBRDF() const {
void SubsurfaceScatteringResource::generateScatteringTable(RenderArgs* args) { void SubsurfaceScatteringResource::generateScatteringTable(RenderArgs* args) {
if (!_scatteringProfile) {
_scatteringProfile = generateScatteringProfile(args);
}
if (!_scatteringTable) { if (!_scatteringTable) {
_scatteringTable = generatePreIntegratedScattering(args); _scatteringTable = generatePreIntegratedScattering(_scatteringProfile, args);
} }
} }
@ -102,6 +106,7 @@ void SubsurfaceScattering::configure(const Config& config) {
glm::vec2 curvatureInfo(config.curvatureOffset, config.curvatureScale); glm::vec2 curvatureInfo(config.curvatureOffset, config.curvatureScale);
_scatteringResource->setCurvatureFactors(curvatureInfo); _scatteringResource->setCurvatureFactors(curvatureInfo);
_showProfile = config.showProfile;
_showLUT = config.showLUT; _showLUT = config.showLUT;
} }
@ -208,6 +213,7 @@ void SubsurfaceScattering::run(const render::SceneContextPointer& sceneContext,
RenderArgs* args = renderContext->args; RenderArgs* args = renderContext->args;
_scatteringResource->generateScatteringTable(args); _scatteringResource->generateScatteringTable(args);
auto scatteringProfile = _scatteringResource->getScatteringProfile();
auto scatteringTable = _scatteringResource->getScatteringTable(); auto scatteringTable = _scatteringResource->getScatteringTable();
@ -227,7 +233,7 @@ void SubsurfaceScattering::run(const render::SceneContextPointer& sceneContext,
const auto theLight = DependencyManager::get<DeferredLightingEffect>()->getLightStage().lights[0]; const auto theLight = DependencyManager::get<DeferredLightingEffect>()->getLightStage().lights[0];
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false); // batch.enableStereo(false);
batch.setViewportTransform(args->_viewport); batch.setViewportTransform(args->_viewport);
@ -252,9 +258,18 @@ void SubsurfaceScattering::run(const render::SceneContextPointer& sceneContext,
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);
*/ */
if (_showLUT) {
auto viewportSize = std::min(args->_viewport.z, args->_viewport.w) >> 1; auto viewportSize = std::min(args->_viewport.z, args->_viewport.w) >> 1;
batch.setViewportTransform(glm::ivec4(0, 0, viewportSize, viewportSize)); auto offsetViewport = viewportSize * 0.1;
if (_showProfile) {
batch.setViewportTransform(glm::ivec4(0, 0, viewportSize, offsetViewport));
batch.setPipeline(getShowLUTPipeline());
batch.setResourceTexture(0, scatteringProfile);
batch.draw(gpu::TRIANGLE_STRIP, 4);
}
if (_showLUT) {
batch.setViewportTransform(glm::ivec4(0, offsetViewport * 1.5, viewportSize, viewportSize));
batch.setPipeline(getShowLUTPipeline()); batch.setPipeline(getShowLUTPipeline());
batch.setResourceTexture(0, scatteringTable); batch.setResourceTexture(0, scatteringTable);
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);
@ -267,7 +282,6 @@ void SubsurfaceScattering::run(const render::SceneContextPointer& sceneContext,
// Reference: http://www.altdevblogaday.com/2011/12/31/skin-shading-in-unity3d/ // Reference: http://www.altdevblogaday.com/2011/12/31/skin-shading-in-unity3d/
#include <cstdio> #include <cstdio>
#include <cmath> #include <cmath>
#include <algorithm> #include <algorithm>
@ -276,7 +290,6 @@ void SubsurfaceScattering::run(const render::SceneContextPointer& sceneContext,
using namespace std; using namespace std;
double gaussian(float v, float r) { double gaussian(float v, float r) {
double g = (1.0 / sqrt(2.0 * _PI * v)) * exp(-(r*r) / (2.0 * v)); double g = (1.0 / sqrt(2.0 * _PI * v)) * exp(-(r*r) / (2.0 * v));
return g; return g;
@ -385,45 +398,6 @@ void diffuseScatter(gpu::TexturePointer& lut) {
} }
void diffuseScatterGPU(gpu::TexturePointer& profileMap, gpu::TexturePointer& lut, RenderArgs* args) {
int width = lut->getWidth();
int height = lut->getHeight();
gpu::PipelinePointer makePipeline;
{
auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
auto ps = gpu::Shader::createPixel(std::string(subsurfaceScattering_makeLUT_frag));
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("profileMap"), 0));
// slotBindings.insert(gpu::Shader::Binding(std::string("sourceMap"), BlurTask_SourceSlot));
gpu::Shader::makeProgram(*program, slotBindings);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
makePipeline = gpu::Pipeline::create(program, state);
}
auto makeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
makeFramebuffer->setRenderBuffer(0, lut);
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
batch.setViewportTransform(glm::ivec4(0, 0, width, height));
batch.setFramebuffer(makeFramebuffer);
batch.setPipeline(makePipeline);
batch.setResourceTexture(0, profileMap);
batch.draw(gpu::TRIANGLE_STRIP, 4);
batch.setResourceTexture(0, nullptr);
batch.setPipeline(nullptr);
batch.setFramebuffer(nullptr);
});
}
void diffuseProfile(gpu::TexturePointer& profile) { void diffuseProfile(gpu::TexturePointer& profile) {
int width = profile->getWidth(); int width = profile->getWidth();
int height = profile->getHeight(); int height = profile->getHeight();
@ -459,15 +433,95 @@ void diffuseProfile(gpu::TexturePointer& profile) {
profile->assignStoredMip(0, gpu::Element::COLOR_RGBA_32, bytes.size(), bytes.data()); profile->assignStoredMip(0, gpu::Element::COLOR_RGBA_32, bytes.size(), bytes.data());
} }
gpu::TexturePointer SubsurfaceScatteringResource::generatePreIntegratedScattering(RenderArgs* args) { void diffuseProfileGPU(gpu::TexturePointer& profileMap, RenderArgs* args) {
int width = profileMap->getWidth();
int height = profileMap->getHeight();
auto profileMap = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 256, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); gpu::PipelinePointer makePipeline;
diffuseProfile(profileMap); {
auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
auto ps = gpu::Shader::createPixel(std::string(subsurfaceScattering_makeProfile_frag));
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
const int WIDTH = 128; gpu::Shader::BindingSet slotBindings;
const int HEIGHT = 128; //slotBindings.insert(gpu::Shader::Binding(std::string("profileMap"), 0));
auto scatteringLUT = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_SRGBA_32, WIDTH, HEIGHT, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); // slotBindings.insert(gpu::Shader::Binding(std::string("sourceMap"), BlurTask_SourceSlot));
gpu::Shader::makeProgram(*program, slotBindings);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
makePipeline = gpu::Pipeline::create(program, state);
}
auto makeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
makeFramebuffer->setRenderBuffer(0, profileMap);
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
batch.setViewportTransform(glm::ivec4(0, 0, width, height));
batch.setFramebuffer(makeFramebuffer);
batch.setPipeline(makePipeline);
batch.draw(gpu::TRIANGLE_STRIP, 4);
batch.setResourceTexture(0, nullptr);
batch.setPipeline(nullptr);
batch.setFramebuffer(nullptr);
});
}
void diffuseScatterGPU(const gpu::TexturePointer& profileMap, gpu::TexturePointer& lut, RenderArgs* args) {
int width = lut->getWidth();
int height = lut->getHeight();
gpu::PipelinePointer makePipeline;
{
auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
auto ps = gpu::Shader::createPixel(std::string(subsurfaceScattering_makeLUT_frag));
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("scatteringProfile"), 0));
// slotBindings.insert(gpu::Shader::Binding(std::string("sourceMap"), BlurTask_SourceSlot));
gpu::Shader::makeProgram(*program, slotBindings);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
makePipeline = gpu::Pipeline::create(program, state);
}
auto makeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
makeFramebuffer->setRenderBuffer(0, lut);
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
batch.setViewportTransform(glm::ivec4(0, 0, width, height));
batch.setFramebuffer(makeFramebuffer);
batch.setPipeline(makePipeline);
batch.setResourceTexture(0, profileMap);
batch.draw(gpu::TRIANGLE_STRIP, 4);
batch.setResourceTexture(0, nullptr);
batch.setPipeline(nullptr);
batch.setFramebuffer(nullptr);
});
}
gpu::TexturePointer SubsurfaceScatteringResource::generateScatteringProfile(RenderArgs* args) {
const int PROFILE_RESOLUTION = 512;
auto profileMap = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_SRGBA_32, PROFILE_RESOLUTION, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
diffuseProfileGPU(profileMap, args);
return profileMap;
}
gpu::TexturePointer SubsurfaceScatteringResource::generatePreIntegratedScattering(const gpu::TexturePointer& profile, RenderArgs* args) {
const int TABLE_RESOLUTION = 512;
auto scatteringLUT = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_SRGBA_32, TABLE_RESOLUTION, TABLE_RESOLUTION, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
//diffuseScatter(scatteringLUT); //diffuseScatter(scatteringLUT);
diffuseScatterGPU(profileMap, scatteringLUT, args); diffuseScatterGPU(profile, scatteringLUT, args);
return scatteringLUT; return scatteringLUT;
} }

View file

@ -39,10 +39,12 @@ public:
UniformBufferView getParametersBuffer() const { return _parametersBuffer; } UniformBufferView getParametersBuffer() const { return _parametersBuffer; }
gpu::TexturePointer getScatteringProfile() const { return _scatteringProfile; }
gpu::TexturePointer getScatteringTable() const { return _scatteringTable; } gpu::TexturePointer getScatteringTable() const { return _scatteringTable; }
void generateScatteringTable(RenderArgs* args); void generateScatteringTable(RenderArgs* args);
static gpu::TexturePointer generatePreIntegratedScattering(RenderArgs* args); static gpu::TexturePointer generateScatteringProfile(RenderArgs* args);
static gpu::TexturePointer generatePreIntegratedScattering(const gpu::TexturePointer& profile, RenderArgs* args);
protected: protected:
@ -62,6 +64,7 @@ protected:
gpu::TexturePointer _scatteringProfile;
gpu::TexturePointer _scatteringTable; gpu::TexturePointer _scatteringTable;
}; };
@ -80,6 +83,7 @@ class SubsurfaceScatteringConfig : public render::Job::Config {
Q_PROPERTY(float curvatureScale MEMBER curvatureScale NOTIFY dirty) Q_PROPERTY(float curvatureScale MEMBER curvatureScale NOTIFY dirty)
Q_PROPERTY(bool showProfile MEMBER showProfile NOTIFY dirty)
Q_PROPERTY(bool showLUT MEMBER showLUT NOTIFY dirty) Q_PROPERTY(bool showLUT MEMBER showLUT NOTIFY dirty)
public: public:
SubsurfaceScatteringConfig() : render::Job::Config(true) {} SubsurfaceScatteringConfig() : render::Job::Config(true) {}
@ -92,6 +96,7 @@ public:
float curvatureOffset{ 0.08f }; float curvatureOffset{ 0.08f };
float curvatureScale{ 0.8f }; float curvatureScale{ 0.8f };
bool showProfile{ true };
bool showLUT{ true }; bool showLUT{ true };
signals: signals:
@ -121,6 +126,7 @@ private:
gpu::PipelinePointer _showLUTPipeline; gpu::PipelinePointer _showLUTPipeline;
gpu::PipelinePointer getShowLUTPipeline(); gpu::PipelinePointer getShowLUTPipeline();
bool _showProfile{ false };
bool _showLUT{ false }; bool _showLUT{ false };
}; };

View file

@ -7,6 +7,95 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
<@func declareSubsurfaceScatteringProfileSource()@>
float gaussian(float v, float r) {
const float _PI = 3.14159265358979523846;
return (1.0 / sqrt(2.0 * _PI * v)) * exp(-(r*r) / (2.0 * v));
}
vec3 scatter(float r) {
// r is the distance expressed in millimeter
// returns the scatter reflectance
// Values from GPU Gems 3 "Advanced Skin Rendering".
// Originally taken from real life samples.
const vec4 profile[6] = vec4[6](
vec4(0.0064, 0.233, 0.455, 0.649),
vec4(0.0484, 0.100, 0.336, 0.344),
vec4(0.1870, 0.118, 0.198, 0.000),
vec4(0.5670, 0.113, 0.007, 0.007),
vec4(1.9900, 0.358, 0.004, 0.000),
vec4(7.4100, 0.078, 0.000, 0.000)
);
const int profileNum = 6;
vec3 ret = vec3(0.0);
for (int i = 0; i < profileNum; i++) {
float v = profile[i].x * 1.414;
float g = gaussian(v, r);
ret += g * profile[i].yzw;
}
return ret;
}
<@endfunc@>
<@func declareSubsurfaceScatteringGenerateProfileMap()@>
<$declareSubsurfaceScatteringProfileSource()$>
vec3 generateProfile(vec2 uv) {
return scatter(uv.x * 2.0);
}
<@endfunc@>
<@func declareSubsurfaceScatteringProfileMap()@>
uniform sampler2D scatteringProfile;
vec3 scatter(float r) {
return texture(scatteringProfile, vec2(r * 0.5, 0.5)).rgb;
}
<@endfunc@>
<@func declareSubsurfaceScatteringIntegrate(NumIntegrationSteps)@>
vec3 integrate(float cosTheta, float skinRadius) {
// Angle from lighting direction.
float theta = acos(cosTheta);
vec3 totalWeights = vec3(0.0);
vec3 totalLight = vec3(0.0);
const float _PI = 3.14159265358979523846;
const float step = 2.0 * _PI / <$NumIntegrationSteps$>;
float a = -(_PI);
while (a <= (_PI)) {
float sampleAngle = theta + a;
float diffuse = clamp(cos(sampleAngle), 0.0, 1.0);
//if (diffuse < 0.0) diffuse = 0.0;
//if (diffuse > 1.0) diffuse = 1.0;
// Distance.
float sampleDist = abs(2.0 * skinRadius * sin(a * 0.5));
// Profile Weight.
vec3 weights = scatter(sampleDist);
totalWeights += weights;
totalLight += diffuse * weights;
a += step;
}
vec3 result = (totalLight / totalWeights);
return clamp(result, vec3(0.0), vec3(1.0));
}
<@endfunc@>
<@func declareSubsurfaceScatteringResource()@> <@func declareSubsurfaceScatteringResource()@>

View file

@ -9,82 +9,9 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
<@include SubsurfaceScattering.slh@>
const float _PI = 3.14159265358979523846; <$declareSubsurfaceScatteringProfileSource()$>
<$declareSubsurfaceScatteringIntegrate(2000)$>
uniform sampler2D profileMap;
/*
vec3 scatter(float r) {
return texture(profileMap, vec2(2.0 * r, 0.5)).xyz;
}
*/
float gaussian(float v, float r) {
return (1.0 / sqrt(2.0 * _PI * v)) * exp(-(r*r) / (2.0 * v));
}
vec3 scatter(float r) {
// Values from GPU Gems 3 "Advanced Skin Rendering".
// Originally taken from real life samples.
vec4 profile[6] = vec4[6](
vec4(0.0064, 0.233, 0.455, 0.649),
vec4(0.0484, 0.100, 0.336, 0.344),
vec4(0.1870, 0.118, 0.198, 0.000),
vec4(0.5670, 0.113, 0.007, 0.007),
vec4(1.9900, 0.358, 0.004, 0.000),
vec4(7.4100, 0.078, 0.000, 0.000)
);
//const int profileNum = 6;
vec3 ret = vec3(0.0);
for (int i = 0; i < 6; i++) {
float v = profile[i].x * 1.414;
float g = gaussian(v, r);
ret += g * profile[i].yzw;
}
return ret;
}
vec3 integrate(float cosTheta, float skinRadius) {
// Angle from lighting direction.
float theta = acos(cosTheta);
vec3 totalWeights = vec3(0.0);
vec3 totalLight= vec3(0.0);
float a = -(_PI);
float inc = 0.1;
while (a <= (_PI)) {
float sampleAngle = theta + a;
float diffuse = clamp(cos(sampleAngle), 0.0, 1.0);
//if (diffuse < 0.0) diffuse = 0.0;
//if (diffuse > 1.0) diffuse = 1.0;
// Distance.
float sampleDist = abs(2.0 * skinRadius * sin(a * 0.5));
// Profile Weight.
vec3 weights = scatter( sampleDist);
totalWeights += weights;
totalLight += diffuse * weights;
a += inc;
}
vec3 result = (totalLight / totalWeights);
return clamp(result, vec3(0.0), vec3(1.0));
return min(sqrt(result), vec3(1.0));
return scatter(skinRadius);
}
in vec2 varTexCoord0; in vec2 varTexCoord0;
out vec4 outFragColor; out vec4 outFragColor;

View file

@ -0,0 +1,20 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// Created by Sam Gateau on 6/27/16.
// Copyright 2016 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 SubsurfaceScattering.slh@>
<$declareSubsurfaceScatteringGenerateProfileMap()$>
in vec2 varTexCoord0;
out vec4 outFragColor;
void main(void) {
outFragColor = vec4(generateProfile(varTexCoord0.xy), 1.0);
}

View file

@ -263,7 +263,7 @@ gpu::PipelinePointer BlurGaussianDepthAware::getBlurVPipeline() {
gpu::StatePointer state = gpu::StatePointer(new gpu::State()); gpu::StatePointer state = gpu::StatePointer(new gpu::State());
// Stencil test the curvature pass for objects pixels only, not the background // Stencil test the curvature pass for objects pixels only, not the background
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));
_blurVPipeline = gpu::Pipeline::create(program, state); _blurVPipeline = gpu::Pipeline::create(program, state);
} }
@ -286,7 +286,7 @@ gpu::PipelinePointer BlurGaussianDepthAware::getBlurHPipeline() {
gpu::StatePointer state = gpu::StatePointer(new gpu::State()); gpu::StatePointer state = gpu::StatePointer(new gpu::State());
// Stencil test the curvature pass for objects pixels only, not the background // Stencil test the curvature pass for objects pixels only, not the background
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));
_blurHPipeline = gpu::Pipeline::create(program, state); _blurHPipeline = gpu::Pipeline::create(program, state);
} }
@ -339,6 +339,10 @@ void BlurGaussianDepthAware::run(const SceneContextPointer& sceneContext, const
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);
batch.setFramebuffer(blurringResources.finalFramebuffer); batch.setFramebuffer(blurringResources.finalFramebuffer);
if (_inOutResources._generateOutputFramebuffer) {
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0));
}
batch.setPipeline(blurHPipeline); batch.setPipeline(blurHPipeline);
batch.setResourceTexture(BlurTask_SourceSlot, blurringResources.blurringTexture); batch.setResourceTexture(BlurTask_SourceSlot, blurringResources.blurringTexture);
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);

View file

@ -116,7 +116,7 @@ class BlurGaussianDepthAwareConfig : public BlurGaussianConfig {
public: public:
BlurGaussianDepthAwareConfig() : BlurGaussianConfig() {} BlurGaussianDepthAwareConfig() : BlurGaussianConfig() {}
float depthThreshold{ 2.0f }; float depthThreshold{ 1.0f };
signals: signals:
void dirty(); void dirty();
protected: protected:

View file

@ -62,7 +62,7 @@ vec4 pixelShaderGaussian(vec2 texcoord, vec2 direction, vec2 pixelStep) {
vec4 sampleCenter = texture(sourceMap, texcoord); vec4 sampleCenter = texture(sourceMap, texcoord);
vec2 finalStep = parameters.filterInfo.x * direction * pixelStep; vec2 finalStep = getFilterScale() * direction * pixelStep;
vec4 srcBlurred = vec4(0.0); vec4 srcBlurred = vec4(0.0);
for(int i = 0; i < NUM_TAPS; i++) { for(int i = 0; i < NUM_TAPS; i++) {
@ -99,9 +99,10 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep
float filterScale = getFilterScale(); float filterScale = getFilterScale();
float scale = distanceToProjectionWindow / sampleDepth; float scale = distanceToProjectionWindow / sampleDepth;
vec2 finalStep = filterScale * scale * direction * pixelStep; vec2 finalStep = filterScale * scale * direction * pixelStep; // *1000.0;
vec4 srcBlurred = vec4(0.0); // Accumulate the center sample
vec4 srcBlurred = gaussianDistributionCurve[0] * sampleCenter;
for(int i = 1; i < NUM_TAPS; i++) { for(int i = 1; i < NUM_TAPS; i++) {
// Fetch color and depth for current sample. // Fetch color and depth for current sample.
@ -111,7 +112,8 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep
// If the difference in depth is huge, we lerp color back. // If the difference in depth is huge, we lerp color back.
float s = clamp(depthThreshold * distanceToProjectionWindow /* * filterScale*/ * abs(srcDepth - sampleDepth), 0.0, 1.0); float s = clamp(/*depthThreshold */12.0 * distanceToProjectionWindow * filterScale * abs(srcDepth - sampleDepth), 0.0, 1.0);
// float s = clamp(depthThreshold * distanceToProjectionWindow * filterScale * abs(srcDepth - sampleDepth), 0.0, 1.0);
srcSample = mix(srcSample, sampleCenter, s); srcSample = mix(srcSample, sampleCenter, s);
// Accumulate. // Accumulate.

View file

@ -57,6 +57,11 @@ Column {
min: 0.0 min: 0.0
} }
} }
CheckBox {
text: "Scattering Profile"
checked: Render.getConfig("Scattering").showProfile
onCheckedChanged: { Render.getConfig("Scattering").showProfile = checked }
}
CheckBox { CheckBox {
text: "Scattering Table" text: "Scattering Table"
checked: Render.getConfig("Scattering").showLUT checked: Render.getConfig("Scattering").showLUT

View file

@ -38,7 +38,7 @@ Column {
onCheckedChanged: { Render.getConfig("DiffuseCurvature").enabled = checked } onCheckedChanged: { Render.getConfig("DiffuseCurvature").enabled = checked }
} }
Repeater { Repeater {
model: [ "Blur Scale:DiffuseCurvature:filterScale:2.0", "Blur Depth Threshold:DiffuseCurvature:depthThreshold:10.0", "Blur Scale2:DiffuseCurvature2:filterScale:2.0", "Blur Depth Threshold 2:DiffuseCurvature2:depthThreshold:10.0"] model: [ "Blur Scale:DiffuseCurvature:filterScale:2.0", "Blur Depth Threshold:DiffuseCurvature:depthThreshold:1.0", "Blur Scale2:DiffuseCurvature2:filterScale:2.0", "Blur Depth Threshold 2:DiffuseCurvature2:depthThreshold:1.0"]
ConfigSlider { ConfigSlider {
label: qsTr(modelData.split(":")[0]) label: qsTr(modelData.split(":")[0])
integral: false integral: false