From 630c61e61da2009ff1460dc0d286dee18f1cca73 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 29 Feb 2016 18:54:43 -0800 Subject: [PATCH] Reflection is working correctly with the PBR property, ship t --- .../src/EntityTreeRenderer.cpp | 2 ++ libraries/model/src/model/Light.cpp | 13 +++++++++-- libraries/model/src/model/Light.h | 7 +++++- libraries/model/src/model/Material.h | 2 +- libraries/model/src/model/Stage.cpp | 3 +++ libraries/model/src/model/Stage.h | 1 + libraries/model/src/model/TextureMap.cpp | 4 ++-- libraries/render-utils/src/DeferredBuffer.slh | 8 ++++++- .../render-utils/src/DeferredGlobalLight.slh | 23 ++++++++++++++----- .../render-utils/src/DeferredLighting.slh | 2 +- .../src/DeferredLightingEffect.cpp | 20 +++++++++------- .../render-utils/src/MaterialTextures.slh | 4 ++-- .../src/SceneScriptingInterface.cpp | 5 ++++ .../src/SceneScriptingInterface.h | 1 + 14 files changed, 71 insertions(+), 24 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index bc1f614f79..ccf5036fa1 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -325,6 +325,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrgetGPUTexture()->getIrradiance()) { sceneKeyLight->setAmbientSphere(_ambientTexture->getGPUTexture()->getIrradiance()); + sceneKeyLight->setAmbientMap(_ambientTexture->getGPUTexture()); isAmbientTextureSet = true; } } else { @@ -360,6 +361,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrgetIrradiance()) { sceneKeyLight->setAmbientSphere(texture->getIrradiance()); + sceneKeyLight->setAmbientMap(texture); isAmbientTextureSet = true; } } else { diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp index 92f53ad4c6..1497ceba86 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/model/src/model/Light.cpp @@ -141,6 +141,15 @@ void Light::setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset) { editSchema()._ambientSphere.assignPreset(preset); } -void Light::setAmbientMapNumMips(int numMips) { - editSchema()._ambientMapNumMips = numMips; +void Light::setAmbientMap(gpu::TexturePointer ambientMap) { + _ambientMap = ambientMap; + if (ambientMap) { + setAmbientMapNumMips(_ambientMap->evalNumMips()); + } else { + setAmbientMapNumMips(0); + } +} + +void Light::setAmbientMapNumMips(int numMips) { + editSchema()._ambientMapNumMips = (float)numMips; } diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index 1ec47f7eea..1db73f4093 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -108,6 +108,9 @@ public: const gpu::SphericalHarmonics& getAmbientSphere() const { return getSchema()._ambientSphere; } void setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset); + void setAmbientMap(gpu::TexturePointer ambientMap); + gpu::TexturePointer getAmbientMap() const { return _ambientMap; } + void setAmbientMapNumMips(int numMips); int getAmbientMapNumMips() const { return getSchema()._ambientMapNumMips; } @@ -123,7 +126,7 @@ public: Vec4 _spot{0.0f, 0.0f, 0.0f, 0.0f}; Vec4 _shadow{0.0f}; - int _ambientMapNumMips{ 0 }; + float _ambientMapNumMips{ 0 }; Vec3 _control{ 0.0f, 0.0f, 0.0f }; gpu::SphericalHarmonics _ambientSphere; @@ -137,6 +140,8 @@ protected: UniformBufferView _schemaBuffer; Transform _transform; + gpu::TexturePointer _ambientMap; + const Schema& getSchema() const { return _schemaBuffer.get(); } Schema& editSchema() { return _schemaBuffer.edit(); } diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index cdc3e4dc39..81a55eea8a 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -277,7 +277,7 @@ public: const TextureMaps& getTextureMaps() const { return _textureMaps; } // conversion from legacy material properties to PBR equivalent - static float shininessToRoughness(float shininess) { return 1.0f - shininess / 128.0f; } + static float shininessToRoughness(float shininess) { return 1.0f - shininess / 100.0f; } protected: diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index c976e5c396..23503ef6fb 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -212,6 +212,9 @@ void SunSkyStage::setSunAmbientSphere(const gpu::SHPointer& sphere) { _sunLight->setAmbientSpherePreset(DEFAULT_AMBIENT_SPHERE); } } +void SunSkyStage::setSunAmbientMap(const gpu::TexturePointer& map) { + _sunLight->setAmbientMap(map); +} void SunSkyStage::setSunDirection(const Vec3& direction) { if (!isSunModelEnabled()) { diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index 31772d5e48..d9fa81b16f 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -150,6 +150,7 @@ public: void setSunAmbientIntensity(float intensity) { _sunLight->setAmbientIntensity(intensity); } float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); } void setSunAmbientSphere(const gpu::SHPointer& sphere); + void setSunAmbientMap(const gpu::TexturePointer& map); // The sun direction is expressed in the world space void setSunDirection(const Vec3& direction); diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index c775443425..d0416ec3b5 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -593,8 +593,8 @@ gpu::Texture* TextureUsage::createCubeTextureFromImage(const QImage& srcImage, c theTexture->assignStoredMipFace(0, formatMip, face.byteCount(), face.constBits(), f); f++; } - - // GEnerate irradiance while we are at it + + // Generate irradiance while we are at it theTexture->generateIrradiance(); } } diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index cc5780e425..5a3c941ce3 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -115,7 +115,13 @@ DeferredFragment unpackDeferredFragmentNoPosition(vec2 texcoord) { frag.metallic = frag.diffuseVal.a; frag.diffuse = frag.diffuseVal.xyz; - frag.specular = vec3(frag.metallic); + if (frag.metallic <= 0.5) { + frag.metallic = 0.0; + frag.specular = vec3(0.03); // Default Di-electric fresnel value + } else { + frag.specular = vec3(frag.diffuseVal.xyz); + frag.metallic = 1.0; + } frag.obscurance = min(frag.specularVal.w, frag.obscurance); return frag; diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index f0231dbb9e..0f92f8df2c 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -35,8 +35,12 @@ vec4 evalSkyboxLight(vec3 direction, float lod) { // Get light Light light = getLight(); - - vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, vec3(metallic), roughness); + vec3 fresnel = vec3(0.03); // Default Di-electric fresnel value + if (metallic > 0.5) { + fresnel = albedo; + metallic = 1.0; + } + vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, metallic, fresnel, roughness); vec3 color = vec3(albedo * shading.w + shading.rgb) * min(shadowAttenuation, obscurance) * getLightColor(light) * getLightIntensity(light); color += emissive; <@endfunc@> @@ -52,21 +56,28 @@ vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obsc <@func declareEvalAmbientSphereGlobalColor()@> vec3 evalAmbientSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) { <$prepareGlobalLight()$> - color += albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light); + color += (1 - (metallic * 0.5)) * albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light); return color; } <@endfunc@> <@func declareEvalSkyboxGlobalColor()@> <$declareSkyboxMap()$> + +vec3 fresnelSchlickAmbient(vec3 fresnelColor, vec3 lightDir, vec3 halfDir, float gloss) { + return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * pow(1.0f - clamp(dot(lightDir, halfDir), 0.0, 1.0), 5); +} + vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 emissive, float roughness) { <$prepareGlobalLight()$> - + color += (1 - metallic) * albedo * evalSphericalLight(getLightAmbientSphere(light), fragNormal).xyz * obscurance * getLightAmbientIntensity(light); + vec3 direction = -reflect(fragEyeDir, fragNormal); float levels = getLightAmbientMapNumMips(light); - float lod = min(1.0 + floor((roughness) * levels), levels); + float lod = min(floor((roughness) * levels), levels); vec4 skyboxLight = evalSkyboxLight(direction, lod); - color += albedo * skyboxLight.rgb * skyboxLight.a * obscurance * getLightAmbientIntensity(light); + vec3 ambientFresnel = fresnelSchlickAmbient(fresnel, fragEyeDir, fragNormal, 1 - roughness); + color += ambientFresnel * skyboxLight.rgb * obscurance * getLightAmbientIntensity(light); return color; } diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index ca3989256a..d02f9e3345 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -37,7 +37,7 @@ vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, float m float power = specularDistribution(roughness, fragNormal, halfDir); vec3 specular = power * fresnelColor * diffuse; - return vec4(specular, diffuse * (1 - fresnelColor.x)); + return vec4(specular, (1.0 - metallic) * diffuse * (1 - fresnelColor.x)); } <@endfunc@> diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 3ffdb2d47b..a05c8c4cc7 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -320,18 +320,19 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo // Setup the global directional pass pipeline { if (_shadowMapEnabled) { - /* if (_skyboxTexture) { + //if (_skyboxTexture) { + if (_skyboxTexture) { program = _directionalSkyboxLightShadow; locations = _directionalSkyboxLightShadowLocations; - } else*/ { + } else { program = _directionalAmbientSphereLightShadow; locations = _directionalAmbientSphereLightShadowLocations; } } else { - /* if (_skyboxTexture) { + if (_skyboxTexture) { program = _directionalSkyboxLight; locations = _directionalSkyboxLightLocations; - } else*/ { + } else { program = _directionalAmbientSphereLight; locations = _directionalAmbientSphereLightLocations; } @@ -501,8 +502,9 @@ void DeferredLightingEffect::setupKeyLightBatch(gpu::Batch& batch, int lightBuff batch.setUniformBuffer(lightBufferUnit, globalLight->getSchemaBuffer()); } - if (_skyboxTexture && (skyboxCubemapUnit >= 0)) { - batch.setResourceTexture(skyboxCubemapUnit, _skyboxTexture); + // if (_skyboxTexture && (skyboxCubemapUnit >= 0)) { + if (globalLight->getAmbientMap() && (skyboxCubemapUnit >= 0)) { + batch.setResourceTexture(skyboxCubemapUnit, globalLight->getAmbientMap()); } } @@ -569,10 +571,12 @@ void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light, co globalLight->setAmbientIntensity(light->getAmbientIntensity()); globalLight->setAmbientSphere(light->getAmbientSphere()); - _skyboxTexture = skyboxTexture; + // _skyboxTexture = skyboxTexture; + _skyboxTexture = (light->getAmbientMap() ? light->getAmbientMap() : _skyboxTexture); // Update the available mipmap levels - globalLight->setAmbientMapNumMips((_skyboxTexture ? _skyboxTexture->evalNumMips() : 0)); + globalLight->setAmbientMap((light->getAmbientMap() ? light->getAmbientMap() : _skyboxTexture)); + // globalLight->setAmbientMapNumMips((_skyboxTexture ? _skyboxTexture->evalNumMips() : 0)); } model::MeshPointer DeferredLightingEffect::getSpotLightMesh() { diff --git a/libraries/render-utils/src/MaterialTextures.slh b/libraries/render-utils/src/MaterialTextures.slh index 5372419465..fb253e3f6d 100644 --- a/libraries/render-utils/src/MaterialTextures.slh +++ b/libraries/render-utils/src/MaterialTextures.slh @@ -23,7 +23,7 @@ vec4 fetchAlbedoMap(vec2 uv) { <@if withRoughness@> uniform sampler2D roughnessMap; float fetchRoughnessMap(vec2 uv) { - return pow(texture(roughnessMap, uv).r, 2.2); + return (texture(roughnessMap, uv).r); } <@endif@> @@ -37,7 +37,7 @@ vec3 fetchNormalMap(vec2 uv) { <@if withMetallic@> uniform sampler2D specularMap; float fetchMetallicMap(vec2 uv) { - return pow(texture(specularMap, uv).r, 2.2); + return (texture(specularMap, uv).r); } <@endif@> diff --git a/libraries/script-engine/src/SceneScriptingInterface.cpp b/libraries/script-engine/src/SceneScriptingInterface.cpp index 079cfff2c7..3883b948df 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.cpp +++ b/libraries/script-engine/src/SceneScriptingInterface.cpp @@ -81,6 +81,11 @@ void SceneScripting::KeyLight::setAmbientSphere(const gpu::SHPointer& sphere) { _skyStage->setSunAmbientSphere(sphere); } +void SceneScripting::KeyLight::setAmbientMap(const gpu::TexturePointer& map) { + _skyStage->setSunAmbientMap(map); +} + + glm::vec3 SceneScripting::KeyLight::getDirection() const { return _skyStage->getSunDirection(); } diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h index 12681b1887..e8ea2e0217 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.h +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -84,6 +84,7 @@ namespace SceneScripting { // AmbientTexture is unscriptable - it must be set through the zone entity void setAmbientSphere(const gpu::SHPointer& sphere); void resetAmbientSphere() { setAmbientSphere(nullptr); } + void setAmbientMap(const gpu::TexturePointer& map); protected: model::SunSkyStagePointer _skyStage;