Adding the deawSCattering pass

This commit is contained in:
samcake 2016-06-09 19:13:28 -07:00
parent 75a2864845
commit 6831710efb
3 changed files with 144 additions and 22 deletions

View file

@ -16,11 +16,13 @@
#include "FramebufferCache.h"
#include "subsurfaceScattering_makeLUT_frag.h"
#include "subsurfaceScattering_drawScattering_frag.h"
const int SubsurfaceScattering_FrameTransformSlot = 0;
const int SubsurfaceScattering_ParamsSlot = 1;
const int SubsurfaceScattering_DepthMapSlot = 0;
const int SubsurfaceScattering_CurvatureMapSlot = 0;
const int SubsurfaceScattering_NormalMapSlot = 1;
const int SubsurfaceScattering_ScatteringTableSlot = 2;
SubsurfaceScattering::SubsurfaceScattering() {
Parameters parameters;
@ -39,12 +41,17 @@ void SubsurfaceScattering::configure(const Config& config) {
gpu::PipelinePointer SubsurfaceScattering::getScatteringPipeline() {
if (!_scatteringPipeline) {
auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
auto ps = gpu::StandardShaderLib::getDrawTextureOpaquePS();
// auto ps = gpu::StandardShaderLib::getDrawTextureOpaquePS();
auto ps = gpu::Shader::createPixel(std::string(subsurfaceScattering_drawScattering_frag));
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
// slotBindings.insert(gpu::Shader::Binding(std::string("blurParamsBuffer"), BlurTask_ParamsSlot));
// slotBindings.insert(gpu::Shader::Binding(std::string("sourceMap"), BlurTask_SourceSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), SubsurfaceScattering_FrameTransformSlot));
// slotBindings.insert(gpu::Shader::Binding(std::string("sourceMap"), BlurTask_SourceSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("curvatureMap"), SubsurfaceScattering_CurvatureMapSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), SubsurfaceScattering_NormalMapSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("scatteringLUT"), SubsurfaceScattering_ScatteringTableSlot));
gpu::Shader::makeProgram(*program, slotBindings);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
@ -71,25 +78,23 @@ void SubsurfaceScattering::run(const render::SceneContextPointer& sceneContext,
auto pipeline = getScatteringPipeline();
auto framebufferCache = DependencyManager::get<FramebufferCache>();
// if (curvatureFramebuffer->getRenderBuffer(0))
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
batch.setViewportTransform(args->_viewport >> 1);
/* batch.setProjectionTransform(glm::mat4());
batch.setViewTransform(Transform());
Transform model;
model.setTranslation(glm::vec3(sMin, tMin, 0.0f));
model.setScale(glm::vec3(sWidth, tHeight, 1.0f));
batch.setModelTransform(model);*/
batch.setUniformBuffer(SubsurfaceScattering_FrameTransformSlot, frameTransform->getFrameTransformBuffer());
batch.setPipeline(pipeline);
batch.setResourceTexture(0, _scatteringTable);
batch.setResourceTexture(SubsurfaceScattering_NormalMapSlot, framebufferCache->getDeferredNormalTexture());
batch.setResourceTexture(SubsurfaceScattering_CurvatureMapSlot, framebufferCache->getCurvatureTexture());
batch.setResourceTexture(SubsurfaceScattering_ScatteringTableSlot, _scatteringTable);
batch.draw(gpu::TRIANGLE_STRIP, 4);
});
}
@ -144,7 +149,7 @@ vec3 integrate(double cosTheta, double skinRadius) {
double a = -(_PI);
double inc = 0.1;
double inc = 0.01;
while (a <= (_PI)) {
double sampleAngle = theta + a;
@ -302,8 +307,8 @@ gpu::TexturePointer SubsurfaceScattering::generatePreIntegratedScattering(Render
const int WIDTH = 128;
const int HEIGHT = 128;
auto scatteringLUT = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, WIDTH, HEIGHT));
// diffuseScatter(scatteringLUT);
diffuseScatterGPU(profileMap, scatteringLUT, args);
diffuseScatter(scatteringLUT);
//diffuseScatterGPU(profileMap, scatteringLUT, args);
return scatteringLUT;
}

View file

@ -0,0 +1,114 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// Created by Sam Gateau on 6/8/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 DeferredTransform.slh@>
<$declareDeferredFrameTransform()$>
vec2 signNotZero(vec2 v) {
return vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);
}
vec3 oct_to_float32x3(in vec2 e) {
vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
if (v.z < 0) {
v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);
}
return normalize(v);
}
vec2 unorm8x3_to_snorm12x2(vec3 u) {
u *= 255.0;
u.y *= (1.0 / 16.0);
vec2 s = vec2( u.x * 16.0 + floor(u.y),
fract(u.y) * (16.0 * 256.0) + u.z);
return clamp(s * (1.0 / 2047.0) - 1.0, vec2(-1.0), vec2(1.0));
}
vec3 unpackNormal(in vec3 p) {
return oct_to_float32x3(unorm8x3_to_snorm12x2(p));
}
vec2 sideToFrameTexcoord(vec2 side, vec2 texcoordPos) {
return vec2((texcoordPos.x + side.x) * side.y, texcoordPos.y);
}
uniform sampler2D normalMap;
vec3 getRawNormal(vec2 texcoord) {
return texture(normalMap, texcoord).xyz;
}
vec3 getWorldNormal(vec2 texcoord) {
vec3 rawNormal = getRawNormal(texcoord);
return unpackNormal(rawNormal);
}
// the curvature texture
uniform sampler2D curvatureMap;
vec4 fetchCurvature(vec2 texcoord) {
return texture(curvatureMap, texcoord);
}
uniform sampler2D scatteringLUT;
vec3 fetchBRDF(float curvature, float LdotN) {
return texture(scatteringLUT, vec2(curvature, LdotN)).xyz;
}
// Scattering parameters
float normalBendFactor = 1.0f;
float normalBendR = 1.5f;
float normalBendG = 0.8f;
float normalBendB = 0.3f;
float scatterBase = 0.012f;
float scatterCurve = 0.25f;
in vec2 varTexCoord0;
out vec4 _fragColor;
void main(void) {
// DeferredTransform deferredTransform = getDeferredTransform();
// DeferredFragment frag = unpackDeferredFragment(deferredTransform, varTexCoord0);
vec3 normal = getWorldNormal(varTexCoord0);
vec4 diffusedCurvature = fetchCurvature(varTexCoord0);
// --> Calculate bent normals.
vec3 bentNormalN = normal;
vec3 bentNormalR = normalize( (diffusedCurvature.xyz - 0.5f) * 2.0f );
float curvature = abs(diffusedCurvature.w * 2 - 1) * 0.5f * scatterCurve + scatterBase;
// --> Calculate the light vector.
vec3 lightVector = normalize(vec3(-1.0f, -1.0f, -1.0f)); //normalize(lightPos - sourcePos.xyz);
// --> Optimise for skin diffusion profile.
float diffuseBlendedR = dot(normalize(mix( bentNormalN.xyz, bentNormalN, normalBendR * normalBendFactor)), lightVector);
float diffuseBlendedG = dot(normalize(mix(normal.xyz, bentNormalN, normalBendG * normalBendFactor)), lightVector);
float diffuseBlendedB = dot(normalize(mix(normal.xyz, bentNormalN, normalBendB * normalBendFactor)), lightVector);
// --> Look up the pre-integrated curvature-dependent BDRF textures
vec3 bdrfR = fetchBRDF(diffuseBlendedR, curvature);
vec3 bdrfG = fetchBRDF(diffuseBlendedG, curvature);
vec3 bdrfB = fetchBRDF(diffuseBlendedB, curvature);
vec3 bdrf = vec3( bdrfR.x, bdrfG.y, bdrfB.z);
bdrf *= bdrf;
_fragColor = vec4(vec3(bdrf.xyz), 1.0);
}

