mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 23:33:48 +02:00
introducing the depth aware blur
This commit is contained in:
parent
938bc77b1f
commit
197d49fc03
12 changed files with 247 additions and 140 deletions
|
@ -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);"
|
||||
" }"
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
||||
|
|
|
@ -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()@>
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -116,7 +116,7 @@ class BlurGaussianDepthAwareConfig : public BlurGaussianConfig {
|
|||
public:
|
||||
BlurGaussianDepthAwareConfig() : BlurGaussianConfig() {}
|
||||
|
||||
float depthThreshold{ 2.0f };
|
||||
float depthThreshold{ 1.0f };
|
||||
signals:
|
||||
void dirty();
|
||||
protected:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue