From 9a604d0eded421fc25eb8bf8c1576a703bbf928d Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 30 Jun 2016 19:03:24 -0700 Subject: [PATCH] Bringing Beckmann specular to the lighting --- .../render-utils/src/DebugDeferredBuffer.cpp | 2 +- .../render-utils/src/DeferredBufferRead.slh | 13 ++++- .../render-utils/src/DeferredBufferWrite.slh | 2 +- .../render-utils/src/DeferredGlobalLight.slh | 55 +++++++++++++----- .../src/DeferredLightingEffect.cpp | 4 ++ .../render-utils/src/MaterialTextures.slh | 3 +- .../render-utils/src/SubsurfaceScattering.cpp | 56 ++++++++++++++++++- .../render-utils/src/SubsurfaceScattering.h | 7 +++ .../render-utils/src/SubsurfaceScattering.slh | 33 +++++++++++ .../src/directional_ambient_light.slf | 1 + .../src/directional_skybox_light.slf | 1 + ...surfaceScattering_makeSpecularBeckmann.slf | 26 +++++++++ .../utilities/render/debugToneMapping.js | 20 +++++++ .../utilities/render/subsurfaceScattering.qml | 5 ++ 14 files changed, 208 insertions(+), 20 deletions(-) create mode 100644 libraries/render-utils/src/subsurfaceScattering_makeSpecularBeckmann.slf create mode 100644 scripts/developer/utilities/render/debugToneMapping.js diff --git a/libraries/render-utils/src/DebugDeferredBuffer.cpp b/libraries/render-utils/src/DebugDeferredBuffer.cpp index 7ae9502889..ba7997c60e 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.cpp +++ b/libraries/render-utils/src/DebugDeferredBuffer.cpp @@ -114,7 +114,7 @@ static const std::string DEFAULT_LIGHTMAP_SHADER{ static const std::string DEFAULT_SCATTERING_SHADER{ "vec4 getFragmentColor() {" " 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));" " }" }; diff --git a/libraries/render-utils/src/DeferredBufferRead.slh b/libraries/render-utils/src/DeferredBufferRead.slh index cabfe001c7..7d6aead855 100644 --- a/libraries/render-utils/src/DeferredBufferRead.slh +++ b/libraries/render-utils/src/DeferredBufferRead.slh @@ -45,6 +45,7 @@ struct DeferredFragment { float roughness; vec3 emissive; int mode; + float scattering; float depthVal; }; @@ -63,8 +64,17 @@ DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) { // Diffuse color and unpack the mode and the metallicness frag.diffuse = frag.diffuseVal.xyz; + frag.scattering = 0.0; 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) { frag.metallic = 0.0; @@ -74,9 +84,6 @@ DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) { frag.metallic = 1.0; } - frag.emissive = frag.specularVal.xyz; - frag.obscurance = min(frag.specularVal.w, frag.obscurance); - return frag; } diff --git a/libraries/render-utils/src/DeferredBufferWrite.slh b/libraries/render-utils/src/DeferredBufferWrite.slh index 71236c71ad..ee90f26346 100755 --- a/libraries/render-utils/src/DeferredBufferWrite.slh +++ b/libraries/render-utils/src/DeferredBufferWrite.slh @@ -39,7 +39,7 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness } _fragColor0 = vec4(albedo, ((scattering > 0.0) ? packScatteringMetallic(metallic) : packShadedMetallic(metallic))); _fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0)); - _fragColor2 = vec4(emissive, occlusion); + _fragColor2 = vec4(((scattering > 0.0) ? vec3(scattering) : emissive), occlusion); } diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index 9860ca79ee..90abb9709a 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -117,7 +117,9 @@ vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, floa <$declareSubsurfaceScatteringResource()$> !> -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 // Transform directions to worldspace @@ -161,16 +163,22 @@ vec3 evalAmbientSphereGlobalColorScattering(mat4 invViewMat, float shadowAttenua // Specular Lighting vec3 halfDir = normalize(fragEyeDir + fragLightDir); + + 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; + //vec3 specular = power * fresnelColor * standardDiffuse; - shading = vec4(specular, (1 - fresnelColor.x)); + shading = vec4(vec3(specular), (1 - fresnelColor.x)); } + if (scatteringLevel < 0.1) { 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); @@ -243,7 +251,12 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur <$declareSubsurfaceScatteringResource()$> !> -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 // Transform directions to worldspace @@ -266,10 +279,10 @@ vec3 evalSkyboxGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, f return diffusedCurvature.xyz; return lowNormal * 0.5 + vec3(0.5); } - if (showCurvature()) { + /* if (showCurvature()) { float curvatureSigned = unpackCurvatureSigned(diffusedCurvature.w); return (curvatureSigned > 0 ? vec3(curvatureSigned, 0.0, 0.0) : vec3(0.0, 0.0, -curvatureSigned)); - } + }*/ vec3 bentNdotL = evalScatteringBentNdotL(fragNormal, midNormal, lowNormal, fragLightDir); @@ -287,25 +300,41 @@ vec3 evalSkyboxGlobalColorScattering(mat4 invViewMat, float shadowAttenuation, f // Specular Lighting 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) { 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 - // color += albedo * evalSphericalLight(getLightAmbientSphere(light), bentNormalHigh).xyz *getLightAmbientIntensity(light); + color += ambientOcclusion * albedo * evalSphericalLight(getLightAmbientSphere(light), lowNormal).xyz *getLightAmbientIntensity(light); // 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; if ( showBRDF()) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 0609191262..369466275b 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -62,6 +62,7 @@ enum DeferredShader_MapSlot { DEFERRED_BUFFER_CURVATURE_UNIT, DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT, SCATTERING_LUT_UNIT, + SCATTERING_SPECULAR_UNIT, }; enum DeferredShader_BufferSlot { 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("diffusedCurvatureMap"), DEFERRED_BUFFER_DIFFUSED_CURVATURE_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)); @@ -399,6 +401,7 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c batch.setResourceTexture(SCATTERING_LUT_UNIT, subsurfaceScatteringResource->getScatteringTable()); + batch.setResourceTexture(SCATTERING_SPECULAR_UNIT, subsurfaceScatteringResource->getScatteringSpecular()); // 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_DIFFUSED_CURVATURE_UNIT, nullptr); batch.setResourceTexture(SCATTERING_LUT_UNIT, nullptr); + batch.setResourceTexture(SCATTERING_SPECULAR_UNIT, nullptr); batch.setUniformBuffer(SCATTERING_PARAMETERS_BUFFER_SLOT, nullptr); batch.setUniformBuffer(DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT, nullptr); diff --git a/libraries/render-utils/src/MaterialTextures.slh b/libraries/render-utils/src/MaterialTextures.slh index 97f0ed6e96..ddebd16c3a 100644 --- a/libraries/render-utils/src/MaterialTextures.slh +++ b/libraries/render-utils/src/MaterialTextures.slh @@ -91,7 +91,8 @@ float fetchOcclusionMap(vec2 uv) { <@if withScattering@> uniform sampler2D scatteringMap; 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@> diff --git a/libraries/render-utils/src/SubsurfaceScattering.cpp b/libraries/render-utils/src/SubsurfaceScattering.cpp index 30b8b3f7bd..3535732f2e 100644 --- a/libraries/render-utils/src/SubsurfaceScattering.cpp +++ b/libraries/render-utils/src/SubsurfaceScattering.cpp @@ -19,6 +19,8 @@ #include "subsurfaceScattering_makeProfile_frag.h" #include "subsurfaceScattering_makeLUT_frag.h" +#include "subsurfaceScattering_makeSpecularBeckmann_frag.h" + #include "subsurfaceScattering_drawScattering_frag.h" enum ScatteringShaderBufferSlots { @@ -109,6 +111,9 @@ void SubsurfaceScatteringResource::generateScatteringTable(RenderArgs* args) { if (!_scatteringTable) { _scatteringTable = generatePreIntegratedScattering(_scatteringProfile, args); } + if (!_scatteringSpecular) { + _scatteringSpecular = generateScatteringSpecularBeckmann(args); + } } 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) { 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))); @@ -388,7 +428,12 @@ gpu::TexturePointer SubsurfaceScatteringResource::generatePreIntegratedScatterin 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() { } @@ -397,6 +442,7 @@ void DebugSubsurfaceScattering::configure(const Config& config) { _showProfile = config.showProfile; _showLUT = config.showLUT; + _showSpecularTable = config.showSpecularTable; _showCursorPixel = config.showCursorPixel; _debugCursorTexcoord = config.debugCursorTexcoord; } @@ -473,6 +519,7 @@ void DebugSubsurfaceScattering::run(const render::SceneContextPointer& sceneCont } auto scatteringProfile = scatteringResource->getScatteringProfile(); auto scatteringTable = scatteringResource->getScatteringTable(); + auto scatteringSpecular = scatteringResource->getScatteringSpecular(); auto framebufferCache = DependencyManager::get(); @@ -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); }); diff --git a/libraries/render-utils/src/SubsurfaceScattering.h b/libraries/render-utils/src/SubsurfaceScattering.h index 3446324df3..1442feeb1f 100644 --- a/libraries/render-utils/src/SubsurfaceScattering.h +++ b/libraries/render-utils/src/SubsurfaceScattering.h @@ -44,10 +44,13 @@ public: gpu::TexturePointer getScatteringProfile() const { return _scatteringProfile; } gpu::TexturePointer getScatteringTable() const { return _scatteringTable; } + gpu::TexturePointer getScatteringSpecular() const { return _scatteringSpecular; } void generateScatteringTable(RenderArgs* args); + static gpu::TexturePointer generateScatteringProfile(RenderArgs* args); static gpu::TexturePointer generatePreIntegratedScattering(const gpu::TexturePointer& profile, RenderArgs* args); + static gpu::TexturePointer generateScatteringSpecularBeckmann(RenderArgs* args); protected: @@ -74,6 +77,7 @@ protected: gpu::TexturePointer _scatteringProfile; gpu::TexturePointer _scatteringTable; + gpu::TexturePointer _scatteringSpecular; }; using SubsurfaceScatteringResourcePointer = std::shared_ptr; @@ -138,6 +142,7 @@ class DebugSubsurfaceScatteringConfig : public render::Job::Config { Q_PROPERTY(bool showProfile MEMBER showProfile 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(glm::vec2 debugCursorTexcoord MEMBER debugCursorTexcoord NOTIFY dirty) public: @@ -145,6 +150,7 @@ public: bool showProfile{ false }; bool showLUT{ false }; + bool showSpecularTable{ false }; bool showCursorPixel{ false }; glm::vec2 debugCursorTexcoord{ 0.5, 0.5 }; @@ -172,6 +178,7 @@ private: gpu::PipelinePointer getShowLUTPipeline(); bool _showProfile{ false }; bool _showLUT{ false }; + bool _showSpecularTable{ false }; bool _showCursorPixel{ false }; glm::vec2 _debugCursorTexcoord; }; diff --git a/libraries/render-utils/src/SubsurfaceScattering.slh b/libraries/render-utils/src/SubsurfaceScattering.slh index 1c2a2ace55..8b801427df 100644 --- a/libraries/render-utils/src/SubsurfaceScattering.slh +++ b/libraries/render-utils/src/SubsurfaceScattering.slh @@ -60,6 +60,39 @@ vec3 scatter(float r) { <@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)@> diff --git a/libraries/render-utils/src/directional_ambient_light.slf b/libraries/render-utils/src/directional_ambient_light.slf index 932f798a73..156ff44f69 100755 --- a/libraries/render-utils/src/directional_ambient_light.slf +++ b/libraries/render-utils/src/directional_ambient_light.slf @@ -52,6 +52,7 @@ void main(void) { frag.position.xyz, frag.normal, frag.diffuse, + frag.scattering, blurredCurvature, diffusedCurvature, frag.roughness); diff --git a/libraries/render-utils/src/directional_skybox_light.slf b/libraries/render-utils/src/directional_skybox_light.slf index 544271d20d..d019e29866 100755 --- a/libraries/render-utils/src/directional_skybox_light.slf +++ b/libraries/render-utils/src/directional_skybox_light.slf @@ -52,6 +52,7 @@ void main(void) { frag.position.xyz, frag.normal, frag.diffuse, + frag.scattering, blurredCurvature, diffusedCurvature, frag.roughness); diff --git a/libraries/render-utils/src/subsurfaceScattering_makeSpecularBeckmann.slf b/libraries/render-utils/src/subsurfaceScattering_makeSpecularBeckmann.slf new file mode 100644 index 0000000000..f10d287c35 --- /dev/null +++ b/libraries/render-utils/src/subsurfaceScattering_makeSpecularBeckmann.slf @@ -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); +} diff --git a/scripts/developer/utilities/render/debugToneMapping.js b/scripts/developer/utilities/render/debugToneMapping.js new file mode 100644 index 0000000000..ef14c24fb7 --- /dev/null +++ b/scripts/developer/utilities/render/debugToneMapping.js @@ -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(); }); + diff --git a/scripts/developer/utilities/render/subsurfaceScattering.qml b/scripts/developer/utilities/render/subsurfaceScattering.qml index db0c2b798c..47b960c98b 100644 --- a/scripts/developer/utilities/render/subsurfaceScattering.qml +++ b/scripts/developer/utilities/render/subsurfaceScattering.qml @@ -71,6 +71,11 @@ Column { checked: Render.getConfig("DebugScattering").showCursorPixel onCheckedChanged: { Render.getConfig("DebugScattering").showCursorPixel = checked } } + CheckBox { + text: "Skin Specular Beckmann" + checked: Render.getConfig("DebugScattering").showSpecularTable + onCheckedChanged: { Render.getConfig("DebugScattering").showSpecularTable = checked } + } } } }