Bringing Beckmann specular to the lighting

This commit is contained in:
samcake 2016-06-30 19:03:24 -07:00
parent 6425a16cbc
commit 9a604d0ede
14 changed files with 208 additions and 20 deletions

View file

@ -114,7 +114,7 @@ static const std::string DEFAULT_LIGHTMAP_SHADER{
static const std::string DEFAULT_SCATTERING_SHADER{ static const std::string DEFAULT_SCATTERING_SHADER{
"vec4 getFragmentColor() {" "vec4 getFragmentColor() {"
" DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);" " DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);"
" return (frag.mode == FRAG_MODE_SCATTERING ? vec4(vec3(1.0), 1.0) : vec4(vec3(0.0), 1.0));" " return (frag.mode == FRAG_MODE_SCATTERING ? vec4(vec3(pow(frag.scattering, 1.0 / 2.2)), 1.0) : vec4(vec3(0.0), 1.0));"
" }" " }"
}; };

View file

@ -45,6 +45,7 @@ struct DeferredFragment {
float roughness; float roughness;
vec3 emissive; vec3 emissive;
int mode; int mode;
float scattering;
float depthVal; float depthVal;
}; };
@ -63,8 +64,17 @@ DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) {
// Diffuse color and unpack the mode and the metallicness // Diffuse color and unpack the mode and the metallicness
frag.diffuse = frag.diffuseVal.xyz; frag.diffuse = frag.diffuseVal.xyz;
frag.scattering = 0.0;
unpackModeMetallic(frag.diffuseVal.w, frag.mode, frag.metallic); unpackModeMetallic(frag.diffuseVal.w, frag.mode, frag.metallic);
frag.emissive = frag.specularVal.xyz;
frag.obscurance = min(frag.specularVal.w, frag.obscurance);
if (frag.mode == FRAG_MODE_SCATTERING) {
frag.scattering = frag.emissive.x;
frag.emissive = vec3(0.0);
}
if (frag.metallic <= 0.5) { if (frag.metallic <= 0.5) {
frag.metallic = 0.0; frag.metallic = 0.0;
@ -74,9 +84,6 @@ DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) {
frag.metallic = 1.0; frag.metallic = 1.0;
} }
frag.emissive = frag.specularVal.xyz;
frag.obscurance = min(frag.specularVal.w, frag.obscurance);
return frag; return frag;
} }

View file

@ -39,7 +39,7 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness
} }
_fragColor0 = vec4(albedo, ((scattering > 0.0) ? packScatteringMetallic(metallic) : packShadedMetallic(metallic))); _fragColor0 = vec4(albedo, ((scattering > 0.0) ? packScatteringMetallic(metallic) : packShadedMetallic(metallic)));
_fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0)); _fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0));
_fragColor2 = vec4(emissive, occlusion); _fragColor2 = vec4(((scattering > 0.0) ? vec3(scattering) : emissive), occlusion);
} }

View file

