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{
"vec4 getFragmentColor() {"
//" 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);"
" }"
};
@ -175,7 +175,7 @@ static const std::string DEFAULT_DIFFUSED_CURVATURE_SHADER{
static const std::string DEFAULT_DIFFUSED_NORMAL_CURVATURE_SHADER{
"vec4 getFragmentColor() {"
//" 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);"
" }"
};

View file

@ -108,7 +108,7 @@ RenderDeferredTask::RenderDeferredTask(CullFunctor cullFunctor) {
const auto theCurvatureVarying = curvatureFramebufferAndDepth[0];
#define SIMPLE_BLUR 1
//#define SIMPLE_BLUR 1
#if SIMPLE_BLUR
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);

View file

@ -17,6 +17,7 @@
#include "DeferredLightingEffect.h"
#include "subsurfaceScattering_makeProfile_frag.h"
#include "subsurfaceScattering_makeLUT_frag.h"
#include "subsurfaceScattering_drawScattering_frag.h"
@ -85,8 +86,11 @@ bool SubsurfaceScatteringResource::isShowBRDF() const {
void SubsurfaceScatteringResource::generateScatteringTable(RenderArgs* args) {
if (!_scatteringProfile) {
_scatteringProfile = generateScatteringProfile(args);
}
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);
_scatteringResource->setCurvatureFactors(curvatureInfo);
_showProfile = config.showProfile;
_showLUT = config.showLUT;
}
@ -208,6 +213,7 @@ void SubsurfaceScattering::run(const render::SceneContextPointer& sceneContext,
RenderArgs* args = renderContext->args;
_scatteringResource->generateScatteringTable(args);
auto scatteringProfile = _scatteringResource->getScatteringProfile();
auto scatteringTable = _scatteringResource->getScatteringTable();
@ -227,7 +233,7 @@ void SubsurfaceScattering::run(const render::SceneContextPointer& sceneContext,
const auto theLight = DependencyManager::get<DeferredLightingEffect>()->getLightStage().lights[0];
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
// batch.enableStereo(false);
batch.setViewportTransform(args->_viewport);
@ -252,9 +258,18 @@ void SubsurfaceScattering::run(const render::SceneContextPointer& sceneContext,
batch.draw(gpu::TRIANGLE_STRIP, 4);
*/
auto viewportSize = std::min(args->_viewport.z, args->_viewport.w) >> 1;
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) {
auto viewportSize = std::min(args->_viewport.z, args->_viewport.w) >> 1;
batch.setViewportTransform(glm::ivec4(0, 0, viewportSize, viewportSize));
batch.setViewportTransform(glm::ivec4(0, offsetViewport * 1.5, viewportSize, viewportSize));
batch.setPipeline(getShowLUTPipeline());
batch.setResourceTexture(0, scatteringTable);
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/
#include <cstdio>
#include <cmath>
#include <algorithm>
@ -276,7 +290,6 @@ void SubsurfaceScattering::run(const render::SceneContextPointer& sceneContext,
using namespace std;
double gaussian(float v, float r) {
double g = (1.0 / sqrt(2.0 * _PI * v)) * exp(-(r*r) / (2.0 * v));
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) {
int width = profile->getWidth();
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());
}
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)));
diffuseProfile(profileMap);
gpu::PipelinePointer makePipeline;
{
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;
const int HEIGHT = 128;
auto scatteringLUT = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_SRGBA_32, WIDTH, HEIGHT, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
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, 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);
diffuseScatterGPU(profileMap, scatteringLUT, args);
diffuseScatterGPU(profile, scatteringLUT, args);
return scatteringLUT;
}

View file

@ -39,10 +39,12 @@ public:
UniformBufferView getParametersBuffer() const { return _parametersBuffer; }
gpu::TexturePointer getScatteringProfile() const { return _scatteringProfile; }
gpu::TexturePointer getScatteringTable() const { return _scatteringTable; }
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:
@ -62,6 +64,7 @@ protected:
gpu::TexturePointer _scatteringProfile;
gpu::TexturePointer _scatteringTable;
};
@ -80,6 +83,7 @@ class SubsurfaceScatteringConfig : public render::Job::Config {
Q_PROPERTY(float curvatureScale MEMBER curvatureScale NOTIFY dirty)
Q_PROPERTY(bool showProfile MEMBER showProfile NOTIFY dirty)
Q_PROPERTY(bool showLUT MEMBER showLUT NOTIFY dirty)
public:
SubsurfaceScatteringConfig() : render::Job::Config(true) {}
@ -92,6 +96,7 @@ public:
float curvatureOffset{ 0.08f };
float curvatureScale{ 0.8f };
bool showProfile{ true };
bool showLUT{ true };
signals:
@ -121,6 +126,7 @@ private:
gpu::PipelinePointer _showLUTPipeline;
gpu::PipelinePointer getShowLUTPipeline();
bool _showProfile{ 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
//
<@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()@>

View file

@ -9,82 +9,9 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
const float _PI = 3.14159265358979523846;
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);
}
<@include SubsurfaceScattering.slh@>
<$declareSubsurfaceScatteringProfileSource()$>
<$declareSubsurfaceScatteringIntegrate(2000)$>
in vec2 varTexCoord0;
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());
// 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);
}
@ -286,7 +286,7 @@ gpu::PipelinePointer BlurGaussianDepthAware::getBlurHPipeline() {
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
// 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);
}
@ -339,6 +339,10 @@ void BlurGaussianDepthAware::run(const SceneContextPointer& sceneContext, const
batch.draw(gpu::TRIANGLE_STRIP, 4);
batch.setFramebuffer(blurringResources.finalFramebuffer);
if (_inOutResources._generateOutputFramebuffer) {
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0));
}
batch.setPipeline(blurHPipeline);
batch.setResourceTexture(BlurTask_SourceSlot, blurringResources.blurringTexture);
batch.draw(gpu::TRIANGLE_STRIP, 4);

View file

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

View file

@ -62,7 +62,7 @@ vec4 pixelShaderGaussian(vec2 texcoord, vec2 direction, vec2 pixelStep) {
vec4 sampleCenter = texture(sourceMap, texcoord);
vec2 finalStep = parameters.filterInfo.x * direction * pixelStep;
vec2 finalStep = getFilterScale() * direction * pixelStep;
vec4 srcBlurred = vec4(0.0);
for(int i = 0; i < NUM_TAPS; i++) {
@ -99,9 +99,10 @@ vec4 pixelShaderGaussianDepthAware(vec2 texcoord, vec2 direction, vec2 pixelStep
float filterScale = getFilterScale();
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++) {
// 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.
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);
// Accumulate.

View file

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

View file

@ -38,7 +38,7 @@ Column {
onCheckedChanged: { Render.getConfig("DiffuseCurvature").enabled = checked }
}
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 {
label: qsTr(modelData.split(":")[0])
integral: false