View file

@ -10,7 +10,7 @@
//
#define _PI 3.14159265358979523846
const float _PI = 3.14159265358979523846;
uniform sampler2D profileMap;
@ -25,7 +25,6 @@ vec3 integrate(float cosTheta, float skinRadius) {
float theta = acos(cosTheta);
vec3 totalWeights = vec3(0.0);
vec3 totalLight= vec3(0.0);
vec3 skinColour = vec3(1.0);
float a = -(_PI);
@ -33,7 +32,9 @@ vec3 integrate(float cosTheta, float skinRadius) {
while (a <= (_PI)) {
float sampleAngle = theta + a;
float diffuse = clamp(cos(sampleAngle), 0.0, 1.0);
float diffuse = cos(sampleAngle);
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));
@ -42,13 +43,15 @@ vec3 integrate(float cosTheta, float skinRadius) {
vec3 weights = scatter(sampleDist);
totalWeights += weights;
totalLight += diffuse * weights /** (skinColour * skinColour)*/;
totalLight += diffuse * weights;
a += inc;
}
vec3 result = sqrt(totalLight / totalWeights);
vec3 result = (totalLight / totalWeights);
return min(result, vec3(1.0));
return min(sqrt(result), vec3(1.0));
return scatter(skinRadius);
}
in vec2 varTexCoord0;
@ -56,6 +59,6 @@ out vec4 outFragColor;
void main(void) {
outFragColor = vec4(integrate(varTexCoord0.x * 2.0 - 1, 2.0 * varTexCoord0.y), 1.0);
outFragColor = vec4(integrate(varTexCoord0.x * 2.0 - 1.0, 2.0 / varTexCoord0.y), 1.0);
}