@ -117,7 +117,9 @@ vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, floa
<$declareSubsurfaceScatteringResource()$> <$declareSubsurfaceScatteringResource()$>
<!<$declareEvalGlobalSpecularIrradiance(1, 0, 0)$>!> <!<$declareEvalGlobalSpecularIrradiance(1, 0, 0)$>!>
vec3 evalAmbientSphereGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec4 blurredCurvature, vec4 diffusedCurvature, float roughness) { <$declareSkinSpecularLighting()$>
vec3 evalAmbientSphereGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float scattering, vec4 blurredCurvature, vec4 diffusedCurvature, float roughness) {
// prepareGlobalLight // prepareGlobalLight
// Transform directions to worldspace // Transform directions to worldspace
@ -161,16 +163,22 @@ vec3 evalAmbientSphereGlobalColorScattering(mat4 invViewMat, float shadowAttenua
// Specular Lighting // Specular Lighting
vec3 halfDir = normalize(fragEyeDir + fragLightDir); vec3 halfDir = normalize(fragEyeDir + fragLightDir);
float specular = skinSpecular(fragNormal, fragLightDir, fragEyeDir, roughness, 1.0);
vec3 fresnelColor = fresnelSchlick(fresnel, fragLightDir, halfDir); vec3 fresnelColor = fresnelSchlick(fresnel, fragLightDir, halfDir);
float power = specularDistribution(roughness, fragNormal, halfDir); float power = specularDistribution(roughness, fragNormal, halfDir);
vec3 specular = power * fresnelColor * standardDiffuse; //vec3 specular = power * fresnelColor * standardDiffuse;
shading = vec4(specular, (1 - fresnelColor.x)); shading = vec4(vec3(specular), (1 - fresnelColor.x));
} }
if (scatteringLevel < 0.1) { if (scatteringLevel < 0.1) {
brdf = vec3(standardDiffuse); brdf = vec3(standardDiffuse);
} }
brdf = mix(vec3(standardDiffuse), brdf, scatteringLevel * scattering);
vec3 color = vec3(albedo * vec3(brdf.xyz) * shading.w + shading.rgb) * getLightColor(light) * getLightIntensity(light); vec3 color = vec3(albedo * vec3(brdf.xyz) * shading.w + shading.rgb) * getLightColor(light) * getLightIntensity(light);
@ -243,7 +251,12 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur
<$declareSubsurfaceScatteringResource()$> <$declareSubsurfaceScatteringResource()$>
<!<$declareEvalGlobalSpecularIrradiance(0, 1, 0)$>!> <!<$declareEvalGlobalSpecularIrradiance(0, 1, 0)$>!>
vec3 evalSkyboxGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec4 blurredCurvature, vec4 diffusedCurvature, float roughness) { <$declareSkinSpecularLighting()$>
float curvatureAO(in float k) {
return 1.0f - (0.0022f * k * k) + (0.0776f * k) + 0.7369;
}
vec3 evalSkyboxGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float scattering, vec4 blurredCurvature, vec4 diffusedCurvature, float roughness) {
// prepareGlobalLight // prepareGlobalLight
// Transform directions to worldspace // Transform directions to worldspace
@ -266,10 +279,10 @@ vec3 evalSkyboxGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, f
return diffusedCurvature.xyz; return diffusedCurvature.xyz;
return lowNormal * 0.5 + vec3(0.5); return lowNormal * 0.5 + vec3(0.5);
} }
if (showCurvature()) { /* if (showCurvature()) {
float curvatureSigned = unpackCurvatureSigned(diffusedCurvature.w); float curvatureSigned = unpackCurvatureSigned(diffusedCurvature.w);
return (curvatureSigned > 0 ? vec3(curvatureSigned, 0.0, 0.0) : vec3(0.0, 0.0, -curvatureSigned)); return (curvatureSigned > 0 ? vec3(curvatureSigned, 0.0, 0.0) : vec3(0.0, 0.0, -curvatureSigned));
} }*/
vec3 bentNdotL = evalScatteringBentNdotL(fragNormal, midNormal, lowNormal, fragLightDir); vec3 bentNdotL = evalScatteringBentNdotL(fragNormal, midNormal, lowNormal, fragLightDir);
@ -287,25 +300,41 @@ vec3 evalSkyboxGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, f
// Specular Lighting // Specular Lighting
vec3 halfDir = normalize(fragEyeDir + fragLightDir); vec3 halfDir = normalize(fragEyeDir + fragLightDir);
vec3 fresnelColor = fresnelSchlick(fresnel, fragLightDir,halfDir);
float power = specularDistribution(roughness, fragNormal, halfDir);
vec3 specular = power * fresnelColor * standardDiffuse;
shading = vec4(specular, (1 - fresnelColor.x)); float specular = skinSpecular(fragNormal, fragLightDir, fragEyeDir, roughness, 1.0);
vec3 fresnelColor = fresnelSchlick(fresnel, fragLightDir, halfDir);
float power = specularDistribution(roughness, fragNormal, halfDir);
//vec3 specular = power * fresnelColor * standardDiffuse;
shading = vec4(vec3(specular), (1 - fresnelColor.x));
// shading = vec4(specular, (1 - fresnelColor.x));
} }
if (scatteringLevel < 0.1) { if (scatteringLevel < 0.1) {
brdf = vec3(standardDiffuse); brdf = vec3(standardDiffuse);
} }
vec3 color = vec3(albedo * vec3(brdf.xyz) * shading.w + shading.rgb) * getLightColor(light) * getLightIntensity(light); brdf = mix(vec3(standardDiffuse), brdf, scatteringLevel * scattering);
vec3 color = vec3(albedo * vec3(brdf.xyz) * shading.w + shading.rgb) * getLightColor(light) * getLightIntensity(light);
//vec3 color = vec3(shading.rgb) * getLightColor(light) * getLightIntensity(light);
float ambientOcclusion = curvatureAO((diffusedCurvature.w * 2 - 1) * 20.0f) * 0.5f;
float ambientOcclusionHF = curvatureAO((diffusedCurvature.w * 2 - 1) * 8.0f) * 0.5f;
ambientOcclusion = min(ambientOcclusion, ambientOcclusionHF);
if (showCurvature()) {
return vec3(ambientOcclusion);
}
// Diffuse from ambient // Diffuse from ambient
// color += albedo * evalSphericalLight(getLightAmbientSphere(light), bentNormalHigh).xyz *getLightAmbientIntensity(light); color += ambientOcclusion * albedo * evalSphericalLight(getLightAmbientSphere(light), lowNormal).xyz *getLightAmbientIntensity(light);
// Specular highlight from ambient // Specular highlight from ambient
vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel, 1.0); // vec3 specularLighting = evalGlobalSpecularIrradiance(light, fragEyeDir, fragNormal, roughness, fresnel, 1.0);
// color += specularLighting; // color += specularLighting;
if ( showBRDF()) if ( showBRDF())

