From fdffd8b6e070434ec32851697f0d897c08f9ec74 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 25 Feb 2016 14:13:57 -0800 Subject: [PATCH 1/2] Track skybox mipmap levels in DeferredTransform --- .../render-utils/src/DeferredLightingEffect.cpp | 14 +++++++++++--- .../render-utils/src/DeferredLightingEffect.h | 6 +++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index e2b5721bd9..736b34d779 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -94,7 +94,7 @@ void DeferredLightingEffect::init() { lp->setColor(glm::vec3(1.0f)); lp->setIntensity(1.0f); lp->setType(model::Light::SUN); - lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset(_ambientLightMode % gpu::SphericalHarmonics::NUM_PRESET)); + lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset::OLD_TOWN_SQUARE); } void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& color, @@ -321,7 +321,7 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo if (_skyboxTexture) { program = _directionalSkyboxLightShadow; locations = _directionalSkyboxLightShadowLocations; - } else if (_ambientLightMode > -1) { + } else { program = _directionalAmbientSphereLightShadow; locations = _directionalAmbientSphereLightShadowLocations; } @@ -329,7 +329,7 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo if (_skyboxTexture) { program = _directionalSkyboxLight; locations = _directionalSkyboxLightLocations; - } else if (_ambientLightMode > -1) { + } else { program = _directionalAmbientSphereLight; locations = _directionalAmbientSphereLightLocations; } @@ -562,6 +562,14 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light, const gpu::TexturePointer& skyboxTexture) { _allocatedLights.front() = light; _skyboxTexture = skyboxTexture; + + // Update the available mipmap levels + if (_skyboxTexture) { + float dim = glm::max(_skyboxTexture->getHeight(), _skyboxTexture->getWidth(), _skyboxTexture->getDepth()); + auto skyboxMipmapLevels = 1 + glm::floor(glm::log2(dim)); + _deferredTransformBuffer[0].edit().skyboxMipmapLevels = skyboxMipmapLevels; + _deferredTransformBuffer[1].edit().skyboxMipmapLevels = skyboxMipmapLevels; + } } model::MeshPointer DeferredLightingEffect::getSpotLightMesh() { diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 7fc6d99a95..49a3825fca 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -96,7 +96,6 @@ private: std::vector _pointLights; std::vector _spotLights; - int _ambientLightMode = 0; gpu::TexturePointer _skyboxTexture; // Class describing the uniform buffer with all the parameters common to the deferred shaders @@ -104,8 +103,9 @@ private: public: glm::mat4 projection; glm::mat4 viewInverse; - float stereoSide{ 0.f }; - float spareA, spareB, spareC; + float stereoSide { 0.f }; + float skyboxMipmapLevels { 1.0f }; + float spareA, spareB; DeferredTransform() {} }; From 1fbcaea4b4d6b77ab65d5031952400aa9f50fafb Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 25 Feb 2016 14:16:06 -0800 Subject: [PATCH 2/2] Fix evalSkyboxGlobalColor --- libraries/render-utils/src/DeferredBuffer.slh | 9 +- .../render-utils/src/DeferredGlobalLight.slh | 107 +++++++----------- .../src/directional_skybox_light.slf | 3 +- .../src/directional_skybox_light_shadow.slf | 3 +- 4 files changed, 49 insertions(+), 73 deletions(-) diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index bfed92018a..699926a87c 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -34,8 +34,9 @@ uniform sampler2D lightingMap; struct DeferredTransform { mat4 projection; mat4 viewInverse; - - vec4 stereoSide_spareABC; + float stereoSide; + float skyboxMipmapLevels; + vec2 _spareAB; }; layout(std140) uniform deferredTransformBuffer { @@ -46,10 +47,10 @@ DeferredTransform getDeferredTransform() { } bool getStereoMode(DeferredTransform deferredTransform) { - return (deferredTransform.stereoSide_spareABC.x != 0.0); + return (deferredTransform.stereoSide != 0.0); } float getStereoSide(DeferredTransform deferredTransform) { - return (deferredTransform.stereoSide_spareABC.x); + return (deferredTransform.stereoSide); } vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) { diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index a3fb1de3ec..3764b19f7c 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -11,88 +11,61 @@ <@if not DEFERRED_GLOBAL_LIGHT_SLH@> <@def DEFERRED_GLOBAL_LIGHT_SLH@> +<@include model/Light.slh@> <@include DeferredLighting.slh@> <@func declareSkyboxMap()@> - +// declareSkyboxMap uniform samplerCube skyboxMap; vec4 evalSkyboxLight(vec3 direction, float lod) { - // FIXME - //vec4 skytexel = textureLod(skyboxMap, direction, lod * textureQueryLevels(skyboxMap)); - vec4 skytexel = texture(skyboxMap, direction); - return skytexel; + // textureQueryLevels is not available until #430, so we require explicit lod + // float mipmapLevel = lod * textureQueryLevels(skyboxMap); + return textureLod(skyboxMap, direction, lod); } - <@endfunc@> -// Everything about light -<@include model/Light.slh@> +<@func prepareGlobalLight()@> + // prepareGlobalLight + + // Transform directions to worldspace + vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0)); + vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0)); + vec3 fragEyeDir = normalize(fragEyeVector); + + // Get light + Light light = getLight(); + + vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, vec3(metallic), roughness); + color = vec3(albedo * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light); + color += emissive; +<@endfunc@> <@func declareEvalAmbientGlobalColor()@> vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) { - - // Need the light now - Light light = getLight(); - - vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0)); - vec4 fragEyeVector = invViewMat * vec4(-position, 0.0); - vec3 fragEyeDir = normalize(fragEyeVector.xyz); - - vec3 color = albedo * getLightColor(light) * obscurance * getLightAmbientIntensity(light); - - - vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, vec3(metallic), roughness); - - color += vec3(albedo * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light); - color += emissive; - + <$prepareGlobalLight()$> + color += albedo * getLightColor(light) * obscurance * getLightAmbientIntensity(light); return color; } <@endfunc@> <@func declareEvalAmbientSphereGlobalColor()@> - - vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) { - // Need the light now - Light light = getLight(); - - vec3 fragNormal = normalize(vec3(invViewMat * vec4(normal, 0.0))); - vec4 fragEyeVector = invViewMat * vec4(-position, 0.0); - vec3 fragEyeDir = normalize(fragEyeVector.xyz); - - vec3 ambientNormal = fragNormal.xyz; - - vec3 color = albedo * evalSphericalLight(getLightAmbientSphere(light), ambientNormal).xyz * obscurance * getLightAmbientIntensity(light); - - vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, vec3(metallic), roughness); - - color += vec3(albedo * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light); - color += emissive; + <$prepareGlobalLight()$> + color += albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light); return color; } <@endfunc@> <@func declareEvalSkyboxGlobalColor()@> - <$declareSkyboxMap()$> - vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) { - // Need the light now - Light light = getLight(); - - vec3 fragNormal = normalize(vec3(invViewMat * vec4(normal, 0.0))); - vec4 fragEyeVector = invViewMat * vec4(-position, 0.0); - vec3 fragEyeDir = normalize(fragEyeVector.xyz); - + <$prepareGlobalLight()$> - vec3 color = albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light); - - vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, vec3(metallic), roughness); - - color += vec3(albedo * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light); - color += emissive; + vec3 direction = -reflect(fragEyeDir, fragNormal); + float lod = min(1.0 + floor((1.0 - gloss) * levels), levels); + vec4 skyboxLight = evalSkyboxLight(direction, lod); + color += albedo * skyboxLight.rgb * skyboxLight.a * obscurance * getLightAmbientIntensity(light); return color; } @@ -100,26 +73,26 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu <@func declareEvalLightmappedColor()@> vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 albedo, vec3 lightmap) { - +vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 diffuse, vec3 lightmap) { Light light = getLight(); - vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0)); - float diffuseDot = dot(fragNormal, -getLightDirection(light)); - - // need to catch normals perpendicular to the projection plane hence the magic number for the threshold - // it should be just 0, but we have innacurracy so we need to overshoot + // Catch normals perpendicular to the projection plane, hence the magic number for the threshold + // It should be just 0, but we have inaccuracy so we overshoot const float PERPENDICULAR_THRESHOLD = -0.005; + vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0)); // transform to worldspace + float diffuseDot = dot(fragNormal, -getLightDirection(light)); float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot); - //float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot); - // evaluate the shadow test but only relevant for light facing fragments + + // Reevaluate the shadow attenuation for light facing fragments float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation; - // diffuse light is the lightmap dimmed by shadow + + // Diffuse light is the lightmap dimmed by shadow vec3 diffuseLight = lightAttenuation * lightmap; - // ambient is a tiny percentage of the lightmap and only when in the shadow + // Ambient light is the lightmap when in shadow vec3 ambientLight = (1 - lightAttenuation) * lightmap * getLightAmbientIntensity(light); - return obscurance * albedo * (ambientLight + diffuseLight); + return obscurance * albedo * (diffuseLight + ambientLight); } <@endfunc@> diff --git a/libraries/render-utils/src/directional_skybox_light.slf b/libraries/render-utils/src/directional_skybox_light.slf index 9e24a5f585..5ec6cc5da3 100755 --- a/libraries/render-utils/src/directional_skybox_light.slf +++ b/libraries/render-utils/src/directional_skybox_light.slf @@ -47,7 +47,8 @@ void main(void) { frag.diffuse, frag.metallic, frag.emissive, - frag.roughness); + frag.roughness, + deferredTransform.skyboxMipmapLevels); _fragColor = vec4(color, frag.normalVal.a); } diff --git a/libraries/render-utils/src/directional_skybox_light_shadow.slf b/libraries/render-utils/src/directional_skybox_light_shadow.slf index c3008b5509..b3f273b39e 100644 --- a/libraries/render-utils/src/directional_skybox_light_shadow.slf +++ b/libraries/render-utils/src/directional_skybox_light_shadow.slf @@ -49,7 +49,8 @@ void main(void) { frag.diffuse, frag.metallic, frag.emissive, - frag.roughness); + frag.roughness, + deferredTransform.skyboxMipmapLevels); _fragColor = vec4(color, frag.normalVal.a); }