diff --git a/libraries/model/src/model/Light.slh b/libraries/model/src/model/Light.slh index 7cb745ff53..5e9d3d30c0 100644 --- a/libraries/model/src/model/Light.slh +++ b/libraries/model/src/model/Light.slh @@ -126,28 +126,48 @@ float getLightAmbientMapNumMips(Light l) { } -<@if GPU_FEATURE_PROFILE == GPU_CORE @> uniform lightBuffer { Light light; }; Light getLight() { return light; } -<@else@> -uniform vec4 lightBuffer[7]; -Light getLight() { - Light light; - light._position = lightBuffer[0]; - light._direction = lightBuffer[1]; - light._color = lightBuffer[2]; - light._attenuation = lightBuffer[3]; - light._spot = lightBuffer[4]; - light._shadow = lightBuffer[5]; - light._control = lightBuffer[6]; - return light; + + + +bool clipFragToLightVolumePoint(Light light, vec3 fragPos, out vec4 fragLightVecLen2) { + fragLightVecLen2.xyz = getLightPosition(light) - fragPos.xyz; + fragLightVecLen2.w = dot(fragLightVecLen2.xyz, fragLightVecLen2.xyz); + + // Kill if too far from the light center + if (fragLightVecLen2.w > getLightCutoffSquareRadius(light)) { + return false; + } + return true; +} + +bool clipFragToLightVolumeSpot(Light light, vec3 fragPos, out vec4 fragLightVecLen2, out vec4 fragLightDirLen, out float cosSpotAngle) { + fragLightVecLen2.xyz = getLightPosition(light) - fragPos.xyz; + fragLightVecLen2.w = dot(fragLightVecLen2.xyz, fragLightVecLen2.xyz); + + // Kill if too far from the light center + if (fragLightVecLen2.w > getLightCutoffSquareRadius(light)) { + return false; + } + + // Allright we re valid in the volume + fragLightDirLen.w = length(fragLightVecLen2.xyz); + fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w; + + // Kill if not in the spot light (ah ah !) + cosSpotAngle = max(-dot(fragLightDirLen.xyz, getLightDirection(light)), 0.0); + if (cosSpotAngle < getLightSpotAngleCos(light)) { + return false; + } + + return true; } -<@endif@> diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index d76c333206..2232638000 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -12,7 +12,7 @@ <@def DEFERRED_GLOBAL_LIGHT_SLH@> <@include model/Light.slh@> -<@include DeferredLighting.slh@> +!> <@include LightingModel.slh@> <$declareLightingModel()$> diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index 2e06deb0af..d656b3e054 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -8,6 +8,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html !> + <@def DEFERRED_LIGHTING_SLH@> @@ -25,14 +26,15 @@ float specularDistribution(float roughness, vec3 normal, vec3 halfDir) { float power = gloss2 / (3.14159 * denom * denom); return power; } - +*/ + // Frag Shading returns the diffuse amount as W and the specular rgb as xyz vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 fresnel, float roughness) { // Diffuse Lighting @@ -69,7 +71,6 @@ vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 <@endfunc@> - <$declareEvalPBRShading()$> // Return xyz the specular/reflection component and w the diffuse component @@ -78,3 +79,4 @@ vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float } <@endif@> +!> \ No newline at end of file diff --git a/libraries/render-utils/src/LightPoint.slh b/libraries/render-utils/src/LightPoint.slh new file mode 100644 index 0000000000..bf5c8aa307 --- /dev/null +++ b/libraries/render-utils/src/LightPoint.slh @@ -0,0 +1,113 @@ +// Generated on <$_SCRIBE_DATE$> +// +// Created by Sam Gateau on 7/5/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 +// + + + +<@func declareLightingPoint(supportScattering)@> + + +<@include DeferredLighting.slh@> + +void evalLightingPoint(out vec3 diffuse, out vec3 specular, Light light, + vec3 fragLightVec, vec3 fragEyeDir, vec3 normal, float roughness, + float metallic, vec3 fresnel, vec3 albedo, float shadow) { + + // Allright we re valid in the volume + float fragLightDistance = length(fragLightVec); + vec3 fragLightDir = fragLightVec / fragLightDistance; + + // Eval attenuation + float radialAttenuation = evalLightAttenuation(light, fragLightDistance); + + vec3 lightEnergy = radialAttenuation * shadow * getLightColor(light) * getLightIntensity(light); + + // Eval shading + vec4 shading = evalFragShading(normal, fragLightDir, fragEyeDir, metallic, fresnel, roughness); + + diffuse = albedo * shading.w * lightEnergy; + + specular = shading.rgb * lightEnergy; + + if (getLightShowContour(light) > 0.0) { + // Show edge + float edge = abs(2.0 * ((getLightRadius(light) - fragLightDistance) / (0.1)) - 1.0); + if (edge < 1) { + float edgeCoord = exp2(-8.0*edge*edge); + diffuse = vec3(edgeCoord * edgeCoord * getLightShowContour(light) * getLightColor(light)); + } + } +} + +<@if supportScattering@> + +<@include SubsurfaceScattering.slh@> +<$declareSubsurfaceScatteringBRDF()$> +<$declareSkinSpecularLighting()$> + +void evalLightingPointScattering(out vec3 diffuse, out vec3 specular, Light light, + vec3 fragLightVec, vec3 fragEyeDir, vec3 normal, float roughness, + float metallic, vec3 fresnel, vec3 albedo, float shadow, + float scattering, vec3 midNormal, vec3 lowNormal, float curvature) { + + // Allright we re valid in the volume + float fragLightDistance = length(fragLightVec); + vec3 fragLightDir = fragLightVec / fragLightDistance; + + // Eval attenuation + float radialAttenuation = evalLightAttenuation(light, fragLightDistance); + + vec3 lightEnergy = radialAttenuation * shadow * getLightColor(light) * getLightIntensity(light); + + // Eval shading + vec3 brdf = evalSkinBRDF(fragLightDir, normal, midNormal, lowNormal, curvature); + float scatteringLevel = getScatteringLevel(); + vec4 shading; + float standardDiffuse = clamp(dot(normal, fragLightDir), 0.0, 1.0); + { // Key Sun Lighting + // Diffuse Lighting + //float diffuse = clamp(dot(normal, fragLightDir), 0.0, 1.0); + + // Specular Lighting + vec3 halfDir = normalize(fragEyeDir + fragLightDir); + + float specular = skinSpecular(normal, fragLightDir, fragEyeDir, roughness, 1.0); + + vec3 fresnelColor = fresnelSchlick(fresnel, fragLightDir, halfDir); + float power = specularDistribution(roughness, normal, halfDir); + //vec3 specular = power * fresnelColor * standardDiffuse; + + shading = vec4(vec3(specular), (1 - fresnelColor.x)); + } + + + if (scatteringLevel < 0.1) { + brdf = vec3(standardDiffuse); + } + brdf = mix(vec3(standardDiffuse), brdf, scatteringLevel * scattering); + + + diffuse = albedo * brdf.xyz * lightEnergy; + + specular = shading.rgb * lightEnergy; + + if (getLightShowContour(light) > 0.0) { + // Show edge + float edge = abs(2.0 * ((getLightRadius(light) - fragLightDistance) / (0.1)) - 1.0); + if (edge < 1) { + float edgeCoord = exp2(-8.0*edge*edge); + diffuse = vec3(edgeCoord * edgeCoord * getLightShowContour(light) * getLightColor(light)); + } + } +} + +<@endif@> + +<@endfunc@> + + diff --git a/libraries/render-utils/src/LightSpot.slh b/libraries/render-utils/src/LightSpot.slh new file mode 100644 index 0000000000..56c70d6c30 --- /dev/null +++ b/libraries/render-utils/src/LightSpot.slh @@ -0,0 +1,119 @@ +// Generated on <$_SCRIBE_DATE$> +// +// Created by Sam Gateau on 7/5/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 +// + + + +<@func declareLightingSpot(supportScattering)@> + + +<@include DeferredLighting.slh@> + +void evalLightingSpot(out vec3 diffuse, out vec3 specular, Light light, + vec4 fragLightDirLen, float cosSpotAngle, vec3 fragEyeDir, vec3 normal, float roughness, + float metallic, vec3 fresnel, vec3 albedo, float shadow) { + + // Allright we re valid in the volume + float fragLightDistance = fragLightDirLen.w; + vec3 fragLightDir = fragLightDirLen.xyz; + + // Eval attenuation + float radialAttenuation = evalLightAttenuation(light, fragLightDistance); + float angularAttenuation = evalLightSpotAttenuation(light, cosSpotAngle); + vec3 lightEnergy = angularAttenuation * radialAttenuation * shadow * getLightColor(light) * getLightIntensity(light); + + // Eval shading + vec4 shading = evalFragShading(normal, fragLightDir, fragEyeDir, metallic, fresnel, roughness); + + diffuse = albedo * shading.w * lightEnergy; + + specular = shading.rgb * lightEnergy; + + if (getLightShowContour(light) > 0.0) { + // Show edges + float edgeDistR = (getLightRadius(light) - fragLightDistance); + float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -getLightSpotOutsideNormal2(light)); + float edgeDist = min(edgeDistR, edgeDistS); + float edge = abs(2.0 * (edgeDist / (0.1)) - 1.0); + if (edge < 1) { + float edgeCoord = exp2(-8.0*edge*edge); + diffuse = vec3(edgeCoord * edgeCoord * getLightColor(light)); + } + } +} + +<@if supportScattering@> + +<@include SubsurfaceScattering.slh@> +<$declareSubsurfaceScatteringBRDF()$> +<$declareSkinSpecularLighting()$> + +void evalLightingSpotScattering(out vec3 diffuse, out vec3 specular, Light light, + vec4 fragLightDirLen, float cosSpotAngle, vec3 fragEyeDir, vec3 normal, float roughness, + float metallic, vec3 fresnel, vec3 albedo, float shadow, + float scattering, vec3 midNormal, vec3 lowNormal, float curvature) { + + // Allright we re valid in the volume + float fragLightDistance = fragLightDirLen.w; + vec3 fragLightDir = fragLightDirLen.xyz; + + // Eval attenuation + float radialAttenuation = evalLightAttenuation(light, fragLightDistance); + float angularAttenuation = evalLightSpotAttenuation(light, cosSpotAngle); + vec3 lightEnergy = angularAttenuation * radialAttenuation * shadow * getLightColor(light) * getLightIntensity(light); + + // Eval shading + vec3 brdf = evalSkinBRDF(fragLightDir, normal, midNormal, lowNormal, curvature); + float scatteringLevel = getScatteringLevel(); + vec4 shading; + float standardDiffuse = clamp(dot(normal, fragLightDir), 0.0, 1.0); + { // Key Sun Lighting + // Diffuse Lighting + //float diffuse = clamp(dot(normal, fragLightDir), 0.0, 1.0); + + // Specular Lighting + vec3 halfDir = normalize(fragEyeDir + fragLightDir); + + float specular = skinSpecular(normal, fragLightDir, fragEyeDir, roughness, 1.0); + + vec3 fresnelColor = fresnelSchlick(fresnel, fragLightDir, halfDir); + float power = specularDistribution(roughness, normal, halfDir); + //vec3 specular = power * fresnelColor * standardDiffuse; + + shading = vec4(vec3(specular), (1 - fresnelColor.x)); + } + + + if (scatteringLevel < 0.1) { + brdf = vec3(standardDiffuse); + } + brdf = mix(vec3(standardDiffuse), brdf, scatteringLevel * scattering); + + + diffuse = albedo * brdf.xyz * lightEnergy; + + specular = shading.rgb * lightEnergy; + + if (getLightShowContour(light) > 0.0) { + // Show edges + float edgeDistR = (getLightRadius(light) - fragLightDistance); + float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -getLightSpotOutsideNormal2(light)); + float edgeDist = min(edgeDistR, edgeDistS); + float edge = abs(2.0 * (edgeDist / (0.1)) - 1.0); + if (edge < 1) { + float edgeCoord = exp2(-8.0*edge*edge); + diffuse = vec3(edgeCoord * edgeCoord * getLightColor(light)); + } + } +} + +<@endif@> + +<@endfunc@> + + diff --git a/libraries/render-utils/src/LightingModel.cpp b/libraries/render-utils/src/LightingModel.cpp index af546f54dd..9e66a9f673 100644 --- a/libraries/render-utils/src/LightingModel.cpp +++ b/libraries/render-utils/src/LightingModel.cpp @@ -108,7 +108,14 @@ void LightingModel::setSpotLight(bool enable) { bool LightingModel::isSpotLightEnabled() const { return (bool)_parametersBuffer.get().enableSpotLight; } - +void LightingModel::setShowLightContour(bool enable) { + if (enable != isShowLightContourEnabled()) { + _parametersBuffer.edit().showLightContour = (float)enable; + } +} +bool LightingModel::isShowLightContourEnabled() const { + return (bool)_parametersBuffer.get().showLightContour; +} MakeLightingModel::MakeLightingModel() { _lightingModel = std::make_shared(); @@ -126,6 +133,7 @@ void MakeLightingModel::configure(const Config& config) { _lightingModel->setDirectionalLight(config.enableDirectionalLight); _lightingModel->setPointLight(config.enablePointLight); _lightingModel->setSpotLight(config.enableSpotLight); + _lightingModel->setShowLightContour(config.showLightContour); } void MakeLightingModel::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext, LightingModelPointer& lightingModel) { diff --git a/libraries/render-utils/src/LightingModel.h b/libraries/render-utils/src/LightingModel.h index 384110bc70..d8325925fe 100644 --- a/libraries/render-utils/src/LightingModel.h +++ b/libraries/render-utils/src/LightingModel.h @@ -52,6 +52,8 @@ public: void setSpotLight(bool enable); bool isSpotLightEnabled() const; + void setShowLightContour(bool enable); + bool isShowLightContourEnabled() const; UniformBufferView getParametersBuffer() const { return _parametersBuffer; } @@ -77,6 +79,9 @@ protected: float enablePointLight{ 1.0f }; float enableSpotLight{ 1.0f }; + float showLightContour{ 1.0f }; + glm::vec3 spares{ 0.0f }; + Parameters() {} }; UniformBufferView _parametersBuffer; @@ -104,6 +109,8 @@ class MakeLightingModelConfig : public render::Job::Config { Q_PROPERTY(bool enablePointLight MEMBER enablePointLight NOTIFY dirty) Q_PROPERTY(bool enableSpotLight MEMBER enableSpotLight NOTIFY dirty) + Q_PROPERTY(bool showLightContour MEMBER showLightContour NOTIFY dirty) + public: MakeLightingModelConfig() : render::Job::Config() {} // Make Lighting Model is always on @@ -121,6 +128,8 @@ public: bool enablePointLight{ true }; bool enableSpotLight{ true }; + bool showLightContour{ true }; + signals: void dirty(); }; diff --git a/libraries/render-utils/src/LightingModel.slh b/libraries/render-utils/src/LightingModel.slh index cd25353f60..e0c7ce779f 100644 --- a/libraries/render-utils/src/LightingModel.slh +++ b/libraries/render-utils/src/LightingModel.slh @@ -17,6 +17,7 @@ struct LightingModel { vec4 _UnlitShadedEmissiveLightmap; vec4 _ScatteringDiffuseSpecular; vec4 _AmbientDirectionalPointSpot; + vec4 _ShowContour; }; uniform lightingModelBuffer { @@ -59,6 +60,117 @@ float isSpotEnabled() { return lightingModel._AmbientDirectionalPointSpot.w; } +float isShowContour() { + return lightingModel._ShowContour.x; +} + <@endfunc@> + + +<@func declareEvalPBRShading()@> + +vec3 fresnelSchlick(vec3 fresnelColor, vec3 lightDir, vec3 halfDir) { + return fresnelColor + (1.0 - fresnelColor) * pow(1.0 - clamp(dot(lightDir, halfDir), 0.0, 1.0), 5); +} + +float specularDistribution(float roughness, vec3 normal, vec3 halfDir) { + float ndoth = clamp(dot(halfDir, normal), 0.0, 1.0); + float gloss2 = pow(0.001 + roughness, 4); + float denom = (ndoth * ndoth*(gloss2 - 1) + 1); + float power = gloss2 / (3.14159 * denom * denom); + return power; +} + +// Frag Shading returns the diffuse amount as W and the specular rgb as xyz +vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 fresnel, float roughness) { + // Diffuse Lighting + float diffuse = clamp(dot(fragNormal, fragLightDir), 0.0, 1.0); + + // Specular Lighting + vec3 halfDir = normalize(fragEyeDir + fragLightDir); + vec3 fresnelColor = fresnelSchlick(fresnel, fragLightDir, halfDir); + float power = specularDistribution(roughness, fragNormal, halfDir); + vec3 specular = power * fresnelColor * diffuse; + + return vec4(specular, (1.0 - metallic) * diffuse * (1 - fresnelColor.x)); +} +<@endfunc@> + +<$declareEvalPBRShading()$> + +// Return xyz the specular/reflection component and w the diffuse component +vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float metallic, vec3 specular, float roughness) { + return evalPBRShading(fragNormal, fragLightDir, fragEyeDir, metallic, specular, roughness); +} + 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; +} + +// Eval shading +vec3 brdf = evalSkinBRDF(fragLightDir, normal, midNormal, lowNormal, curvature); +float scatteringLevel = getScatteringLevel(); +vec4 shading; +float standardDiffuse = clamp(dot(normal, fragLightDir), 0.0, 1.0); +{ // Key Sun Lighting + // Diffuse Lighting + //float diffuse = clamp(dot(normal, fragLightDir), 0.0, 1.0); + + // Specular Lighting + vec3 halfDir = normalize(fragEyeDir + fragLightDir); + + float specular = skinSpecular(normal, fragLightDir, fragEyeDir, roughness, 1.0); + + vec3 fresnelColor = fresnelSchlick(fresnel, fragLightDir, halfDir); + float power = specularDistribution(roughness, normal, halfDir); + //vec3 specular = power * fresnelColor * standardDiffuse; + + shading = vec4(vec3(specular), (1 - fresnelColor.x)); +} + + +if (scatteringLevel < 0.1) { + brdf = vec3(standardDiffuse); +} +brdf = mix(vec3(standardDiffuse), brdf, scatteringLevel * scattering); + + +diffuse = albedo * brdf.xyz * lightEnergy; + +specular = shading.rgb * lightEnergy; + +!> + <@endif@> diff --git a/libraries/render-utils/src/overlay3D.slf b/libraries/render-utils/src/overlay3D.slf index 38f236e0b3..1c374b759b 100644 --- a/libraries/render-utils/src/overlay3D.slf +++ b/libraries/render-utils/src/overlay3D.slf @@ -11,7 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include DeferredLighting.slh@> +<@include LightingModel.slh@> <@include model/Light.slh@> <@include gpu/Transform.slh@> diff --git a/libraries/render-utils/src/overlay3D_translucent.slf b/libraries/render-utils/src/overlay3D_translucent.slf index f8c18abf20..14c257c75e 100644 --- a/libraries/render-utils/src/overlay3D_translucent.slf +++ b/libraries/render-utils/src/overlay3D_translucent.slf @@ -12,7 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include DeferredLighting.slh@> +<@include LightingModel.slh@> <@include model/Light.slh@> <@include gpu/Transform.slh@> diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index e9c6ee90a0..3012ad1ac2 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -5,7 +5,7 @@ // point_light.frag // fragment shader // -// Created by Andrzej Kapolka on 9/18/14. +// Created by Sam Gateau on 9/18/15. // Copyright 2014 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -15,12 +15,18 @@ // Everything about deferred buffer <@include DeferredBufferRead.slh@> -//Everything about deferred lighting -<@include DeferredLighting.slh@> +<$declareDeferredCurvature()$> // Everything about light <@include model/Light.slh@> +<@include LightingModel.slh@> +<$declareLightingModel()$> + +<@include LightPoint.slh@> +<$declareLightingPoint(supportScattering)$> + + in vec4 _texCoord0; out vec4 _fragColor; @@ -36,8 +42,6 @@ void main(void) { discard; } - mat4 invViewMat = getViewInverse(); - // Kill if in front of the light volume float depth = frag.depthVal; if (depth < gl_FragCoord.z) { @@ -47,38 +51,41 @@ void main(void) { // Need the light now Light light = getLight(); - // Make the Light vector going from fragment to light center in world space + // Frag pos in world + mat4 invViewMat = getViewInverse(); vec4 fragPos = invViewMat * frag.position; - vec3 fragLightVec = getLightPosition(light) - fragPos.xyz; - // Kill if too far from the light center - if (dot(fragLightVec, fragLightVec) > getLightCutoffSquareRadius(light)) { + // Clip againgst the light volume and Make the Light vector going from fragment to light center in world space + vec4 fragLightVecLen2; + if (!clipFragToLightVolumePoint(light, fragPos.xyz, fragLightVecLen2)) { discard; } - // Allright we re valid in the volume - float fragLightDistance = length(fragLightVec); - vec3 fragLightDir = fragLightVec / fragLightDistance; - - // Eval shading - vec3 fragNormal = vec3(frag.normal); + // Frag to eye vec vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); - vec4 shading = evalFragShading(fragNormal, fragLightDir, fragEyeDir, frag.metallic, frag.specular, frag.roughness); - // Eval attenuation - float radialAttenuation = evalLightAttenuation(light, fragLightDistance); - // Final Lighting color - vec3 fragColor = (shading.w * frag.diffuse + shading.xyz); - _fragColor = vec4(fragColor * radialAttenuation * getLightColor(light) * getLightIntensity(light) * frag.obscurance, 0.0); + vec3 diffuse; + vec3 specular; - if (getLightShowContour(light) > 0.0) { - // Show edge - float edge = abs(2.0 * ((getLightRadius(light) - fragLightDistance) / (0.1)) - 1.0); - if (edge < 1) { - float edgeCoord = exp2(-8.0*edge*edge); - _fragColor = vec4(edgeCoord * edgeCoord * getLightShowContour(light) * getLightColor(light), 0.0); - } + if ((isScatteringEnabled() > 0.0) && (frag.mode == FRAG_MODE_SCATTERING)) { + vec4 blurredCurvature = fetchCurvature(texCoord); + vec4 diffusedCurvature = fetchDiffusedCurvature(texCoord); + vec3 midNormal = normalize((blurredCurvature.xyz - 0.5f) * 2.0f); + vec3 lowNormal = normalize((diffusedCurvature.xyz - 0.5f) * 2.0f); + float highCurvature = unpackCurvature(blurredCurvature.w); + float lowCurvature = unpackCurvature(diffusedCurvature.w); + evalLightingPointScattering(diffuse, specular, light, + fragLightVecLen2.xyz, fragEyeDir, frag.normal, frag.roughness, + frag.metallic, frag.specular, frag.diffuse, 1.0, + frag.scattering, midNormal, lowNormal, lowCurvature); + } else { + evalLightingPoint(diffuse, specular, light, + fragLightVecLen2.xyz, fragEyeDir, frag.normal, frag.roughness, + frag.metallic, frag.specular, frag.diffuse, 1.0); } + + _fragColor.rgb += diffuse * isDiffuseEnabled() * isPointEnabled(); + _fragColor.rgb += specular * isSpecularEnabled() * isPointEnabled(); } diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index bf046a613b..5654b86d68 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -5,7 +5,7 @@ // spot_light.frag // fragment shader // -// Created by Andrzej Kapolka on 9/18/14. +// Created by Sam Gateau on 9/18/15. // Copyright 2014 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -15,12 +15,18 @@ // Everything about deferred buffer <@include DeferredBufferRead.slh@> -//Everything about deferred lighting -<@include DeferredLighting.slh@> +<$declareDeferredCurvature()$> // Everything about light <@include model/Light.slh@> +<@include LightingModel.slh@> +<$declareLightingModel()$> + +<@include LightSpot.slh@> +<$declareLightingSpot(supportScattering)$> + + in vec4 _texCoord0; out vec4 _fragColor; @@ -36,8 +42,6 @@ void main(void) { discard; } - mat4 invViewMat = getViewInverse(); - // Kill if in front of the light volume float depth = frag.depthVal; if (depth < gl_FragCoord.z) { @@ -47,50 +51,43 @@ void main(void) { // Need the light now Light light = getLight(); - // Make the Light vector going from fragment to light center in world space + // Frag pos in world + mat4 invViewMat = getViewInverse(); vec4 fragPos = invViewMat * frag.position; - vec3 fragLightVec = getLightPosition(light) - fragPos.xyz; - // Kill if too far from the light center - if (dot(fragLightVec, fragLightVec) > getLightCutoffSquareRadius(light)) { + // Clip againgst the light volume and Make the Light vector going from fragment to light center in world space + vec4 fragLightVecLen2; + vec4 fragLightDirLen; + float cosSpotAngle; + if (!clipFragToLightVolumeSpot(light, fragPos.xyz, fragLightVecLen2, fragLightDirLen, cosSpotAngle)) { discard; } - // Allright we re valid in the volume - float fragLightDistance = length(fragLightVec); - vec3 fragLightDir = fragLightVec / fragLightDistance; - - // Kill if not in the spot light (ah ah !) - vec3 lightSpotDir = getLightDirection(light); - float cosSpotAngle = max(-dot(fragLightDir, lightSpotDir), 0.0); - if (cosSpotAngle < getLightSpotAngleCos(light)) { - discard; - } - - // Eval shading - vec3 fragNormal = vec3(frag.normal); + // Frag to eye vec vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); - vec4 shading = evalFragShading(fragNormal, fragLightDir, fragEyeDir, frag.metallic, frag.specular, frag.roughness); - - // Eval attenuation - float radialAttenuation = evalLightAttenuation(light, fragLightDistance); - float angularAttenuation = evalLightSpotAttenuation(light, cosSpotAngle); - // Final Lighting color - vec3 fragColor = (shading.w * frag.diffuse + shading.xyz); - _fragColor = vec4(fragColor * angularAttenuation * radialAttenuation * getLightColor(light) * getLightIntensity(light) * frag.obscurance, 0.0); - if (getLightShowContour(light) > 0.0) { - // Show edges - float edgeDistR = (getLightRadius(light) - fragLightDistance); - float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -getLightSpotOutsideNormal2(light)); - float edgeDist = min(edgeDistR, edgeDistS); - float edge = abs(2.0 * (edgeDist / (0.1)) - 1.0); - if (edge < 1) { - float edgeCoord = exp2(-8.0*edge*edge); - _fragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); - } + vec3 diffuse; + vec3 specular; + if ((isScatteringEnabled() > 0.0) && (frag.mode == FRAG_MODE_SCATTERING)) { + vec4 blurredCurvature = fetchCurvature(texCoord); + vec4 diffusedCurvature = fetchDiffusedCurvature(texCoord); + vec3 midNormal = normalize((blurredCurvature.xyz - 0.5f) * 2.0f); + vec3 lowNormal = normalize((diffusedCurvature.xyz - 0.5f) * 2.0f); + float highCurvature = unpackCurvature(blurredCurvature.w); + float lowCurvature = unpackCurvature(diffusedCurvature.w); + evalLightingSpotScattering(diffuse, specular, light, + fragLightDirLen.xyzw, cosSpotAngle, fragEyeDir, frag.normal, frag.roughness, + frag.metallic, frag.specular, frag.diffuse, 1.0, + frag.scattering, midNormal, lowNormal, lowCurvature); + } else { + evalLightingSpot(diffuse, specular, light, + fragLightDirLen.xyzw, cosSpotAngle, fragEyeDir, frag.normal, frag.roughness, + frag.metallic, frag.specular, frag.diffuse, 1.0); } + + _fragColor.rgb += diffuse * isDiffuseEnabled() * isSpotEnabled(); + _fragColor.rgb += specular * isSpecularEnabled() * isSpotEnabled(); } diff --git a/libraries/render/src/render/ShapePipeline.cpp b/libraries/render/src/render/ShapePipeline.cpp index 5245992ec4..6c5128830e 100644 --- a/libraries/render/src/render/ShapePipeline.cpp +++ b/libraries/render/src/render/ShapePipeline.cpp @@ -69,6 +69,10 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p auto locations = std::make_shared(); locations->normalFittingMapUnit = program->getTextures().findLocation("normalFittingMap"); + if (program->getTextures().findLocation("normalFittingMap") > -1) { + locations->normalFittingMapUnit = program->getTextures().findLocation("normalFittingMap"); + + } locations->albedoTextureUnit = program->getTextures().findLocation("albedoMap"); locations->roughnessTextureUnit = program->getTextures().findLocation("roughnessMap"); locations->normalTextureUnit = program->getTextures().findLocation("normalMap");