View file

@ -62,6 +62,7 @@ enum DeferredShader_MapSlot {
DEFERRED_BUFFER_CURVATURE_UNIT, DEFERRED_BUFFER_CURVATURE_UNIT,
DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT, DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT,
SCATTERING_LUT_UNIT, SCATTERING_LUT_UNIT,
SCATTERING_SPECULAR_UNIT,
}; };
enum DeferredShader_BufferSlot { enum DeferredShader_BufferSlot {
DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT = 0, DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT = 0,
@ -175,6 +176,7 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
slotBindings.insert(gpu::Shader::Binding(std::string("curvatureMap"), DEFERRED_BUFFER_CURVATURE_UNIT)); slotBindings.insert(gpu::Shader::Binding(std::string("curvatureMap"), DEFERRED_BUFFER_CURVATURE_UNIT));
slotBindings.insert(gpu::Shader::Binding(std::string("diffusedCurvatureMap"), DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT)); slotBindings.insert(gpu::Shader::Binding(std::string("diffusedCurvatureMap"), DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT));
slotBindings.insert(gpu::Shader::Binding(std::string("scatteringLUT"), SCATTERING_LUT_UNIT)); slotBindings.insert(gpu::Shader::Binding(std::string("scatteringLUT"), SCATTERING_LUT_UNIT));
slotBindings.insert(gpu::Shader::Binding(std::string("scatteringSpecularBeckmann"), SCATTERING_SPECULAR_UNIT));
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT));
@ -399,6 +401,7 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c
batch.setResourceTexture(SCATTERING_LUT_UNIT, subsurfaceScatteringResource->getScatteringTable()); batch.setResourceTexture(SCATTERING_LUT_UNIT, subsurfaceScatteringResource->getScatteringTable());
batch.setResourceTexture(SCATTERING_SPECULAR_UNIT, subsurfaceScatteringResource->getScatteringSpecular());
// Global directional light and ambient pass // Global directional light and ambient pass
@ -593,6 +596,7 @@ void RenderDeferredCleanup::run(const render::SceneContextPointer& sceneContext,
batch.setResourceTexture(DEFERRED_BUFFER_CURVATURE_UNIT, nullptr); batch.setResourceTexture(DEFERRED_BUFFER_CURVATURE_UNIT, nullptr);
batch.setResourceTexture(DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT, nullptr); batch.setResourceTexture(DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT, nullptr);
batch.setResourceTexture(SCATTERING_LUT_UNIT, nullptr); batch.setResourceTexture(SCATTERING_LUT_UNIT, nullptr);
batch.setResourceTexture(SCATTERING_SPECULAR_UNIT, nullptr);
batch.setUniformBuffer(SCATTERING_PARAMETERS_BUFFER_SLOT, nullptr); batch.setUniformBuffer(SCATTERING_PARAMETERS_BUFFER_SLOT, nullptr);
batch.setUniformBuffer(DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT, nullptr); batch.setUniformBuffer(DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT, nullptr);

View file

@ -91,7 +91,8 @@ float fetchOcclusionMap(vec2 uv) {
<@if withScattering@> <@if withScattering@>
uniform sampler2D scatteringMap; uniform sampler2D scatteringMap;
float fetchScatteringMap(vec2 uv) { float fetchScatteringMap(vec2 uv) {
return step(0.5, texture(scatteringMap, uv).r); // boolean scattering for now //return step(0.5, texture(scatteringMap, uv).r); // boolean scattering for now
return texture(scatteringMap, uv).r; // boolean scattering for now
} }
<@endif@> <@endif@>

View file

@ -19,6 +19,8 @@
#include "subsurfaceScattering_makeProfile_frag.h" #include "subsurfaceScattering_makeProfile_frag.h"
#include "subsurfaceScattering_makeLUT_frag.h" #include "subsurfaceScattering_makeLUT_frag.h"
#include "subsurfaceScattering_makeSpecularBeckmann_frag.h"
#include "subsurfaceScattering_drawScattering_frag.h" #include "subsurfaceScattering_drawScattering_frag.h"
enum ScatteringShaderBufferSlots { enum ScatteringShaderBufferSlots {
@ -109,6 +111,9 @@ void SubsurfaceScatteringResource::generateScatteringTable(RenderArgs* args) {
if (!_scatteringTable) { if (!_scatteringTable) {
_scatteringTable = generatePreIntegratedScattering(_scatteringProfile, args); _scatteringTable = generatePreIntegratedScattering(_scatteringProfile, args);
} }
if (!_scatteringSpecular) {
_scatteringSpecular = generateScatteringSpecularBeckmann(args);
}
} }
SubsurfaceScattering::SubsurfaceScattering() { SubsurfaceScattering::SubsurfaceScattering() {
@ -372,6 +377,41 @@ void diffuseScatterGPU(const gpu::TexturePointer& profileMap, gpu::TexturePointe
}); });
} }
void computeSpecularBeckmannGPU(gpu::TexturePointer& beckmannMap, RenderArgs* args) {
int width = beckmannMap->getWidth();
int height = beckmannMap->getHeight();
gpu::PipelinePointer makePipeline;
{
auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
auto ps = gpu::Shader::createPixel(std::string(subsurfaceScattering_makeSpecularBeckmann_frag));
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
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, beckmannMap);
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);
});
}
gpu::TexturePointer SubsurfaceScatteringResource::generateScatteringProfile(RenderArgs* args) { gpu::TexturePointer SubsurfaceScatteringResource::generateScatteringProfile(RenderArgs* args) {
const int PROFILE_RESOLUTION = 512; 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, gpu::Sampler::WRAP_CLAMP))); auto profileMap = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_SRGBA_32, PROFILE_RESOLUTION, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP)));
@ -388,7 +428,12 @@ gpu::TexturePointer SubsurfaceScatteringResource::generatePreIntegratedScatterin
return scatteringLUT; return scatteringLUT;
} }
gpu::TexturePointer SubsurfaceScatteringResource::generateScatteringSpecularBeckmann(RenderArgs* args) {
const int SPECULAR_RESOLUTION = 256;
auto beckmannMap = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32 /*gpu::Element(gpu::SCALAR, gpu::HALF, gpu::RGB)*/, SPECULAR_RESOLUTION, SPECULAR_RESOLUTION, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP)));
computeSpecularBeckmannGPU(beckmannMap, args);
return beckmannMap;
}
DebugSubsurfaceScattering::DebugSubsurfaceScattering() { DebugSubsurfaceScattering::DebugSubsurfaceScattering() {
} }
@ -397,6 +442,7 @@ void DebugSubsurfaceScattering::configure(const Config& config) {
_showProfile = config.showProfile; _showProfile = config.showProfile;
_showLUT = config.showLUT; _showLUT = config.showLUT;
_showSpecularTable = config.showSpecularTable;
_showCursorPixel = config.showCursorPixel; _showCursorPixel = config.showCursorPixel;
_debugCursorTexcoord = config.debugCursorTexcoord; _debugCursorTexcoord = config.debugCursorTexcoord;
} }
@ -473,6 +519,7 @@ void DebugSubsurfaceScattering::run(const render::SceneContextPointer& sceneCont
} }
auto scatteringProfile = scatteringResource->getScatteringProfile(); auto scatteringProfile = scatteringResource->getScatteringProfile();
auto scatteringTable = scatteringResource->getScatteringTable(); auto scatteringTable = scatteringResource->getScatteringTable();
auto scatteringSpecular = scatteringResource->getScatteringSpecular();
auto framebufferCache = DependencyManager::get<FramebufferCache>(); auto framebufferCache = DependencyManager::get<FramebufferCache>();
@ -528,6 +575,13 @@ void DebugSubsurfaceScattering::run(const render::SceneContextPointer& sceneCont
} }
} }
if (_showSpecularTable) {
batch.setViewportTransform(glm::ivec4(viewportSize + offsetViewport * 0.5, 0, viewportSize * 0.5, viewportSize * 0.5));
batch.setPipeline(getShowLUTPipeline());
batch.setResourceTexture(0, scatteringSpecular);
batch.draw(gpu::TRIANGLE_STRIP, 4);
}
batch.setViewportTransform(args->_viewport); batch.setViewportTransform(args->_viewport);
}); });

View file

@ -44,10 +44,13 @@ public:
gpu::TexturePointer getScatteringProfile() const { return _scatteringProfile; } gpu::TexturePointer getScatteringProfile() const { return _scatteringProfile; }
gpu::TexturePointer getScatteringTable() const { return _scatteringTable; } gpu::TexturePointer getScatteringTable() const { return _scatteringTable; }
gpu::TexturePointer getScatteringSpecular() const { return _scatteringSpecular; }
void generateScatteringTable(RenderArgs* args); void generateScatteringTable(RenderArgs* args);
static gpu::TexturePointer generateScatteringProfile(RenderArgs* args); static gpu::TexturePointer generateScatteringProfile(RenderArgs* args);
static gpu::TexturePointer generatePreIntegratedScattering(const gpu::TexturePointer& profile, RenderArgs* args); static gpu::TexturePointer generatePreIntegratedScattering(const gpu::TexturePointer& profile, RenderArgs* args);
static gpu::TexturePointer generateScatteringSpecularBeckmann(RenderArgs* args);
protected: protected:
@ -74,6 +77,7 @@ protected:
gpu::TexturePointer _scatteringProfile; gpu::TexturePointer _scatteringProfile;
gpu::TexturePointer _scatteringTable; gpu::TexturePointer _scatteringTable;
gpu::TexturePointer _scatteringSpecular;
}; };
using SubsurfaceScatteringResourcePointer = std::shared_ptr<SubsurfaceScatteringResource>; using SubsurfaceScatteringResourcePointer = std::shared_ptr<SubsurfaceScatteringResource>;
@ -138,6 +142,7 @@ class DebugSubsurfaceScatteringConfig : public render::Job::Config {
Q_PROPERTY(bool showProfile MEMBER showProfile 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)
Q_PROPERTY(bool showSpecularTable MEMBER showSpecularTable NOTIFY dirty)
Q_PROPERTY(bool showCursorPixel MEMBER showCursorPixel NOTIFY dirty) Q_PROPERTY(bool showCursorPixel MEMBER showCursorPixel NOTIFY dirty)
Q_PROPERTY(glm::vec2 debugCursorTexcoord MEMBER debugCursorTexcoord NOTIFY dirty) Q_PROPERTY(glm::vec2 debugCursorTexcoord MEMBER debugCursorTexcoord NOTIFY dirty)
public: public:
@ -145,6 +150,7 @@ public:
bool showProfile{ false }; bool showProfile{ false };
bool showLUT{ false }; bool showLUT{ false };
bool showSpecularTable{ false };
bool showCursorPixel{ false }; bool showCursorPixel{ false };
glm::vec2 debugCursorTexcoord{ 0.5, 0.5 }; glm::vec2 debugCursorTexcoord{ 0.5, 0.5 };
@ -172,6 +178,7 @@ private:
gpu::PipelinePointer getShowLUTPipeline(); gpu::PipelinePointer getShowLUTPipeline();
bool _showProfile{ false }; bool _showProfile{ false };
bool _showLUT{ false }; bool _showLUT{ false };
bool _showSpecularTable{ false };
bool _showCursorPixel{ false }; bool _showCursorPixel{ false };
glm::vec2 _debugCursorTexcoord; glm::vec2 _debugCursorTexcoord;
}; };

View file

@ -60,6 +60,39 @@ vec3 scatter(float r) {
<@endfunc@> <@endfunc@>
<@func declareSkinSpecularLighting()@>
uniform sampler2D scatteringSpecularBeckmann;
float fetchSpecularBeckmann(float ndoth, float roughness) {
return pow( 2.0 * texture(scatteringSpecularBeckmann, vec2(ndoth, roughness)).r, 10.0);
}
float fresnelReflectance(vec3 H, vec3 V, float Fo) {
float base = 1.0 - dot(V, H);
float exponential = pow(base, 5.0);
return exponential + Fo * (1.0 - exponential);
}
float skinSpecular(vec3 N, vec3 L, vec3 V, float roughness, float intensity) {
float result = 0.0;
float ndotl = dot(N, L);
if (ndotl > 0.0) {
vec3 h = L + V;
vec3 H = normalize(h);
float ndoth = dot(N, H);
float PH = fetchSpecularBeckmann(ndoth, roughness);
float F = fresnelReflectance(H, V, 0.028);
float frSpec = max(PH * F / dot(h, h), 0.0);
result = ndotl * intensity * frSpec;
}
return result;
}
<@endfunc@>
<@func declareSubsurfaceScatteringIntegrate(NumIntegrationSteps)@> <@func declareSubsurfaceScatteringIntegrate(NumIntegrationSteps)@>

View file

@ -52,6 +52,7 @@ void main(void) {
frag.position.xyz, frag.position.xyz,
frag.normal, frag.normal,
frag.diffuse, frag.diffuse,
frag.scattering,
blurredCurvature, blurredCurvature,
diffusedCurvature, diffusedCurvature,
frag.roughness); frag.roughness);

View file

@ -52,6 +52,7 @@ void main(void) {
frag.position.xyz, frag.position.xyz,
frag.normal, frag.normal,
frag.diffuse, frag.diffuse,
frag.scattering,
blurredCurvature, blurredCurvature,
diffusedCurvature, diffusedCurvature,
frag.roughness); frag.roughness);

View file

@ -0,0 +1,26 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// Created by Sam Gateau on 6/30/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
//
in vec2 varTexCoord0;
out vec4 outFragColor;
float specularBeckmann(float ndoth, float roughness) {
float alpha = acos(ndoth);
float ta = tan(alpha);
float val = 1.0 / (roughness * roughness * pow(ndoth, 4.0)) * exp(-(ta * ta) / (roughness * roughness));
return val;
}
void main(void) {
outFragColor = vec4(vec3(0.5 * pow( specularBeckmann(varTexCoord0.x, varTexCoord0.y), 0.1)), 1.0);
}

View file

@ -0,0 +1,20 @@
//
// debugToneMapping.js
//
// Created by Sam Gateau on 6/30/2016
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
// Set up the qml ui
var qml = Script.resolvePath('toneMapping.qml');
var window = new OverlayWindow({
title: 'Tone Mapping',
source: qml,
width: 400, height: 200,
});
window.setPosition(250, 1000);
window.closed.connect(function() { Script.stop(); });

View file

@ -71,6 +71,11 @@ Column {
checked: Render.getConfig("DebugScattering").showCursorPixel checked: Render.getConfig("DebugScattering").showCursorPixel
onCheckedChanged: { Render.getConfig("DebugScattering").showCursorPixel = checked } onCheckedChanged: { Render.getConfig("DebugScattering").showCursorPixel = checked }
} }
CheckBox {
text: "Skin Specular Beckmann"
checked: Render.getConfig("DebugScattering").showSpecularTable
onCheckedChanged: { Render.getConfig("DebugScattering").showSpecularTable = checked }
}
} }
} }
} }