From ca776fb9b4db3708116e0f2e397e1ac434529aff Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Mon, 15 Jan 2018 11:36:52 +0100 Subject: [PATCH 01/21] Added LightLocal.slh to centralize shading with local lights --- libraries/render-utils/src/LightLocal.slh | 48 +++++++++++++++++++ .../render-utils/src/local_lights_shading.slf | 36 +------------- 2 files changed, 50 insertions(+), 34 deletions(-) create mode 100644 libraries/render-utils/src/LightLocal.slh diff --git a/libraries/render-utils/src/LightLocal.slh b/libraries/render-utils/src/LightLocal.slh new file mode 100644 index 0000000000..69563d4985 --- /dev/null +++ b/libraries/render-utils/src/LightLocal.slh @@ -0,0 +1,48 @@ +// Generated on <$_SCRIBE_DATE$> +// +// Created by Olivier Prat on 15/01/18. +// Copyright 2018 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 +// + +// Everything about light +<@include model/Light.slh@> +<$declareLightBuffer(256)$> +<@include LightingModel.slh@> + + +<@include LightPoint.slh@> +<$declareLightingPoint(supportScattering)$> +<@include LightSpot.slh@> +<$declareLightingSpot(supportScattering)$> + +<@include LightClusterGrid.slh@> + +<@func fetchClusterInfo(fragPos)@> + + // From frag world pos find the cluster + vec4 clusterEyePos = frustumGrid_worldToEye(<$fragPos$>); + ivec3 clusterPos = frustumGrid_eyeToClusterPos(clusterEyePos.xyz); + + ivec3 cluster = clusterGrid_getCluster(frustumGrid_clusterToIndex(clusterPos)); + int numLights = cluster.x + cluster.y; + if (numLights <= 0) { + discard; + } + int lightClusterOffset = cluster.z; + + ivec3 dims = frustumGrid.dims.xyz; + if (clusterPos.x < 0 || clusterPos.x >= dims.x) { + discard; + } + + if (clusterPos.y < 0 || clusterPos.y >= dims.y) { + discard; + } + if (clusterPos.z < 0 || clusterPos.z > dims.z) { + discard; + } + +<@endfunc@> \ No newline at end of file diff --git a/libraries/render-utils/src/local_lights_shading.slf b/libraries/render-utils/src/local_lights_shading.slf index c6310cb079..3968ec9077 100644 --- a/libraries/render-utils/src/local_lights_shading.slf +++ b/libraries/render-utils/src/local_lights_shading.slf @@ -17,18 +17,7 @@ <$declareDeferredCurvature()$> -// Everything about light -<@include model/Light.slh@> -<$declareLightBuffer(256)$> -<@include LightingModel.slh@> - - -<@include LightPoint.slh@> -<$declareLightingPoint(supportScattering)$> -<@include LightSpot.slh@> -<$declareLightingSpot(supportScattering)$> - -<@include LightClusterGrid.slh@> +<@include LightLocal.slh@> in vec2 _texCoord0; out vec4 _fragColor; @@ -51,28 +40,7 @@ void main(void) { mat4 invViewMat = getViewInverse(); vec4 fragPos = invViewMat * fragPosition; - // From frag world pos find the cluster - vec4 clusterEyePos = frustumGrid_worldToEye(fragPos); - ivec3 clusterPos = frustumGrid_eyeToClusterPos(clusterEyePos.xyz); - - ivec3 cluster = clusterGrid_getCluster(frustumGrid_clusterToIndex(clusterPos)); - int numLights = cluster.x + cluster.y; - if (numLights <= 0) { - discard; - } - int lightClusterOffset = cluster.z; - - ivec3 dims = frustumGrid.dims.xyz; - if (clusterPos.x < 0 || clusterPos.x >= dims.x) { - discard; - } - - if (clusterPos.y < 0 || clusterPos.y >= dims.y) { - discard; - } - if (clusterPos.z < 0 || clusterPos.z > dims.z) { - discard; - } + <$fetchClusterInfo(fragPos)$>; vec4 midNormalCurvature; vec4 lowNormalCurvature; From 6af6b5fe41839f8155a468bd69f4e5edee02e554 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Mon, 15 Jan 2018 12:02:29 +0100 Subject: [PATCH 02/21] evalLocalLighting function created in LightLocal.slh --- libraries/render-utils/src/LightLocal.slh | 123 +++++++++++++++++- .../render-utils/src/local_lights_shading.slf | 114 +--------------- 2 files changed, 124 insertions(+), 113 deletions(-) diff --git a/libraries/render-utils/src/LightLocal.slh b/libraries/render-utils/src/LightLocal.slh index 69563d4985..dac5f74bc8 100644 --- a/libraries/render-utils/src/LightLocal.slh +++ b/libraries/render-utils/src/LightLocal.slh @@ -20,10 +20,10 @@ <@include LightClusterGrid.slh@> -<@func fetchClusterInfo(fragPos)@> +<@func fetchClusterInfo(fragWorldPos)@> // From frag world pos find the cluster - vec4 clusterEyePos = frustumGrid_worldToEye(<$fragPos$>); + vec4 clusterEyePos = frustumGrid_worldToEye(<$fragWorldPos$>); ivec3 clusterPos = frustumGrid_eyeToClusterPos(clusterEyePos.xyz); ivec3 cluster = clusterGrid_getCluster(frustumGrid_clusterToIndex(clusterPos)); @@ -31,7 +31,6 @@ if (numLights <= 0) { discard; } - int lightClusterOffset = cluster.z; ivec3 dims = frustumGrid.dims.xyz; if (clusterPos.x < 0 || clusterPos.x >= dims.x) { @@ -45,4 +44,120 @@ discard; } -<@endfunc@> \ No newline at end of file +<@endfunc@> + +vec4 evalLocalLighting(ivec3 cluster, int numLights, vec3 fragWorldPos, vec3 fragNormal, vec3 fragEyeDir, + vec4 midNormalCurvature, vec4 lowNormalCurvature, + float fragRoughness, float fragScattering, float fragMetallic, vec3 fragFresnel, vec3 fragAlbedo) { + vec4 _fragColor = vec4(0.0); + int lightClusterOffset = cluster.z; + + // Compute the rougness into gloss2 once: + float fragGloss2 = pow(fragRoughness + 0.001, 4.0); + bool withScattering = (fragScattering * isScatteringEnabled() > 0.0); + + int numLightTouching = 0; + for (int i = 0; i < cluster.x; i++) { + // Need the light now + int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset); + Light light = getLight(theLightIndex); + + // Clip againgst the light volume and Make the Light vector going from fragment to light center in world space + vec4 fragLightVecLen2; + vec4 fragLightDirLen; + + if (!lightVolume_clipFragToLightVolumePoint(light.volume, fragWorldPos.xyz, fragLightVecLen2)) { + continue; + } + + // Allright we re in the light sphere volume + fragLightDirLen.w = length(fragLightVecLen2.xyz); + fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w; + if (dot(fragNormal, fragLightDirLen.xyz) < 0.0) { + continue; + } + + numLightTouching++; + + vec3 diffuse = vec3(1.0); + vec3 specular = vec3(0.1); + + // Allright we re valid in the volume + float fragLightDistance = fragLightDirLen.w; + vec3 fragLightDir = fragLightDirLen.xyz; + + // Eval attenuation + float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance); + vec3 lightEnergy = radialAttenuation * getLightIrradiance(light); + + // Eval shading + if (withScattering) { + evalFragShadingScattering(diffuse, specular, fragNormal, fragLightDir, fragEyeDir, fragMetallic, fragFresnel, fragRoughness, fragAlbedo + ,fragScattering, midNormalCurvature, lowNormalCurvature ); + } else { + evalFragShadingGloss(diffuse, specular, fragNormal, fragLightDir, fragEyeDir, fragMetallic, fragFresnel, fragGloss2, fragAlbedo); + } + + diffuse *= lightEnergy * isDiffuseEnabled(); + specular *= lightEnergy * isSpecularEnabled(); + + _fragColor.rgb += diffuse; + _fragColor.rgb += specular; + } + + for (int i = cluster.x; i < numLights; i++) { + // Need the light now + int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset); + Light light = getLight(theLightIndex); + + // 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 (!lightVolume_clipFragToLightVolumePoint(light.volume, fragWorldPos.xyz, fragLightVecLen2)) { + continue; + } + + // Allright we re in the light sphere volume + fragLightDirLen.w = length(fragLightVecLen2.xyz); + fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w; + if (dot(fragNormal, fragLightDirLen.xyz) < 0.0) { + continue; + } + + // Check spot + if (!lightVolume_clipFragToLightVolumeSpotSide(light.volume, fragLightDirLen, cosSpotAngle)) { + continue; + } + + numLightTouching++; + + vec3 diffuse = vec3(1.0); + vec3 specular = vec3(0.1); + + // Allright we re valid in the volume + float fragLightDistance = fragLightDirLen.w; + vec3 fragLightDir = fragLightDirLen.xyz; + + // Eval attenuation + float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance); + float angularAttenuation = lightIrradiance_evalLightSpotAttenuation(light.irradiance, cosSpotAngle); + vec3 lightEnergy = radialAttenuation * angularAttenuation * getLightIrradiance(light); + + // Eval shading + if (withScattering) { + evalFragShadingScattering(diffuse, specular, fragNormal, fragLightDir, fragEyeDir, fragMetallic, fragFresnel, fragRoughness, fragAlbedo + ,fragScattering, midNormalCurvature, lowNormalCurvature ); + } else { + evalFragShadingGloss(diffuse, specular, fragNormal, fragLightDir, fragEyeDir, fragMetallic, fragFresnel, fragGloss2, fragAlbedo); + } + + diffuse *= lightEnergy * isDiffuseEnabled(); + specular *= lightEnergy * isSpecularEnabled(); + + _fragColor.rgb += diffuse; + _fragColor.rgb += specular; + } + return _fragColor; +} \ No newline at end of file diff --git a/libraries/render-utils/src/local_lights_shading.slf b/libraries/render-utils/src/local_lights_shading.slf index 3968ec9077..f302c6daba 100644 --- a/libraries/render-utils/src/local_lights_shading.slf +++ b/libraries/render-utils/src/local_lights_shading.slf @@ -38,9 +38,9 @@ void main(void) { // Frag pos in world mat4 invViewMat = getViewInverse(); - vec4 fragPos = invViewMat * fragPosition; + vec4 fragWorldPos = invViewMat * fragPosition; - <$fetchClusterInfo(fragPos)$>; + <$fetchClusterInfo(fragWorldPos)$>; vec4 midNormalCurvature; vec4 lowNormalCurvature; @@ -53,113 +53,9 @@ void main(void) { vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); - // Compute the rougness into gloss2 once: - float fragGloss2 = pow(frag.roughness + 0.001, 4.0); - bool withScattering = (frag.scattering * isScatteringEnabled() > 0.0); - - int numLightTouching = 0; - for (int i = 0; i < cluster.x; i++) { - // Need the light now - int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset); - Light light = getLight(theLightIndex); - - // Clip againgst the light volume and Make the Light vector going from fragment to light center in world space - vec4 fragLightVecLen2; - vec4 fragLightDirLen; - - if (!lightVolume_clipFragToLightVolumePoint(light.volume, fragPos.xyz, fragLightVecLen2)) { - continue; - } - - // Allright we re in the light sphere volume - fragLightDirLen.w = length(fragLightVecLen2.xyz); - fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w; - if (dot(frag.normal, fragLightDirLen.xyz) < 0.0) { - continue; - } - - numLightTouching++; - - vec3 diffuse = vec3(1.0); - vec3 specular = vec3(0.1); - - // Allright we re valid in the volume - float fragLightDistance = fragLightDirLen.w; - vec3 fragLightDir = fragLightDirLen.xyz; - - // Eval attenuation - float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance); - vec3 lightEnergy = radialAttenuation * getLightIrradiance(light); - - // Eval shading - if (withScattering) { - evalFragShadingScattering(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, frag.roughness, frag.albedo - ,frag.scattering, midNormalCurvature, lowNormalCurvature ); - } else { - evalFragShadingGloss(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, fragGloss2, frag.albedo); - } - - diffuse *= lightEnergy * isDiffuseEnabled(); - specular *= lightEnergy * isSpecularEnabled(); - - _fragColor.rgb += diffuse; - _fragColor.rgb += specular; - } - - for (int i = cluster.x; i < numLights; i++) { - // Need the light now - int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset); - Light light = getLight(theLightIndex); - - // 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 (!lightVolume_clipFragToLightVolumePoint(light.volume, fragPos.xyz, fragLightVecLen2)) { - continue; - } - - // Allright we re in the light sphere volume - fragLightDirLen.w = length(fragLightVecLen2.xyz); - fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w; - if (dot(frag.normal, fragLightDirLen.xyz) < 0.0) { - continue; - } - - // Check spot - if (!lightVolume_clipFragToLightVolumeSpotSide(light.volume, fragLightDirLen, cosSpotAngle)) { - continue; - } - - numLightTouching++; - - vec3 diffuse = vec3(1.0); - vec3 specular = vec3(0.1); - - // Allright we re valid in the volume - float fragLightDistance = fragLightDirLen.w; - vec3 fragLightDir = fragLightDirLen.xyz; - - // Eval attenuation - float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance); - float angularAttenuation = lightIrradiance_evalLightSpotAttenuation(light.irradiance, cosSpotAngle); - vec3 lightEnergy = radialAttenuation * angularAttenuation * getLightIrradiance(light); - - // Eval shading - if (withScattering) { - evalFragShadingScattering(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, frag.roughness, frag.albedo - ,frag.scattering, midNormalCurvature, lowNormalCurvature ); - } else { - evalFragShadingGloss(diffuse, specular, frag.normal, fragLightDir, fragEyeDir, frag.metallic, frag.fresnel, fragGloss2, frag.albedo); - } - - diffuse *= lightEnergy * isDiffuseEnabled(); - specular *= lightEnergy * isSpecularEnabled(); - - _fragColor.rgb += diffuse; - _fragColor.rgb += specular; - } + _fragColor = evalLocalLighting(cluster, numLights, fragWorldPos.xyz, frag.normal, fragEyeDir, + midNormalCurvature, lowNormalCurvature, frag.roughness, frag.scattering, + frag.metallic, frag.fresnel, frag.albedo); } From a3e50689cbf27d45a705385879e4012542abc715 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Mon, 15 Jan 2018 12:18:22 +0100 Subject: [PATCH 03/21] Modified light outline shader to use some factorized code --- .../render-utils/src/LightClusterGrid.slh | 27 +++++++++++++++++++ libraries/render-utils/src/LightLocal.slh | 26 ------------------ .../src/local_lights_drawOutline.slf | 24 ++--------------- 3 files changed, 29 insertions(+), 48 deletions(-) diff --git a/libraries/render-utils/src/LightClusterGrid.slh b/libraries/render-utils/src/LightClusterGrid.slh index 722d37814d..d2eb213c71 100644 --- a/libraries/render-utils/src/LightClusterGrid.slh +++ b/libraries/render-utils/src/LightClusterGrid.slh @@ -86,4 +86,31 @@ int clusterGrid_getClusterLightId(int index, int offset) { return (((elementIndex & 0x00000001) == 1) ? (element >> 16) : element) & 0x0000FFFF; } + +<@func fetchClusterInfo(fragWorldPos)@> + + // From frag world pos find the cluster + vec4 clusterEyePos = frustumGrid_worldToEye(<$fragWorldPos$>); + ivec3 clusterPos = frustumGrid_eyeToClusterPos(clusterEyePos.xyz); + + ivec3 cluster = clusterGrid_getCluster(frustumGrid_clusterToIndex(clusterPos)); + int numLights = cluster.x + cluster.y; + if (numLights <= 0) { + discard; + } + + ivec3 dims = frustumGrid.dims.xyz; + if (clusterPos.x < 0 || clusterPos.x >= dims.x) { + discard; + } + + if (clusterPos.y < 0 || clusterPos.y >= dims.y) { + discard; + } + if (clusterPos.z < 0 || clusterPos.z > dims.z) { + discard; + } + +<@endfunc@> + <@endif@> diff --git a/libraries/render-utils/src/LightLocal.slh b/libraries/render-utils/src/LightLocal.slh index dac5f74bc8..d9980b1fa6 100644 --- a/libraries/render-utils/src/LightLocal.slh +++ b/libraries/render-utils/src/LightLocal.slh @@ -20,32 +20,6 @@ <@include LightClusterGrid.slh@> -<@func fetchClusterInfo(fragWorldPos)@> - - // From frag world pos find the cluster - vec4 clusterEyePos = frustumGrid_worldToEye(<$fragWorldPos$>); - ivec3 clusterPos = frustumGrid_eyeToClusterPos(clusterEyePos.xyz); - - ivec3 cluster = clusterGrid_getCluster(frustumGrid_clusterToIndex(clusterPos)); - int numLights = cluster.x + cluster.y; - if (numLights <= 0) { - discard; - } - - ivec3 dims = frustumGrid.dims.xyz; - if (clusterPos.x < 0 || clusterPos.x >= dims.x) { - discard; - } - - if (clusterPos.y < 0 || clusterPos.y >= dims.y) { - discard; - } - if (clusterPos.z < 0 || clusterPos.z > dims.z) { - discard; - } - -<@endfunc@> - vec4 evalLocalLighting(ivec3 cluster, int numLights, vec3 fragWorldPos, vec3 fragNormal, vec3 fragEyeDir, vec4 midNormalCurvature, vec4 lowNormalCurvature, float fragRoughness, float fragScattering, float fragMetallic, vec3 fragFresnel, vec3 fragAlbedo) { diff --git a/libraries/render-utils/src/local_lights_drawOutline.slf b/libraries/render-utils/src/local_lights_drawOutline.slf index 3aa210a241..f7527d0542 100644 --- a/libraries/render-utils/src/local_lights_drawOutline.slf +++ b/libraries/render-utils/src/local_lights_drawOutline.slf @@ -54,34 +54,14 @@ void main(void) { mat4 invViewMat = getViewInverse(); vec4 fragPos = invViewMat * fragPosition; - // From frag world pos find the cluster - vec4 clusterEyePos = frustumGrid_worldToEye(fragPos); - ivec3 clusterPos = frustumGrid_eyeToClusterPos(clusterEyePos.xyz); - - ivec3 cluster = clusterGrid_getCluster(frustumGrid_clusterToIndex(clusterPos)); - int numLights = cluster.x + cluster.y; - if (numLights <= 0) { - discard; - } - int lightClusterOffset = cluster.z; - - ivec3 dims = frustumGrid.dims.xyz; - if (clusterPos.x < 0 || clusterPos.x >= dims.x) { - discard; - } - - if (clusterPos.y < 0 || clusterPos.y >= dims.y) { - discard; - } - if (clusterPos.z < 0 || clusterPos.z > dims.z) { - discard; - } + <$fetchClusterInfo(fragPos)$>; // Frag to eye vec vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); int numLightTouching = 0; + int lightClusterOffset = cluster.z; for (int i = 0; i < cluster.x; i++) { // Need the light now int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset); From 54eab1c878d1e5ccb534d1d605b9808254c9b6c2 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Mon, 15 Jan 2018 17:49:55 +0100 Subject: [PATCH 04/21] First working local lights on transparent objects --- libraries/model/src/model/Light.slh | 4 +- .../render-utils/src/DeferredGlobalLight.slh | 4 +- .../src/DeferredLightingEffect.cpp | 37 ++++++++++++---- .../render-utils/src/DeferredLightingEffect.h | 3 ++ libraries/render-utils/src/DrawHaze.cpp | 2 +- .../render-utils/src/ForwardGlobalLight.slh | 4 +- libraries/render-utils/src/Haze.slf | 2 +- .../render-utils/src/RenderDeferredTask.cpp | 19 +++++++- .../render-utils/src/RenderDeferredTask.h | 3 +- .../render-utils/src/RenderPipelines.cpp | 30 ++++++++----- .../render-utils/src/SubsurfaceScattering.cpp | 2 +- libraries/render-utils/src/ZoneRenderer.cpp | 2 +- .../render-utils/src/model_translucent.slf | 13 ++++++ .../render-utils/src/model_translucent.slv | 44 +++++++++++++++++++ .../src/model_translucent_fade.slf | 12 +++++ libraries/render-utils/src/overlay3D.slf | 2 +- .../src/overlay3D_translucent.slf | 2 +- .../subsurfaceScattering_drawScattering.slf | 4 +- .../render-utils/src/zone_drawKeyLight.slf | 2 +- libraries/render/src/render/ShapePipeline.cpp | 20 ++++++++- libraries/render/src/render/ShapePipeline.h | 9 ++++ 21 files changed, 181 insertions(+), 39 deletions(-) create mode 100644 libraries/render-utils/src/model_translucent.slv diff --git a/libraries/model/src/model/Light.slh b/libraries/model/src/model/Light.slh index 093a87adc8..a7960e473e 100644 --- a/libraries/model/src/model/Light.slh +++ b/libraries/model/src/model/Light.slh @@ -56,10 +56,10 @@ Light getLight(int index) { } <@else@> -uniform lightBuffer { +uniform keyLightBuffer { Light light; }; -Light getLight() { +Light getKeyLight() { return light; } diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index de2d41be6b..8406e4a0c5 100644 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -29,7 +29,7 @@ vec3 fragEyeDir = normalize(fragEyeVector); // Get light - Light light = getLight(); + Light light = getKeyLight(); LightAmbient lightAmbient = getLightAmbient(); vec3 lightDirection = getLightDirection(light); @@ -143,7 +143,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu <@func declareEvalLightmappedColor()@> vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 albedo, vec3 lightmap) { - Light light = getLight(); + Light light = getKeyLight(); LightAmbient ambient = getLightAmbient(); // Catch normals perpendicular to the projection plane, hence the magic number for the threshold diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 81a33f17e3..227c1ce339 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -42,6 +42,7 @@ using namespace render; struct LightLocations { int radius{ -1 }; + int keyLightBufferUnit{ -1 }; int lightBufferUnit{ -1 }; int ambientBufferUnit { -1 }; int lightIndexBufferUnit { -1 }; @@ -144,6 +145,29 @@ void DeferredLightingEffect::unsetKeyLightBatch(gpu::Batch& batch, int lightBuff } } +void DeferredLightingEffect::setupLocalLightsBatch(gpu::Batch& batch, + int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit, + const LightClustersPointer& lightClusters) { + // Bind the global list of lights and the visible lights this frame + batch.setUniformBuffer(_localLightLocations->lightBufferUnit, lightClusters->_lightStage->getLightArrayBuffer()); + + batch.setUniformBuffer(frustumGridBufferUnit, lightClusters->_frustumGridBuffer); + batch.setUniformBuffer(clusterGridBufferUnit, lightClusters->_clusterGridBuffer); + batch.setUniformBuffer(clusterContentBufferUnit, lightClusters->_clusterContentBuffer); +} + +void DeferredLightingEffect::unsetLocalLightsBatch(gpu::Batch& batch, int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit) { + if (clusterGridBufferUnit >= 0) { + batch.setUniformBuffer(clusterGridBufferUnit, nullptr); + } + if (clusterContentBufferUnit >= 0) { + batch.setUniformBuffer(clusterContentBufferUnit, nullptr); + } + if (frustumGridBufferUnit >= 0) { + batch.setUniformBuffer(frustumGridBufferUnit, nullptr); + } +} + static gpu::ShaderPointer makeLightProgram(const char* vertSource, const char* fragSource, LightLocationsPtr& locations) { auto VS = gpu::Shader::createVertex(std::string(vertSource)); auto PS = gpu::Shader::createPixel(std::string(fragSource)); @@ -186,6 +210,7 @@ static gpu::ShaderPointer makeLightProgram(const char* vertSource, const char* f locations->texcoordFrameTransform = program->getUniforms().findLocation("texcoordFrameTransform"); + locations->keyLightBufferUnit = program->getUniformBuffers().findLocation("keyLightBuffer"); locations->lightBufferUnit = program->getUniformBuffers().findLocation("lightBuffer"); locations->ambientBufferUnit = program->getUniformBuffers().findLocation("lightAmbientBuffer"); locations->lightIndexBufferUnit = program->getUniformBuffers().findLocation("lightIndexBuffer"); @@ -558,7 +583,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, batch._glUniform4fv(locations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform)); // Setup the global lighting - deferredLightingEffect->setupKeyLightBatch(args, batch, locations->lightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT); + deferredLightingEffect->setupKeyLightBatch(args, batch, locations->keyLightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT); // Haze if (haze) { @@ -567,7 +592,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, batch.draw(gpu::TRIANGLE_STRIP, 4); - deferredLightingEffect->unsetKeyLightBatch(batch, locations->lightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT); + deferredLightingEffect->unsetKeyLightBatch(batch, locations->keyLightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT); for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) { batch.setResourceTexture(SHADOW_MAP_UNIT+i, nullptr); @@ -622,12 +647,8 @@ void RenderDeferredLocals::run(const render::RenderContextPointer& renderContext auto& lightIndices = lightClusters->_visibleLightIndices; if (!lightIndices.empty() && lightIndices[0] > 0) { - // Bind the global list of lights and the visible lights this frame - batch.setUniformBuffer(deferredLightingEffect->_localLightLocations->lightBufferUnit, lightClusters->_lightStage->getLightArrayBuffer()); - - batch.setUniformBuffer(LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT, lightClusters->_frustumGridBuffer); - batch.setUniformBuffer(LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, lightClusters->_clusterGridBuffer); - batch.setUniformBuffer(LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, lightClusters->_clusterContentBuffer); + deferredLightingEffect->setupLocalLightsBatch(batch, LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT, + lightClusters); // Local light pipeline batch.setPipeline(deferredLightingEffect->_localLight); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 212d17db12..1607cb2c85 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -51,6 +51,9 @@ public: void setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit); void unsetKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit); + void setupLocalLightsBatch(gpu::Batch& batch, int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit, const LightClustersPointer& lightClusters); + void unsetLocalLightsBatch(gpu::Batch& batch, int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit); + void setShadowMapEnabled(bool enable) { _shadowMapEnabled = enable; }; void setAmbientOcclusionEnabled(bool enable) { _ambientOcclusionEnabled = enable; } bool isAmbientOcclusionEnabled() const { return _ambientOcclusionEnabled; } diff --git a/libraries/render-utils/src/DrawHaze.cpp b/libraries/render-utils/src/DrawHaze.cpp index da07f5bd9b..783dadba7c 100644 --- a/libraries/render-utils/src/DrawHaze.cpp +++ b/libraries/render-utils/src/DrawHaze.cpp @@ -147,7 +147,7 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), HazeEffect_TransformBufferSlot)); slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), HazeEffect_ColorMapSlot)); slotBindings.insert(gpu::Shader::Binding(std::string("linearDepthMap"), HazeEffect_LinearDepthMapSlot)); - slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), HazeEffect_LightingMapSlot)); + slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), HazeEffect_LightingMapSlot)); gpu::Shader::makeProgram(*program, slotBindings); _hazePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); diff --git a/libraries/render-utils/src/ForwardGlobalLight.slh b/libraries/render-utils/src/ForwardGlobalLight.slh index aba0498ef5..cde37e0ba7 100644 --- a/libraries/render-utils/src/ForwardGlobalLight.slh +++ b/libraries/render-utils/src/ForwardGlobalLight.slh @@ -29,7 +29,7 @@ vec3 fragEyeDir = normalize(fragEyeVector); // Get light - Light light = getLight(); + Light light = getKeyLight(); LightAmbient lightAmbient = getLightAmbient(); vec3 lightDirection = getLightDirection(light); @@ -139,7 +139,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu <@func declareEvalLightmappedColor()@> vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 normal, vec3 albedo, vec3 lightmap) { - Light light = getLight(); + Light light = getKeyLight(); LightAmbient ambient = getLightAmbient(); // Catch normals perpendicular to the projection plane, hence the magic number for the threshold diff --git a/libraries/render-utils/src/Haze.slf b/libraries/render-utils/src/Haze.slf index 0270aa58f0..b3b1e6d979 100644 --- a/libraries/render-utils/src/Haze.slf +++ b/libraries/render-utils/src/Haze.slf @@ -53,7 +53,7 @@ void main(void) { vec4 worldFragPos = viewInverse * eyeFragPos; vec4 worldEyePos = viewInverse[3]; - Light light = getLight(); + Light light = getKeyLight(); vec3 lightDirection = getLightDirection(light); outFragColor = computeHazeColor(fragColor, eyeFragPos.xyz, worldFragPos.xyz, worldEyePos.y, lightDirection); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index f860c0494e..3aa8538fbc 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -12,6 +12,8 @@ #include "RenderDeferredTask.h" +#include + #include #include #include @@ -167,7 +169,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren task.addJob("DrawHazeDeferred", drawHazeInputs); // Render transparent objects forward in LightingBuffer - const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel).asVarying(); + const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel, lightClusters).asVarying(); task.addJob("DrawTransparentDeferred", transparentsInputs, shapePlumber); // Light Cluster Grid Debuging job @@ -314,6 +316,8 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& const auto& inItems = inputs.get0(); const auto& lightingModel = inputs.get1(); + const auto& lightClusters = inputs.get2(); + auto deferredLightingEffect = DependencyManager::get(); RenderArgs* args = renderContext->args; @@ -335,7 +339,13 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& // Setup lighting model for all items; batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer()); - // Setup haze iff curretn zone has haze + deferredLightingEffect->setupLocalLightsBatch(batch, + render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, + render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, + render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT, + lightClusters); + + // Setup haze if current zone has haze auto hazeStage = args->_scene->getStage(); if (hazeStage && hazeStage->_currentFrame._hazes.size() > 0) { model::HazePointer hazePointer = hazeStage->getHaze(hazeStage->_currentFrame._hazes.front()); @@ -355,6 +365,11 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs& args->_batch = nullptr; args->_globalShapeKey = 0; + + deferredLightingEffect->unsetLocalLightsBatch(batch, + render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, + render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, + render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT); }); config->setNumDrawn((int)inItems.size()); diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index e41b7edc77..7e439a547f 100644 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -15,6 +15,7 @@ #include #include #include "LightingModel.h" +#include "LightClusters.h" class BeginGPURangeTimer { public: @@ -65,7 +66,7 @@ protected: class DrawDeferred { public: - using Inputs = render::VaryingSet2 ; + using Inputs = render::VaryingSet3 ; using Config = DrawConfig; using JobModel = render::Job::ModelI; diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index 7f644add72..668d524018 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -29,6 +29,7 @@ #include "model_lightmap_fade_vert.h" #include "model_lightmap_normal_map_fade_vert.h" +#include "model_translucent_vert.h" #include "skin_model_fade_vert.h" #include "skin_model_normal_map_fade_vert.h" @@ -188,6 +189,7 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip auto modelNormalMapVertex = gpu::Shader::createVertex(std::string(model_normal_map_vert)); auto modelLightmapVertex = gpu::Shader::createVertex(std::string(model_lightmap_vert)); auto modelLightmapNormalMapVertex = gpu::Shader::createVertex(std::string(model_lightmap_normal_map_vert)); + auto modelTranslucentVertex = gpu::Shader::createVertex(std::string(model_translucent_vert)); auto modelShadowVertex = gpu::Shader::createVertex(std::string(model_shadow_vert)); auto skinModelVertex = gpu::Shader::createVertex(std::string(skin_model_vert)); auto skinModelNormalMapVertex = gpu::Shader::createVertex(std::string(skin_model_normal_map_vert)); @@ -196,9 +198,13 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip auto modelLightmapNormalMapFadeVertex = gpu::Shader::createVertex(std::string(model_lightmap_normal_map_fade_vert)); auto skinModelFadeVertex = gpu::Shader::createVertex(std::string(skin_model_fade_vert)); auto skinModelNormalMapFadeVertex = gpu::Shader::createVertex(std::string(skin_model_normal_map_fade_vert)); + auto skinModelTranslucentVertex = skinModelFadeVertex; // We use the same because it ouputs world position per vertex + auto skinModelNormalMapTranslucentVertex = skinModelNormalMapFadeVertex; // We use the same because it ouputs world position per vertex auto modelFadeVertex = gpu::Shader::createVertex(std::string(model_fade_vert)); + auto modelTranslucentFadeVertex = modelTranslucentVertex; // We use the same because it ouputs world position per vertex auto modelNormalMapFadeVertex = gpu::Shader::createVertex(std::string(model_normal_map_fade_vert)); + auto modelNormalMapTranslucentVertex = modelNormalMapFadeVertex; // We use the same because it ouputs world position per vertex auto simpleFadeVertex = gpu::Shader::createVertex(std::string(simple_fade_vert)); auto modelShadowFadeVertex = gpu::Shader::createVertex(std::string(model_shadow_fade_vert)); auto skinModelShadowFadeVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_fade_vert)); @@ -289,7 +295,7 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip // Translucents addPipeline( Key::Builder().withMaterial().withTranslucent(), - modelVertex, modelTranslucentPixel, nullptr, nullptr); + modelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); addPipeline( Key::Builder().withTranslucent(), simpleVertex, simpleTranslucentPixel, nullptr, nullptr); @@ -301,21 +307,21 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip simpleVertex, simpleTranslucentUnlitPixel, nullptr, nullptr); addPipeline( Key::Builder().withMaterial().withTranslucent().withTangents(), - modelNormalMapVertex, modelTranslucentPixel, nullptr, nullptr); + modelNormalMapTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); addPipeline( Key::Builder().withMaterial().withTranslucent().withSpecular(), - modelVertex, modelTranslucentPixel, nullptr, nullptr); + modelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); addPipeline( Key::Builder().withMaterial().withTranslucent().withTangents().withSpecular(), - modelNormalMapVertex, modelTranslucentPixel, nullptr, nullptr); + modelNormalMapTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); addPipeline( // FIXME: Ignore lightmap for translucents meshpart Key::Builder().withMaterial().withTranslucent().withLightmap(), - modelVertex, modelTranslucentPixel, nullptr, nullptr); + modelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); // Same thing but with Fade on addPipeline( Key::Builder().withMaterial().withTranslucent().withFade(), - modelFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter); + modelTranslucentFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withTranslucent().withFade(), simpleFadeVertex, simpleTranslucentFadePixel, batchSetter, itemSetter); @@ -396,16 +402,16 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip // Skinned and Translucent addPipeline( Key::Builder().withMaterial().withSkinned().withTranslucent(), - skinModelVertex, modelTranslucentPixel, nullptr, nullptr); + skinModelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); addPipeline( Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents(), - skinModelNormalMapVertex, modelTranslucentPixel, nullptr, nullptr); + skinModelNormalMapTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); addPipeline( Key::Builder().withMaterial().withSkinned().withTranslucent().withSpecular(), - skinModelVertex, modelTranslucentPixel, nullptr, nullptr); + skinModelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); addPipeline( Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents().withSpecular(), - skinModelNormalMapVertex, modelTranslucentPixel, nullptr, nullptr); + skinModelNormalMapTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); // Same thing but with Fade on addPipeline( Key::Builder().withMaterial().withSkinned().withTranslucent().withFade(), @@ -565,9 +571,9 @@ void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderAr batchSetter(pipeline, batch, args); // Set the light - if (pipeline.locations->lightBufferUnit >= 0) { + if (pipeline.locations->keyLightBufferUnit >= 0) { DependencyManager::get()->setupKeyLightBatch(args, batch, - pipeline.locations->lightBufferUnit, + pipeline.locations->keyLightBufferUnit, pipeline.locations->lightAmbientBufferUnit, pipeline.locations->lightAmbientMapUnit); } diff --git a/libraries/render-utils/src/SubsurfaceScattering.cpp b/libraries/render-utils/src/SubsurfaceScattering.cpp index 1786898e57..2183f95565 100644 --- a/libraries/render-utils/src/SubsurfaceScattering.cpp +++ b/libraries/render-utils/src/SubsurfaceScattering.cpp @@ -463,7 +463,7 @@ gpu::PipelinePointer DebugSubsurfaceScattering::getScatteringPipeline() { gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), ScatteringTask_FrameTransformSlot)); slotBindings.insert(gpu::Shader::Binding(std::string("scatteringParamsBuffer"), ScatteringTask_ParamSlot)); - slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), ScatteringTask_LightSlot)); + slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), ScatteringTask_LightSlot)); slotBindings.insert(gpu::Shader::Binding(std::string("scatteringLUT"), ScatteringTask_ScatteringTableSlot)); slotBindings.insert(gpu::Shader::Binding(std::string("curvatureMap"), ScatteringTask_CurvatureMapSlot)); diff --git a/libraries/render-utils/src/ZoneRenderer.cpp b/libraries/render-utils/src/ZoneRenderer.cpp index c0d01c2eaf..ce2957dc9f 100644 --- a/libraries/render-utils/src/ZoneRenderer.cpp +++ b/libraries/render-utils/src/ZoneRenderer.cpp @@ -83,7 +83,7 @@ const gpu::PipelinePointer& DebugZoneLighting::getKeyLightPipeline() { gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), ZONE_DEFERRED_TRANSFORM_BUFFER)); - slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), ZONE_KEYLIGHT_BUFFER)); + slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), ZONE_KEYLIGHT_BUFFER)); gpu::Shader::makeProgram(*program, slotBindings); diff --git a/libraries/render-utils/src/model_translucent.slf b/libraries/render-utils/src/model_translucent.slf index 38f162fdc3..5f61aea889 100644 --- a/libraries/render-utils/src/model_translucent.slf +++ b/libraries/render-utils/src/model_translucent.slf @@ -18,6 +18,8 @@ <$declareEvalGlobalLightingAlphaBlended()$> +<@include LightLocal.slh@> + <@include gpu/Transform.slh@> <$declareStandardCameraTransform()$> @@ -27,6 +29,7 @@ in vec2 _texCoord0; in vec2 _texCoord1; in vec4 _position; +in vec4 _worldPosition; in vec3 _normal; in vec3 _color; in float _alpha; @@ -66,6 +69,16 @@ void main(void) { TransformCamera cam = getTransformCamera(); + <$fetchClusterInfo(_worldPosition)$>; + + vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0)); + vec3 fragEyeDir = normalize(fragEyeVector); + + vec4 localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, fragNormal, fragEyeDir, + vec4(0), vec4(0), roughness, 0.0, + metallic, fresnel, albedo); + emissive += localLighting.rgb; + _fragColor = vec4(evalGlobalLightingAlphaBlendedWithHaze( cam._viewInverse, 1.0, diff --git a/libraries/render-utils/src/model_translucent.slv b/libraries/render-utils/src/model_translucent.slv new file mode 100644 index 0000000000..2fe4c511f0 --- /dev/null +++ b/libraries/render-utils/src/model_translucent.slv @@ -0,0 +1,44 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// model_translucent.slv +// vertex shader +// +// Created by Olivier Prat on 15/01/18. +// Copyright 2018 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 +// + +<@include gpu/Inputs.slh@> +<@include gpu/Color.slh@> +<@include gpu/Transform.slh@> +<$declareStandardTransform()$> + +<@include MaterialTextures.slh@> +<$declareMaterialTexMapArrayBuffer()$> + +out float _alpha; +out vec2 _texCoord0; +out vec2 _texCoord1; +out vec4 _position; +out vec4 _worldPosition; +out vec3 _normal; +out vec3 _color; + +void main(void) { + _color = colorToLinearRGB(inColor.xyz); + _alpha = inColor.w; + + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$> + <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord1)$> + + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + <$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$> + <$transformModelToWorldPos(obj, inPosition, _worldPosition)$> + <$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$> +} diff --git a/libraries/render-utils/src/model_translucent_fade.slf b/libraries/render-utils/src/model_translucent_fade.slf index 9d5477304c..e07730a07e 100644 --- a/libraries/render-utils/src/model_translucent_fade.slf +++ b/libraries/render-utils/src/model_translucent_fade.slf @@ -18,6 +18,8 @@ <$declareEvalGlobalLightingAlphaBlended()$> +<@include LightLocal.slh@> + <@include gpu/Transform.slh@> <$declareStandardCameraTransform()$> @@ -76,6 +78,16 @@ void main(void) { TransformCamera cam = getTransformCamera(); + <$fetchClusterInfo(_worldPosition)$>; + + vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0)); + vec3 fragEyeDir = normalize(fragEyeVector); + + vec4 localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, fragNormal, fragEyeDir, + vec4(0), vec4(0), roughness, 0.0, + metallic, fresnel, albedo); + emissive += localLighting.rgb; + _fragColor = vec4(evalGlobalLightingAlphaBlendedWithHaze( cam._viewInverse, 1.0, diff --git a/libraries/render-utils/src/overlay3D.slf b/libraries/render-utils/src/overlay3D.slf index 0cb3340845..683e1420bc 100644 --- a/libraries/render-utils/src/overlay3D.slf +++ b/libraries/render-utils/src/overlay3D.slf @@ -27,7 +27,7 @@ vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 fresnel, float roughness, float opacity) { // Need the light now - Light light = getLight(); + Light light = getKeyLight(); vec3 lightDirection = getLightDirection(light); vec3 lightIrradiance = getLightIrradiance(light); diff --git a/libraries/render-utils/src/overlay3D_translucent.slf b/libraries/render-utils/src/overlay3D_translucent.slf index 9bdac2d21f..c39d4b0c3b 100644 --- a/libraries/render-utils/src/overlay3D_translucent.slf +++ b/libraries/render-utils/src/overlay3D_translucent.slf @@ -27,7 +27,7 @@ vec4 evalGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 albedo, float metallic, vec3 fresnel, float roughness, float opacity) { // Need the light now - Light light = getLight(); + Light light = getKeyLight(); vec3 lightDirection = getLightDirection(light); vec3 lightIrradiance = getLightIrradiance(light); diff --git a/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf b/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf index 981993615c..6f52e02040 100644 --- a/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf +++ b/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf @@ -42,7 +42,7 @@ vec3 evalScatteringBRDF(vec2 texcoord) { vec3 fragNormal = vec3((normal)); // Get light - Light light = getLight(); + Light light = getKeyLight(); vec3 fresnel = vec3(0.028); // Default Di-electric fresnel value for skin float metallic = 0.0; @@ -65,7 +65,7 @@ vec3 drawScatteringTableUV(vec2 cursor, vec2 texcoord) { float curvature = unpackCurvature(diffusedCurvature.w); // Get light - Light light = getLight(); + Light light = getKeyLight(); vec3 fresnel = vec3(0.028); // Default Di-electric fresnel value for skin vec3 fragLightDir = -normalize(getLightDirection(light)); diff --git a/libraries/render-utils/src/zone_drawKeyLight.slf b/libraries/render-utils/src/zone_drawKeyLight.slf index e96239b6dc..f7caf9b44a 100644 --- a/libraries/render-utils/src/zone_drawKeyLight.slf +++ b/libraries/render-utils/src/zone_drawKeyLight.slf @@ -25,7 +25,7 @@ void main(void) { <$evalGlobeWidget()$> - Light light = getLight(); + Light light = getKeyLight(); vec3 lightDirection = normalize(getLightDirection(light)); vec3 lightIrradiance = getLightIrradiance(light); vec3 color = vec3(0.0); diff --git a/libraries/render/src/render/ShapePipeline.cpp b/libraries/render/src/render/ShapePipeline.cpp index 4254280fa1..27fe6604ff 100644 --- a/libraries/render/src/render/ShapePipeline.cpp +++ b/libraries/render/src/render/ShapePipeline.cpp @@ -70,6 +70,8 @@ void ShapePlumber::addPipeline(const Key& key, const gpu::ShaderPointer& program void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& program, const gpu::StatePointer& state, BatchSetter batchSetter, ItemSetter itemSetter) { + ShapeKey key{ filter._flags }; + gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), Slot::BUFFER::LIGHTING_MODEL)); slotBindings.insert(gpu::Shader::Binding(std::string("skinClusterBuffer"), Slot::BUFFER::SKINNING)); @@ -82,6 +84,7 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), Slot::MAP::EMISSIVE_LIGHTMAP)); slotBindings.insert(gpu::Shader::Binding(std::string("occlusionMap"), Slot::MAP::OCCLUSION)); slotBindings.insert(gpu::Shader::Binding(std::string("scatteringMap"), Slot::MAP::SCATTERING)); + slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), Slot::BUFFER::KEY_LIGHT)); slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), Slot::BUFFER::LIGHT)); slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), Slot::BUFFER::LIGHT_AMBIENT_BUFFER)); slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), Slot::MAP::LIGHT_AMBIENT)); @@ -89,6 +92,12 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p slotBindings.insert(gpu::Shader::Binding(std::string("fadeParametersBuffer"), Slot::BUFFER::FADE_PARAMETERS)); slotBindings.insert(gpu::Shader::Binding(std::string("hazeParametersBuffer"), Slot::BUFFER::HAZE_MODEL)); + if (key.isTranslucent()) { + slotBindings.insert(gpu::Shader::Binding(std::string("clusterGridBuffer"), Slot::BUFFER::LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("clusterContentBuffer"), Slot::BUFFER::LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("frustumGridBuffer"), Slot::BUFFER::LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT)); + } + gpu::Shader::makeProgram(*program, slotBindings); auto locations = std::make_shared(); @@ -103,14 +112,23 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p locations->skinClusterBufferUnit = program->getUniformBuffers().findLocation("skinClusterBuffer"); locations->materialBufferUnit = program->getUniformBuffers().findLocation("materialBuffer"); locations->texMapArrayBufferUnit = program->getUniformBuffers().findLocation("texMapArrayBuffer"); + locations->keyLightBufferUnit = program->getUniformBuffers().findLocation("keyLightBuffer"); locations->lightBufferUnit = program->getUniformBuffers().findLocation("lightBuffer"); locations->lightAmbientBufferUnit = program->getUniformBuffers().findLocation("lightAmbientBuffer"); locations->lightAmbientMapUnit = program->getTextures().findLocation("skyboxMap"); locations->fadeMaskTextureUnit = program->getTextures().findLocation("fadeMaskMap"); locations->fadeParameterBufferUnit = program->getUniformBuffers().findLocation("fadeParametersBuffer"); locations->hazeParameterBufferUnit = program->getUniformBuffers().findLocation("hazeParametersBuffer"); + if (key.isTranslucent()) { + locations->lightClusterGridBufferUnit = program->getUniformBuffers().findLocation("clusterGridBuffer"); + locations->lightClusterContentBufferUnit = program->getUniformBuffers().findLocation("clusterContentBuffer"); + locations->lightClusterFrustumBufferUnit = program->getUniformBuffers().findLocation("frustumGridBuffer"); + } else { + locations->lightClusterGridBufferUnit = -1; + locations->lightClusterContentBufferUnit = -1; + locations->lightClusterFrustumBufferUnit = -1; + } - ShapeKey key{filter._flags}; auto gpuPipeline = gpu::Pipeline::create(program, state); auto shapePipeline = std::make_shared(gpuPipeline, locations, batchSetter, itemSetter); addPipelineHelper(filter, key, 0, shapePipeline); diff --git a/libraries/render/src/render/ShapePipeline.h b/libraries/render/src/render/ShapePipeline.h index be77e2f95e..c84f7efba5 100644 --- a/libraries/render/src/render/ShapePipeline.h +++ b/libraries/render/src/render/ShapePipeline.h @@ -235,10 +235,15 @@ public: MATERIAL, TEXMAPARRAY, LIGHTING_MODEL, + KEY_LIGHT, LIGHT, LIGHT_AMBIENT_BUFFER, HAZE_MODEL, FADE_PARAMETERS, + LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT, + LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, + LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, + }; enum MAP { @@ -266,12 +271,16 @@ public: int skinClusterBufferUnit; int materialBufferUnit; int texMapArrayBufferUnit; + int keyLightBufferUnit; int lightBufferUnit; int lightAmbientBufferUnit; int lightAmbientMapUnit; int fadeMaskTextureUnit; int fadeParameterBufferUnit; int hazeParameterBufferUnit; + int lightClusterGridBufferUnit; + int lightClusterContentBufferUnit; + int lightClusterFrustumBufferUnit; }; using LocationsPointer = std::shared_ptr; From 32445a566017b9c59cf499e6cda2e67b25a08bb8 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Mon, 15 Jan 2018 18:18:13 +0100 Subject: [PATCH 05/21] Updated pipelines --- .../render-utils/src/RenderPipelines.cpp | 8 ++-- .../src/model_translucent_fade.slv | 44 +++++++++++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 libraries/render-utils/src/model_translucent_fade.slv diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index 668d524018..e9b1b59016 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -30,6 +30,7 @@ #include "model_lightmap_fade_vert.h" #include "model_lightmap_normal_map_fade_vert.h" #include "model_translucent_vert.h" +#include "model_translucent_fade_vert.h" #include "skin_model_fade_vert.h" #include "skin_model_normal_map_fade_vert.h" @@ -190,6 +191,7 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip auto modelLightmapVertex = gpu::Shader::createVertex(std::string(model_lightmap_vert)); auto modelLightmapNormalMapVertex = gpu::Shader::createVertex(std::string(model_lightmap_normal_map_vert)); auto modelTranslucentVertex = gpu::Shader::createVertex(std::string(model_translucent_vert)); + auto modelTranslucentFadeVertex = gpu::Shader::createVertex(std::string(model_translucent_fade_vert)); auto modelShadowVertex = gpu::Shader::createVertex(std::string(model_shadow_vert)); auto skinModelVertex = gpu::Shader::createVertex(std::string(skin_model_vert)); auto skinModelNormalMapVertex = gpu::Shader::createVertex(std::string(skin_model_normal_map_vert)); @@ -202,9 +204,7 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip auto skinModelNormalMapTranslucentVertex = skinModelNormalMapFadeVertex; // We use the same because it ouputs world position per vertex auto modelFadeVertex = gpu::Shader::createVertex(std::string(model_fade_vert)); - auto modelTranslucentFadeVertex = modelTranslucentVertex; // We use the same because it ouputs world position per vertex auto modelNormalMapFadeVertex = gpu::Shader::createVertex(std::string(model_normal_map_fade_vert)); - auto modelNormalMapTranslucentVertex = modelNormalMapFadeVertex; // We use the same because it ouputs world position per vertex auto simpleFadeVertex = gpu::Shader::createVertex(std::string(simple_fade_vert)); auto modelShadowFadeVertex = gpu::Shader::createVertex(std::string(model_shadow_fade_vert)); auto skinModelShadowFadeVertex = gpu::Shader::createVertex(std::string(skin_model_shadow_fade_vert)); @@ -307,13 +307,13 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip simpleVertex, simpleTranslucentUnlitPixel, nullptr, nullptr); addPipeline( Key::Builder().withMaterial().withTranslucent().withTangents(), - modelNormalMapTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); + modelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); addPipeline( Key::Builder().withMaterial().withTranslucent().withSpecular(), modelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); addPipeline( Key::Builder().withMaterial().withTranslucent().withTangents().withSpecular(), - modelNormalMapTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); + modelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); addPipeline( // FIXME: Ignore lightmap for translucents meshpart Key::Builder().withMaterial().withTranslucent().withLightmap(), diff --git a/libraries/render-utils/src/model_translucent_fade.slv b/libraries/render-utils/src/model_translucent_fade.slv new file mode 100644 index 0000000000..eaabdd27e8 --- /dev/null +++ b/libraries/render-utils/src/model_translucent_fade.slv @@ -0,0 +1,44 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// model_translucent_fade.slv +// vertex shader +// +// Created by Olivier Prat on 15/01/18. +// Copyright 2018 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 +// + +<@include gpu/Inputs.slh@> +<@include gpu/Color.slh@> +<@include gpu/Transform.slh@> +<$declareStandardTransform()$> + +<@include MaterialTextures.slh@> +<$declareMaterialTexMapArrayBuffer()$> + +out float _alpha; +out vec2 _texCoord0; +out vec2 _texCoord1; +out vec4 _position; +out vec4 _worldPosition; +out vec3 _normal; +out vec3 _color; + +void main(void) { + _color = colorToLinearRGB(inColor.xyz); + _alpha = inColor.w; + + TexMapArray texMapArray = getTexMapArray(); + <$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _texCoord0)$> + <$evalTexMapArrayTexcoord1(texMapArray, inTexCoord0, _texCoord1)$> + + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + <$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$> + <$transformModelToWorldPos(obj, inPosition, _worldPosition)$> + <$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$> +} From 3382a35c3fff97c3897b4e39eff413eb6abff96a Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Tue, 16 Jan 2018 12:13:45 +0100 Subject: [PATCH 06/21] Fixed bug due to incorrect discard of fragments with no local lights --- .../render-utils/src/DeferredGlobalLight.slh | 15 +++++--- .../render-utils/src/LightClusterGrid.slh | 38 ++++++++++++------- libraries/render-utils/src/LightLocal.slh | 31 +++++++++------ .../src/local_lights_drawOutline.slf | 3 ++ .../render-utils/src/local_lights_shading.slf | 5 ++- .../render-utils/src/model_translucent.slf | 17 +++++---- .../src/model_translucent_fade.slf | 17 +++++---- .../src/overlay3D_model_translucent.slf | 2 +- .../src/simple_transparent_textured.slf | 2 +- .../src/simple_transparent_textured_fade.slf | 2 +- 10 files changed, 81 insertions(+), 51 deletions(-) diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index 8406e4a0c5..02ab97b825 100644 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -171,9 +171,11 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur <$declareLightingAmbient(1, 1, 1)$> <$declareLightingDirectional()$> -vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity) { +vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity, vec3 prevLighting) { <$prepareGlobalLight()$> + color = prevLighting; + color += emissive * isEmissiveEnabled(); // Ambient @@ -195,25 +197,26 @@ vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, fl vec3 evalGlobalLightingAlphaBlendedWithHaze( mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, - vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity) + vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity, vec3 prevLighting) { <$prepareGlobalLight()$> + color = prevLighting; + color += emissive * isEmissiveEnabled(); // Ambient vec3 ambientDiffuse; vec3 ambientSpecular; evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, obscurance); - color += ambientDiffuse; - color += ambientSpecular / opacity; // Directional vec3 directionalDiffuse; vec3 directionalSpecular; evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, fragEyeDir, fragNormal, roughness, metallic, fresnel, albedo, shadowAttenuation); - color += directionalDiffuse; - color += directionalSpecular / opacity; + + color += ambientDiffuse + directionalDiffuse; + color += (ambientSpecular + directionalSpecular) / opacity; // Haze if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) { diff --git a/libraries/render-utils/src/LightClusterGrid.slh b/libraries/render-utils/src/LightClusterGrid.slh index d2eb213c71..60daa520a3 100644 --- a/libraries/render-utils/src/LightClusterGrid.slh +++ b/libraries/render-utils/src/LightClusterGrid.slh @@ -95,22 +95,32 @@ int clusterGrid_getClusterLightId(int index, int offset) { ivec3 cluster = clusterGrid_getCluster(frustumGrid_clusterToIndex(clusterPos)); int numLights = cluster.x + cluster.y; - if (numLights <= 0) { - discard; - } - ivec3 dims = frustumGrid.dims.xyz; - if (clusterPos.x < 0 || clusterPos.x >= dims.x) { - discard; - } - - if (clusterPos.y < 0 || clusterPos.y >= dims.y) { - discard; - } - if (clusterPos.z < 0 || clusterPos.z > dims.z) { - discard; - } <@endfunc@> +bool hasLocalLights(int numLights, ivec3 clusterPos, ivec3 dims) { +/* + if (numLights <= 0) { + return false; + } + + if (clusterPos.x < 0 || clusterPos.x >= dims.x) { + return false; + } + + if (clusterPos.y < 0 || clusterPos.y >= dims.y) { + return false; + } + if (clusterPos.z < 0 || clusterPos.z > dims.z) { + return false; + } + return true; +*/ + return numLights>0 + && all(greaterThanEqual(clusterPos, ivec3(0))) + && all(lessThan(clusterPos.xy, dims.xy)) + && clusterPos.z <= dims.z; +} + <@endif@> diff --git a/libraries/render-utils/src/LightLocal.slh b/libraries/render-utils/src/LightLocal.slh index d9980b1fa6..895955269d 100644 --- a/libraries/render-utils/src/LightLocal.slh +++ b/libraries/render-utils/src/LightLocal.slh @@ -22,8 +22,11 @@ vec4 evalLocalLighting(ivec3 cluster, int numLights, vec3 fragWorldPos, vec3 fragNormal, vec3 fragEyeDir, vec4 midNormalCurvature, vec4 lowNormalCurvature, - float fragRoughness, float fragScattering, float fragMetallic, vec3 fragFresnel, vec3 fragAlbedo) { - vec4 _fragColor = vec4(0.0); + float fragRoughness, float fragScattering, float fragMetallic, vec3 fragFresnel, vec3 fragAlbedo, + float opacity) { + vec4 fragColor = vec4(0.0); + vec3 fragSpecular = vec3(0.0); + vec3 fragDiffuse = vec3(0.0); int lightClusterOffset = cluster.z; // Compute the rougness into gloss2 once: @@ -72,11 +75,11 @@ vec4 evalLocalLighting(ivec3 cluster, int numLights, vec3 fragWorldPos, vec3 fra evalFragShadingGloss(diffuse, specular, fragNormal, fragLightDir, fragEyeDir, fragMetallic, fragFresnel, fragGloss2, fragAlbedo); } - diffuse *= lightEnergy * isDiffuseEnabled(); - specular *= lightEnergy * isSpecularEnabled(); + diffuse *= lightEnergy; + specular *= lightEnergy; - _fragColor.rgb += diffuse; - _fragColor.rgb += specular; + fragDiffuse.rgb += diffuse; + fragSpecular.rgb += specular; } for (int i = cluster.x; i < numLights; i++) { @@ -127,11 +130,17 @@ vec4 evalLocalLighting(ivec3 cluster, int numLights, vec3 fragWorldPos, vec3 fra evalFragShadingGloss(diffuse, specular, fragNormal, fragLightDir, fragEyeDir, fragMetallic, fragFresnel, fragGloss2, fragAlbedo); } - diffuse *= lightEnergy * isDiffuseEnabled(); - specular *= lightEnergy * isSpecularEnabled(); + diffuse *= lightEnergy; + specular *= lightEnergy; - _fragColor.rgb += diffuse; - _fragColor.rgb += specular; + fragDiffuse.rgb += diffuse; + fragSpecular.rgb += specular; } - return _fragColor; + + fragDiffuse *= isDiffuseEnabled(); + fragSpecular *= isSpecularEnabled(); + + fragColor.rgb += fragDiffuse; + fragColor.rgb += fragSpecular / opacity; + return fragColor; } \ No newline at end of file diff --git a/libraries/render-utils/src/local_lights_drawOutline.slf b/libraries/render-utils/src/local_lights_drawOutline.slf index f7527d0542..de49478eba 100644 --- a/libraries/render-utils/src/local_lights_drawOutline.slf +++ b/libraries/render-utils/src/local_lights_drawOutline.slf @@ -55,6 +55,9 @@ void main(void) { vec4 fragPos = invViewMat * fragPosition; <$fetchClusterInfo(fragPos)$>; + if (!hasLocalLights(numLights, clusterPos, dims)) { + discard; + } // Frag to eye vec vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); diff --git a/libraries/render-utils/src/local_lights_shading.slf b/libraries/render-utils/src/local_lights_shading.slf index f302c6daba..b9c57b82cb 100644 --- a/libraries/render-utils/src/local_lights_shading.slf +++ b/libraries/render-utils/src/local_lights_shading.slf @@ -41,6 +41,9 @@ void main(void) { vec4 fragWorldPos = invViewMat * fragPosition; <$fetchClusterInfo(fragWorldPos)$>; + if (!hasLocalLights(numLights, clusterPos, dims)) { + discard; + } vec4 midNormalCurvature; vec4 lowNormalCurvature; @@ -55,7 +58,7 @@ void main(void) { _fragColor = evalLocalLighting(cluster, numLights, fragWorldPos.xyz, frag.normal, fragEyeDir, midNormalCurvature, lowNormalCurvature, frag.roughness, frag.scattering, - frag.metallic, frag.fresnel, frag.albedo); + frag.metallic, frag.fresnel, frag.albedo, 1.0); } diff --git a/libraries/render-utils/src/model_translucent.slf b/libraries/render-utils/src/model_translucent.slf index 5f61aea889..c054a5c096 100644 --- a/libraries/render-utils/src/model_translucent.slf +++ b/libraries/render-utils/src/model_translucent.slf @@ -68,16 +68,17 @@ void main(void) { vec3 fragNormal = normalize(_normal); TransformCamera cam = getTransformCamera(); + vec4 localLighting = vec4(0.0); <$fetchClusterInfo(_worldPosition)$>; + if (hasLocalLights(numLights, clusterPos, dims)) { + vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0)); + vec3 fragEyeDir = normalize(fragEyeVector); - vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0)); - vec3 fragEyeDir = normalize(fragEyeVector); - - vec4 localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, fragNormal, fragEyeDir, - vec4(0), vec4(0), roughness, 0.0, - metallic, fresnel, albedo); - emissive += localLighting.rgb; + localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, fragNormal, fragEyeDir, + vec4(0), vec4(0), roughness, 0.0, + metallic, fresnel, albedo, opacity); + } _fragColor = vec4(evalGlobalLightingAlphaBlendedWithHaze( cam._viewInverse, @@ -89,6 +90,6 @@ void main(void) { fresnel, metallic, emissive, - roughness, opacity), + roughness, opacity, localLighting.rgb), opacity); } diff --git a/libraries/render-utils/src/model_translucent_fade.slf b/libraries/render-utils/src/model_translucent_fade.slf index e07730a07e..c6bfd1659d 100644 --- a/libraries/render-utils/src/model_translucent_fade.slf +++ b/libraries/render-utils/src/model_translucent_fade.slf @@ -77,16 +77,17 @@ void main(void) { vec3 fragNormal = normalize(_normal); TransformCamera cam = getTransformCamera(); + vec4 localLighting = vec4(0.0); <$fetchClusterInfo(_worldPosition)$>; + if (hasLocalLights(numLights, clusterPos, dims)) { + vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0)); + vec3 fragEyeDir = normalize(fragEyeVector); - vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0)); - vec3 fragEyeDir = normalize(fragEyeVector); - - vec4 localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, fragNormal, fragEyeDir, - vec4(0), vec4(0), roughness, 0.0, - metallic, fresnel, albedo); - emissive += localLighting.rgb; + localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, fragNormal, fragEyeDir, + vec4(0), vec4(0), roughness, 0.0, + metallic, fresnel, albedo, opacity); + } _fragColor = vec4(evalGlobalLightingAlphaBlendedWithHaze( cam._viewInverse, @@ -98,6 +99,6 @@ void main(void) { fresnel, metallic, emissive+fadeEmissive, - roughness, opacity), + roughness, opacity, localLighting.rgb), opacity); } diff --git a/libraries/render-utils/src/overlay3D_model_translucent.slf b/libraries/render-utils/src/overlay3D_model_translucent.slf index b26e70f465..18f40a37b4 100644 --- a/libraries/render-utils/src/overlay3D_model_translucent.slf +++ b/libraries/render-utils/src/overlay3D_model_translucent.slf @@ -75,7 +75,7 @@ void main(void) { fresnel, metallic, emissive, - roughness, opacity), + roughness, opacity, vec3(0)), opacity); // Apply standard tone mapping diff --git a/libraries/render-utils/src/simple_transparent_textured.slf b/libraries/render-utils/src/simple_transparent_textured.slf index b16b19c8b4..5068b59e89 100644 --- a/libraries/render-utils/src/simple_transparent_textured.slf +++ b/libraries/render-utils/src/simple_transparent_textured.slf @@ -56,7 +56,7 @@ void main(void) { 0.0, vec3(0.0f), DEFAULT_ROUGHNESS, - opacity), + opacity, vec3(0)), opacity); } \ No newline at end of file diff --git a/libraries/render-utils/src/simple_transparent_textured_fade.slf b/libraries/render-utils/src/simple_transparent_textured_fade.slf index ad260210a7..2fff00849f 100644 --- a/libraries/render-utils/src/simple_transparent_textured_fade.slf +++ b/libraries/render-utils/src/simple_transparent_textured_fade.slf @@ -68,7 +68,7 @@ void main(void) { 0.0f, fadeEmissive, DEFAULT_ROUGHNESS, - opacity), + opacity, vec3(0)), opacity); } \ No newline at end of file From 8fb863e98c259ac16a7cc4dbaaa695229b38ee24 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Tue, 16 Jan 2018 15:57:05 +0100 Subject: [PATCH 07/21] Added SurfaceData mechanism to evalGlobalLight --- .../render-utils/src/DeferredGlobalLight.slh | 60 ++++++++++++++++--- .../render-utils/src/model_translucent.slf | 4 +- .../render-utils/src/model_translucent.slv | 2 +- .../src/model_translucent_fade.slf | 4 +- .../src/model_translucent_fade.slv | 2 +- .../src/overlay3D_model_translucent.slf | 2 +- .../src/simple_transparent_textured.slf | 2 +- .../src/simple_transparent_textured_fade.slf | 2 +- 8 files changed, 60 insertions(+), 18 deletions(-) diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index ab26f95482..7750b62430 100644 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -21,13 +21,7 @@ <@include LightDirectional.slh@> -<@func prepareGlobalLight(isScattering)@> - // prepareGlobalLight - // Transform directions to worldspace - vec3 fragNormal = vec3((normal)); - vec3 fragEyeVector = vec3(invViewMat * vec4(-1.0*position, 0.0)); - vec3 fragEyeDir = normalize(fragEyeVector); - +<@func fetchGlobalLight()@> // Get light Light light = getKeyLight(); LightAmbient lightAmbient = getLightAmbient(); @@ -36,6 +30,16 @@ vec3 lightIrradiance = getLightIrradiance(light); vec3 color = vec3(0.0); +<@endfunc@> + +<@func prepareGlobalLight(isScattering)@> + // prepareGlobalLight + // Transform directions to worldspace + vec3 fragNormal = vec3((normal)); + vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0)); + vec3 fragEyeDir = normalize(fragEyeVector); + + <$fetchGlobalLight()$> <@endfunc@> @@ -202,12 +206,50 @@ vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, fl vec3 evalGlobalLightingAlphaBlendedWithHaze( mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, - vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity, vec3 prevLighting) + vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity) { <$prepareGlobalLight()$> SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir); + color += emissive * isEmissiveEnabled(); + + // Ambient + vec3 ambientDiffuse; + vec3 ambientSpecular; + evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance); + color += ambientDiffuse; + color += ambientSpecular / opacity; + + // Directional + vec3 directionalDiffuse; + vec3 directionalSpecular; + evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation); + color += directionalDiffuse; + color += directionalSpecular / opacity; + + // Haze + if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) { + vec4 colorV4 = computeHazeColor( + vec4(color, 1.0), // fragment original color + position, // fragment position in eye coordinates + fragEyeVector, // fragment position in world coordinates + invViewMat[3].y, // eye height in world coordinates + lightDirection // keylight direction vector + ); + + color = colorV4.rgb; + } + + return color; +} + +vec3 evalGlobalLightingAlphaBlendedWithHaze( + mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, + vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, SurfaceData surface, float opacity, vec3 prevLighting) +{ + <$fetchGlobalLight()$> + color = prevLighting; color += emissive * isEmissiveEnabled(); @@ -229,7 +271,7 @@ vec3 evalGlobalLightingAlphaBlendedWithHaze( vec4 colorV4 = computeHazeColor( vec4(color, 1.0), // fragment original color position, // fragment position in eye coordinates - fragEyeVector, // fragment position in world coordinates + surface.eyeDir, // fragment eye vector in world coordinates invViewMat[3].y, // eye height in world coordinates lightDirection // keylight direction vector ); diff --git a/libraries/render-utils/src/model_translucent.slf b/libraries/render-utils/src/model_translucent.slf index 9b6913fe1c..6b3fe5991b 100644 --- a/libraries/render-utils/src/model_translucent.slf +++ b/libraries/render-utils/src/model_translucent.slf @@ -59,6 +59,7 @@ void main(void) { <$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>; vec3 fragPosition = _position.xyz; + // Lighting is done in world space vec3 fragNormal = normalize(_normal); TransformCamera cam = getTransformCamera(); @@ -80,11 +81,10 @@ void main(void) { 1.0, occlusionTex, fragPosition, - fragNormal, albedo, fresnel, metallic, emissive, - roughness, opacity, localLighting.rgb), + surface, opacity, localLighting.rgb), opacity); } diff --git a/libraries/render-utils/src/model_translucent.slv b/libraries/render-utils/src/model_translucent.slv index 2fe4c511f0..305aba06c3 100644 --- a/libraries/render-utils/src/model_translucent.slv +++ b/libraries/render-utils/src/model_translucent.slv @@ -40,5 +40,5 @@ void main(void) { TransformObject obj = getTransformObject(); <$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$> <$transformModelToWorldPos(obj, inPosition, _worldPosition)$> - <$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$> + <$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$> } diff --git a/libraries/render-utils/src/model_translucent_fade.slf b/libraries/render-utils/src/model_translucent_fade.slf index ea8774fd4e..46eac17cf7 100644 --- a/libraries/render-utils/src/model_translucent_fade.slf +++ b/libraries/render-utils/src/model_translucent_fade.slf @@ -68,6 +68,7 @@ void main(void) { <$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>; vec3 fragPosition = _position.xyz; + // Lighting is done in world space vec3 fragNormal = normalize(_normal); TransformCamera cam = getTransformCamera(); @@ -89,11 +90,10 @@ void main(void) { 1.0, occlusionTex, fragPosition, - fragNormal, albedo, fresnel, metallic, emissive+fadeEmissive, - roughness, opacity, localLighting.rgb), + surface, opacity, localLighting.rgb), opacity); } diff --git a/libraries/render-utils/src/model_translucent_fade.slv b/libraries/render-utils/src/model_translucent_fade.slv index eaabdd27e8..3fb9ad2cb4 100644 --- a/libraries/render-utils/src/model_translucent_fade.slv +++ b/libraries/render-utils/src/model_translucent_fade.slv @@ -40,5 +40,5 @@ void main(void) { TransformObject obj = getTransformObject(); <$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$> <$transformModelToWorldPos(obj, inPosition, _worldPosition)$> - <$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$> + <$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$> } diff --git a/libraries/render-utils/src/overlay3D_model_translucent.slf b/libraries/render-utils/src/overlay3D_model_translucent.slf index 6f1d34926e..b6ae8eb75e 100644 --- a/libraries/render-utils/src/overlay3D_model_translucent.slf +++ b/libraries/render-utils/src/overlay3D_model_translucent.slf @@ -69,7 +69,7 @@ void main(void) { fresnel, metallic, emissive, - roughness, opacity, vec3(0)), + roughness, opacity), opacity); // Apply standard tone mapping diff --git a/libraries/render-utils/src/simple_transparent_textured.slf b/libraries/render-utils/src/simple_transparent_textured.slf index 5068b59e89..b16b19c8b4 100644 --- a/libraries/render-utils/src/simple_transparent_textured.slf +++ b/libraries/render-utils/src/simple_transparent_textured.slf @@ -56,7 +56,7 @@ void main(void) { 0.0, vec3(0.0f), DEFAULT_ROUGHNESS, - opacity, vec3(0)), + opacity), opacity); } \ No newline at end of file diff --git a/libraries/render-utils/src/simple_transparent_textured_fade.slf b/libraries/render-utils/src/simple_transparent_textured_fade.slf index 2fff00849f..ad260210a7 100644 --- a/libraries/render-utils/src/simple_transparent_textured_fade.slf +++ b/libraries/render-utils/src/simple_transparent_textured_fade.slf @@ -68,7 +68,7 @@ void main(void) { 0.0f, fadeEmissive, DEFAULT_ROUGHNESS, - opacity, vec3(0)), + opacity), opacity); } \ No newline at end of file From 027a1e69f478693ddec6763a41f05c4300b691c4 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 20 Jan 2018 00:08:06 -0800 Subject: [PATCH 08/21] some settings cleanup, adding description to Send Data --- interface/src/ui/PreferencesDialog.cpp | 40 ++++++++----------- .../src/display-plugins/CompositorHelper.h | 3 -- 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 1a09af07ab..1bd6ef5889 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -142,7 +142,10 @@ void setupPreferences() { { auto getter = []()->bool { return !Menu::getInstance()->isOptionChecked(MenuOption::DisableActivityLogger); }; auto setter = [](bool value) { Menu::getInstance()->setIsOptionChecked(MenuOption::DisableActivityLogger, !value); }; - preferences->addPreference(new CheckPreference("Privacy", "Send data", getter, setter)); + preferences->addPreference(new CheckPreference("Privacy", "Send data - High Fidelity uses information provided by your " + "client to improve the product through the logging of errors and tracking of usage patterns, " + "installation and system details, and crash events. By allowing High Fidelity to collect " + "this information you are helping to improve the product. ", getter, setter)); } static const QString LOD_TUNING("Level of Detail Tuning"); @@ -297,26 +300,6 @@ void setupPreferences() { } #endif - { - auto getter = []()->float { return qApp->getMaxOctreePacketsPerSecond(); }; - auto setter = [](float value) { qApp->setMaxOctreePacketsPerSecond(value); }; - auto preference = new SpinnerPreference("Octree", "Max packets sent each second", getter, setter); - preference->setMin(60); - preference->setMax(6000); - preference->setStep(10); - preferences->addPreference(preference); - } - - - { - auto getter = []()->float { return qApp->getApplicationCompositor().getHmdUIAngularSize(); }; - auto setter = [](float value) { qApp->getApplicationCompositor().setHmdUIAngularSize(value); }; - auto preference = new SpinnerPreference("HMD", "UI horizontal angular size (degrees)", getter, setter); - preference->setMin(30); - preference->setMax(160); - preference->setStep(1); - preferences->addPreference(preference); - } { static const QString RENDER("Graphics"); @@ -342,7 +325,7 @@ void setupPreferences() { } } { - static const QString RENDER("Networking"); + static const QString NETWORKING("Networking"); auto nodelist = DependencyManager::get(); { @@ -350,10 +333,21 @@ void setupPreferences() { static const int MAX_PORT_NUMBER { 65535 }; auto getter = [nodelist] { return static_cast(nodelist->getSocketLocalPort()); }; auto setter = [nodelist](int preset) { nodelist->setSocketLocalPort(static_cast(preset)); }; - auto preference = new IntSpinnerPreference(RENDER, "Listening Port", getter, setter); + auto preference = new IntSpinnerPreference(NETWORKING, "Listening Port", getter, setter); preference->setMin(MIN_PORT_NUMBER); preference->setMax(MAX_PORT_NUMBER); preferences->addPreference(preference); } + + { + auto getter = []()->float { return qApp->getMaxOctreePacketsPerSecond(); }; + auto setter = [](float value) { qApp->setMaxOctreePacketsPerSecond(value); }; + auto preference = new SpinnerPreference(NETWORKING, "Max entities packets sent each second", getter, setter); + preference->setMin(60); + preference->setMax(6000); + preference->setStep(10); + preferences->addPreference(preference); + } + } } diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.h b/libraries/display-plugins/src/display-plugins/CompositorHelper.h index f448375f0d..6c2acb7e62 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.h +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.h @@ -53,8 +53,6 @@ public: bool calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const; - float getHmdUIAngularSize() const { return _hmdUIAngularSize; } - void setHmdUIAngularSize(float hmdUIAngularSize) { _hmdUIAngularSize = hmdUIAngularSize; } bool isHMD() const; bool fakeEventActive() const { return _fakeMouseEvent; } @@ -139,7 +137,6 @@ private: //quint64 _hoverItemEnterUsecs { 0 }; bool _isOverDesktop { true }; - float _hmdUIAngularSize { glm::degrees(VIRTUAL_UI_TARGET_FOV.y) }; float _textureFov { VIRTUAL_UI_TARGET_FOV.y }; float _textureAspectRatio { VIRTUAL_UI_ASPECT_RATIO }; From ab9041bcab20c61468b83bd51202bba98df39c7f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 20 Jan 2018 00:14:44 -0800 Subject: [PATCH 09/21] remove LOAD DEFAULT SCRIPTS from General Preferences, since it already exists on Running Scripts --- interface/src/ui/PreferencesDialog.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 1bd6ef5889..1d4d6f94b2 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -135,10 +135,6 @@ void setupPreferences() { preferences->addPreference(new BrowsePreference("Scripts", "Load scripts from this directory", getter, setter)); } - preferences->addPreference(new ButtonPreference("Scripts", "Load Default Scripts", [] { - DependencyManager::get()->loadDefaultScripts(); - })); - { auto getter = []()->bool { return !Menu::getInstance()->isOptionChecked(MenuOption::DisableActivityLogger); }; auto setter = [](bool value) { Menu::getInstance()->setIsOptionChecked(MenuOption::DisableActivityLogger, !value); }; From 4ad5d34a1078aabaf04743d607ebc1b0698117fb Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 20 Jan 2018 17:20:42 -0800 Subject: [PATCH 10/21] more preferences cleanup, removing some dead code from ScriptEngines/ScriptModel --- .../dialogs/AdvancedPreferencesDialog.qml | 29 +++++++++ .../hifi/dialogs/GeneralPreferencesDialog.qml | 2 +- interface/src/Application.cpp | 5 +- interface/src/Menu.cpp | 7 ++ interface/src/ui/PreferencesDialog.cpp | 65 +++++++++---------- libraries/script-engine/src/ScriptEngines.cpp | 12 +--- libraries/script-engine/src/ScriptEngines.h | 5 +- libraries/script-engine/src/ScriptsModel.cpp | 3 +- 8 files changed, 79 insertions(+), 49 deletions(-) create mode 100644 interface/resources/qml/hifi/dialogs/AdvancedPreferencesDialog.qml diff --git a/interface/resources/qml/hifi/dialogs/AdvancedPreferencesDialog.qml b/interface/resources/qml/hifi/dialogs/AdvancedPreferencesDialog.qml new file mode 100644 index 0000000000..2d80a1c330 --- /dev/null +++ b/interface/resources/qml/hifi/dialogs/AdvancedPreferencesDialog.qml @@ -0,0 +1,29 @@ +// +// AdvancedPreferencesDialog.qml +// +// Created by Brad Hefta-Gaub on 20 Jan 2018 +// Copyright 2018 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 +// + +import QtQuick 2.5 +import Qt.labs.settings 1.0 + +import "../../dialogs" + +PreferencesDialog { + id: root + objectName: "AdvancedPreferencesDialog" + title: "Advanced Settings" + showCategories: ["Advanced UI" ] + property var settings: Settings { + category: root.objectName + property alias x: root.x + property alias y: root.y + property alias width: root.width + property alias height: root.height + } +} + diff --git a/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml b/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml index 94665794d6..6f5798e2b2 100644 --- a/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml +++ b/interface/resources/qml/hifi/dialogs/GeneralPreferencesDialog.qml @@ -17,7 +17,7 @@ PreferencesDialog { id: root objectName: "GeneralPreferencesDialog" title: "General Settings" - showCategories: ["UI", "Snapshots", "Scripts", "Privacy", "Octree", "HMD", "Game Controller", "Sixense Controllers", "Perception Neuron", "Kinect", "Leap Motion"] + showCategories: ["UI", "Snapshots", "Privacy", "HMD", "Game Controller", "Sixense Controllers", "Perception Neuron", "Kinect", "Leap Motion"] property var settings: Settings { category: root.objectName property alias x: root.x diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f3c41565f8..cf5b83aafd 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1375,8 +1375,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo userInputMapper->registerDevice(_touchscreenDevice->getInputDevice()); } - // force the model the look at the correct directory (weird order of operations issue) - scriptEngines->setScriptsLocation(scriptEngines->getScriptsLocation()); + // this will force the model the look at the correct directory (weird order of operations issue) + scriptEngines->reloadLocalFiles(); + // do this as late as possible so that all required subsystems are initialized // If we've overridden the default scripts location, just load default scripts // otherwise, load 'em all diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index d295e96867..50142d6a3c 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -758,6 +758,13 @@ Menu::Menu() { // Developer > Stats addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Stats); + // Developer > Advanced Settings... + action = addActionToQMenuAndActionHash(developerMenu, "Advanced Preferences..."); + connect(action, &QAction::triggered, [] { + qApp->showDialog(QString("hifi/dialogs/AdvancedPreferencesDialog.qml"), + QString("hifi/tablet/AdvancedPreferencesDialog.qml"), "AdvancedPreferencesDialog"); + }); + #if 0 /// -------------- REMOVED FOR NOW -------------- addDisabledActionAndSeparator(navigateMenu, "History"); diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 1d4d6f94b2..48b56c7ced 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -82,19 +82,42 @@ void setupPreferences() { preference->setMax(500); preferences->addPreference(preference); } - { - auto getter = []()->float { return qApp->getDesktopTabletScale(); }; - auto setter = [](float value) { qApp->setDesktopTabletScale(value); }; - auto preference = new SpinnerPreference(UI_CATEGORY, "Desktop Tablet Scale %", getter, setter); - preference->setMin(20); - preference->setMax(500); - preferences->addPreference(preference); - } + + { auto getter = []()->bool { return qApp->getPreferStylusOverLaser(); }; auto setter = [](bool value) { qApp->setPreferStylusOverLaser(value); }; preferences->addPreference(new CheckPreference(UI_CATEGORY, "Prefer Stylus Over Laser", getter, setter)); } + + static const QString ADVANCED_UI_CATEGORY { "Advanced UI" }; + { + auto getter = []()->float { return qApp->getDesktopTabletScale(); }; + auto setter = [](float value) { qApp->setDesktopTabletScale(value); }; + auto preference = new SpinnerPreference(ADVANCED_UI_CATEGORY, "Desktop Tablet Scale %", getter, setter); + preference->setMin(20); + preference->setMax(500); + preferences->addPreference(preference); + } + { + auto getter = [=]()->float { return myAvatar->getRealWorldFieldOfView(); }; + auto setter = [=](float value) { myAvatar->setRealWorldFieldOfView(value); }; + auto preference = new SpinnerPreference(ADVANCED_UI_CATEGORY, "Real world vertical field of view (angular size of monitor)", getter, setter); + preference->setMin(1); + preference->setMax(180); + preferences->addPreference(preference); + } + { + auto getter = []()->float { return qApp->getFieldOfView(); }; + auto setter = [](float value) { qApp->setFieldOfView(value); }; + auto preference = new SpinnerPreference(ADVANCED_UI_CATEGORY, "Vertical field of view", getter, setter); + preference->setMin(1); + preference->setMax(180); + preference->setStep(1); + preferences->addPreference(preference); + } + + // FIXME: Remove setting completely or make available through JavaScript API? /* { @@ -128,18 +151,11 @@ void setupPreferences() { preferences->addPreference(preference); } - // Scripts - { - auto getter = []()->QString { return DependencyManager::get()->getScriptsLocation(); }; - auto setter = [](const QString& value) { DependencyManager::get()->setScriptsLocation(value); }; - preferences->addPreference(new BrowsePreference("Scripts", "Load scripts from this directory", getter, setter)); - } - { auto getter = []()->bool { return !Menu::getInstance()->isOptionChecked(MenuOption::DisableActivityLogger); }; auto setter = [](bool value) { Menu::getInstance()->setIsOptionChecked(MenuOption::DisableActivityLogger, !value); }; preferences->addPreference(new CheckPreference("Privacy", "Send data - High Fidelity uses information provided by your " - "client to improve the product through the logging of errors and tracking of usage patterns, " + "client to improve the product through the logging of errors, tracking of usage patterns, " "installation and system details, and crash events. By allowing High Fidelity to collect " "this information you are helping to improve the product. ", getter, setter)); } @@ -166,23 +182,6 @@ void setupPreferences() { } static const QString AVATAR_TUNING { "Avatar Tuning" }; - { - auto getter = [=]()->float { return myAvatar->getRealWorldFieldOfView(); }; - auto setter = [=](float value) { myAvatar->setRealWorldFieldOfView(value); }; - auto preference = new SpinnerPreference(AVATAR_TUNING, "Real world vertical field of view (angular size of monitor)", getter, setter); - preference->setMin(1); - preference->setMax(180); - preferences->addPreference(preference); - } - { - auto getter = []()->float { return qApp->getFieldOfView(); }; - auto setter = [](float value) { qApp->setFieldOfView(value); }; - auto preference = new SpinnerPreference(AVATAR_TUNING, "Vertical field of view", getter, setter); - preference->setMin(1); - preference->setMax(180); - preference->setStep(1); - preferences->addPreference(preference); - } { auto getter = [=]()->QString { return myAvatar->getDominantHand(); }; auto setter = [=](const QString& value) { myAvatar->setDominantHand(value); }; diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 6cfa678652..78cb05fa0d 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -62,8 +62,7 @@ void ScriptEngines::onErrorLoadingScript(const QString& url) { } ScriptEngines::ScriptEngines(ScriptEngine::Context context) - : _context(context), - _scriptsLocationHandle("scriptsLocation", DESKTOP_LOCATION) + : _context(context) { _scriptsModelFilter.setSourceModel(&_scriptsModel); _scriptsModelFilter.sort(0, Qt::AscendingOrder); @@ -429,13 +428,8 @@ bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) { return stoppedScript; } -QString ScriptEngines::getScriptsLocation() const { - return _scriptsLocationHandle.get(); -} - -void ScriptEngines::setScriptsLocation(const QString& scriptsLocation) { - _scriptsLocationHandle.set(scriptsLocation); - _scriptsModel.updateScriptsLocation(scriptsLocation); +void ScriptEngines::reloadLocalFiles() { + _scriptsModel.reloadLocalFiles(); } void ScriptEngines::reloadAllScripts() { diff --git a/libraries/script-engine/src/ScriptEngines.h b/libraries/script-engine/src/ScriptEngines.h index f2b0105be1..265902143f 100644 --- a/libraries/script-engine/src/ScriptEngines.h +++ b/libraries/script-engine/src/ScriptEngines.h @@ -41,9 +41,9 @@ public: void loadScripts(); void saveScripts(); - QString getScriptsLocation() const; void loadDefaultScripts(); - void setScriptsLocation(const QString& scriptsLocation); + void reloadLocalFiles(); + QStringList getRunningScripts(); ScriptEnginePointer getScriptEngine(const QUrl& scriptHash); @@ -111,7 +111,6 @@ protected: QSet _allKnownScriptEngines; QMutex _allScriptsMutex; std::list _scriptInitializers; - mutable Setting::Handle _scriptsLocationHandle; ScriptsModel _scriptsModel; ScriptsModelFilter _scriptsModelFilter; std::atomic _isStopped { false }; diff --git a/libraries/script-engine/src/ScriptsModel.cpp b/libraries/script-engine/src/ScriptsModel.cpp index 9b7a367773..5f30033bf9 100644 --- a/libraries/script-engine/src/ScriptsModel.cpp +++ b/libraries/script-engine/src/ScriptsModel.cpp @@ -100,6 +100,7 @@ QVariant ScriptsModel::data(const QModelIndex& index, int role) const { return QVariant(); } if (node->getType() == TREE_NODE_TYPE_SCRIPT) { + TreeNodeScript* script = static_cast(node); if (role == Qt::DisplayRole) { return QVariant(script->getName() + (script->getOrigin() == SCRIPT_ORIGIN_LOCAL ? " (local)" : "")); @@ -133,7 +134,6 @@ void ScriptsModel::updateScriptsLocation(const QString& newPath) { _fsWatcher.addPath(_localDirectory.absolutePath()); } } - reloadLocalFiles(); } @@ -305,6 +305,7 @@ void ScriptsModel::rebuildTree() { _treeNodes.removeAt(i); } } + QHash folders; for (int i = 0; i < _treeNodes.size(); i++) { TreeNodeBase* node = _treeNodes.at(i); From 43f7bb5f56e9dbd72939a54e2cc1f63821ba2fa8 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Mon, 22 Jan 2018 16:50:03 +0100 Subject: [PATCH 11/21] Fixed compilation error due to really long shader --- libraries/render-utils/src/LightClusterGrid.slh | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/libraries/render-utils/src/LightClusterGrid.slh b/libraries/render-utils/src/LightClusterGrid.slh index 60daa520a3..709e8c0f70 100644 --- a/libraries/render-utils/src/LightClusterGrid.slh +++ b/libraries/render-utils/src/LightClusterGrid.slh @@ -100,23 +100,6 @@ int clusterGrid_getClusterLightId(int index, int offset) { <@endfunc@> bool hasLocalLights(int numLights, ivec3 clusterPos, ivec3 dims) { -/* - if (numLights <= 0) { - return false; - } - - if (clusterPos.x < 0 || clusterPos.x >= dims.x) { - return false; - } - - if (clusterPos.y < 0 || clusterPos.y >= dims.y) { - return false; - } - if (clusterPos.z < 0 || clusterPos.z > dims.z) { - return false; - } - return true; -*/ return numLights>0 && all(greaterThanEqual(clusterPos, ivec3(0))) && all(lessThan(clusterPos.xy, dims.xy)) From 64a55f139383644dfb81514e0ed4d74b5d745569 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 23 Jan 2018 20:36:11 -0800 Subject: [PATCH 12/21] fix asan build --- tests/gl/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/gl/CMakeLists.txt b/tests/gl/CMakeLists.txt index 2b2b79d8b2..40bb64be1c 100644 --- a/tests/gl/CMakeLists.txt +++ b/tests/gl/CMakeLists.txt @@ -1,6 +1,7 @@ set(TARGET_NAME gl-test) # This is not a testcase -- just set it up as a regular hifi project setup_hifi_project(Quick Gui OpenGL) +setup_memory_debugger() set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") link_hifi_libraries(shared gl) package_libraries_for_deployment() From 94e1c425ab618bf8b8105214d7928c38e029c527 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 24 Jan 2018 17:03:16 -0800 Subject: [PATCH 13/21] Fix MacOS Security Pic visibility; fix incorrect button state when changing pic --- .../resources/qml/hifi/commerce/wallet/Security.qml | 2 +- .../hifi/commerce/wallet/SecurityImageChange.qml | 13 ++----------- .../hifi/commerce/wallet/SecurityImageSelection.qml | 3 ++- interface/src/commerce/Wallet.cpp | 4 ++-- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/Security.qml b/interface/resources/qml/hifi/commerce/wallet/Security.qml index d825196655..634a68d117 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Security.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Security.qml @@ -193,7 +193,7 @@ Item { color: hifi.colors.white; } - // "Change Passphrase" button + // "Change Security Pic" button HifiControlsUit.Button { id: changeSecurityImageButton; color: hifi.buttons.blue; diff --git a/interface/resources/qml/hifi/commerce/wallet/SecurityImageChange.qml b/interface/resources/qml/hifi/commerce/wallet/SecurityImageChange.qml index 2ad2b75553..86a4220b74 100644 --- a/interface/resources/qml/hifi/commerce/wallet/SecurityImageChange.qml +++ b/interface/resources/qml/hifi/commerce/wallet/SecurityImageChange.qml @@ -34,13 +34,11 @@ Item { securityImageChangePageSecurityImage.source = "image://security/securityImage"; if (exists) { // Success submitting new security image if (root.justSubmitted) { - root.resetSubmitButton(); sendSignalToWallet({method: "walletSecurity_changeSecurityImageSuccess"}); root.justSubmitted = false; } } else if (root.justSubmitted) { // Error submitting new security image. - root.resetSubmitButton(); root.justSubmitted = false; } } @@ -180,7 +178,8 @@ Item { // "Submit" button HifiControlsUit.Button { id: securityImageSubmitButton; - enabled: securityImageSelection.currentIndex !== -1; + text: root.justSubmitted ? "Submitting..." : "Submit"; + enabled: securityImageSelection.currentIndex !== -1 && !root.justSubmitted; color: hifi.buttons.blue; colorScheme: hifi.colorSchemes.dark; anchors.top: parent.top; @@ -188,11 +187,8 @@ Item { anchors.right: parent.right; anchors.rightMargin: 20; width: 150; - text: "Submit"; onClicked: { root.justSubmitted = true; - securityImageSubmitButton.text = "Submitting..."; - securityImageSubmitButton.enabled = false; var securityImagePath = securityImageSelection.getImagePathFromImageID(securityImageSelection.getSelectedImageIndex()) Commerce.chooseSecurityImage(securityImagePath); } @@ -205,11 +201,6 @@ Item { signal sendSignalToWallet(var msg); - function resetSubmitButton() { - securityImageSubmitButton.enabled = true; - securityImageSubmitButton.text = "Submit"; - } - function initModel() { securityImageSelection.initModel(); } diff --git a/interface/resources/qml/hifi/commerce/wallet/SecurityImageSelection.qml b/interface/resources/qml/hifi/commerce/wallet/SecurityImageSelection.qml index c6c6056605..56b78c5865 100644 --- a/interface/resources/qml/hifi/commerce/wallet/SecurityImageSelection.qml +++ b/interface/resources/qml/hifi/commerce/wallet/SecurityImageSelection.qml @@ -24,7 +24,7 @@ Item { HifiConstants { id: hifi; } id: root; - property int currentIndex: securityImageGrid.currentIndex; + property alias currentIndex: securityImageGrid.currentIndex; // This will cause a bug -- if you bring up security image selection in HUD mode while // in HMD while having HMD preview enabled, then move, then finish passphrase selection, @@ -98,6 +98,7 @@ Item { function initModel() { gridModel.initModel(); + securityImageGrid.currentIndex = -1; } function resetSelection() { diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 8b73042ada..9599af827f 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -591,8 +591,8 @@ void Wallet::chooseSecurityImage(const QString& filename) { if (_securityImage) { delete _securityImage; } - QString path = qApp->applicationDirPath(); - path.append("/resources/qml/hifi/commerce/wallet/"); + QString path = PathUtils::resourcesPath(); + path.append("/qml/hifi/commerce/wallet/"); path.append(filename); // now create a new security image pixmap From a252e90f969e85503f2a83380a6e101026732783 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 24 Jan 2018 18:58:08 -0800 Subject: [PATCH 14/21] Bug fix for incorrect positioned eyes on other peoples avatars There was a bug in writeBitVector(), where the last byte was not consistantly written into the destination buffer. A unit test was added to verify that writeBitVector() and readBitVector() are correct. --- libraries/shared/src/BitVectorHelpers.h | 16 +++-- tests/shared/src/BitVectorHelperTests.cpp | 80 +++++++++++++++++++++++ tests/shared/src/BitVectorHelperTests.h | 23 +++++++ 3 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 tests/shared/src/BitVectorHelperTests.cpp create mode 100644 tests/shared/src/BitVectorHelperTests.h diff --git a/libraries/shared/src/BitVectorHelpers.h b/libraries/shared/src/BitVectorHelpers.h index 71826036eb..9f5af0c380 100644 --- a/libraries/shared/src/BitVectorHelpers.h +++ b/libraries/shared/src/BitVectorHelpers.h @@ -12,14 +12,14 @@ #ifndef hifi_BitVectorHelpers_h #define hifi_BitVectorHelpers_h -size_t calcBitVectorSize(int numBits) { +int calcBitVectorSize(int numBits) { return ((numBits - 1) >> 3) + 1; } // func should be of type bool func(int index) template -size_t writeBitVector(uint8_t* destinationBuffer, int numBits, const F& func) { - size_t totalBytes = ((numBits - 1) >> 3) + 1; +int writeBitVector(uint8_t* destinationBuffer, int numBits, const F& func) { + int totalBytes = calcBitVectorSize(numBits); uint8_t* cursor = destinationBuffer; uint8_t byte = 0; uint8_t bit = 0; @@ -34,13 +34,19 @@ size_t writeBitVector(uint8_t* destinationBuffer, int numBits, const F& func) { bit = 0; } } + // write the last byte, if necessary + if (bit != 0) { + *cursor++ = byte; + } + + assert((int)(cursor - destinationBuffer) == totalBytes); return totalBytes; } // func should be of type 'void func(int index, bool value)' template -size_t readBitVector(const uint8_t* sourceBuffer, int numBits, const F& func) { - size_t totalBytes = ((numBits - 1) >> 3) + 1; +int readBitVector(const uint8_t* sourceBuffer, int numBits, const F& func) { + int totalBytes = calcBitVectorSize(numBits); const uint8_t* cursor = sourceBuffer; uint8_t bit = 0; diff --git a/tests/shared/src/BitVectorHelperTests.cpp b/tests/shared/src/BitVectorHelperTests.cpp new file mode 100644 index 0000000000..070e90eec7 --- /dev/null +++ b/tests/shared/src/BitVectorHelperTests.cpp @@ -0,0 +1,80 @@ +// +// BitVectorHelperTests.cpp +// tests/shared/src +// +// Copyright 2018 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 +// + +#include "BitVectorHelperTests.h" + +#include + +#include "../QTestExtensions.h" +#include +#include +#include +#include + +QTEST_MAIN(BitVectorHelperTests) + +const int BITS_IN_BYTE = 8; + +void BitVectorHelperTests::sizeTest() { + std::vector sizes = {0, 6, 7, 8, 30, 31, 32, 33, 87, 88, 89, 90, 90, 91, 92, 93}; + for (auto& size : sizes) { + const int oldWay = (int)ceil((float)size / (float)BITS_IN_BYTE); + const int newWay = (int)calcBitVectorSize(size); + QCOMPARE(oldWay, newWay); + } +} + +static void readWriteHelper(const std::vector& src) { + + int numBits = (int)src.size(); + int numBytes = calcBitVectorSize(numBits); + uint8_t* bytes = new uint8_t[numBytes]; + memset(bytes, numBytes, sizeof(uint8_t)); + int numBytesWritten = writeBitVector(bytes, numBits, [&](int i) { + return src[i]; + }); + QCOMPARE(numBytesWritten, numBytes); + + std::vector dst; + int numBytesRead = readBitVector(bytes, numBits, [&](int i, bool value) { + dst.push_back(value); + }); + QCOMPARE(numBytesRead, numBytes); + + QCOMPARE(numBits, (int)src.size()); + QCOMPARE(numBits, (int)dst.size()); + for (int i = 0; i < numBits; i++) { + bool a = src[i]; + bool b = dst[i]; + QCOMPARE(a, b); + } +} + +void BitVectorHelperTests::readWriteTest() { + std::vector sizes = {0, 6, 7, 8, 30, 31, 32, 33, 87, 88, 89, 90, 90, 91, 92, 93}; + + for (auto& size : sizes) { + std::vector allTrue(size, true); + std::vector allFalse(size, false); + std::vector evenSet; + evenSet.reserve(size); + std::vector oddSet; + oddSet.reserve(size); + for (int i = 0; i < size; i++) { + bool isOdd = (i & 0x1) > 0; + evenSet.push_back(!isOdd); + oddSet.push_back(isOdd); + } + readWriteHelper(allTrue); + readWriteHelper(allFalse); + readWriteHelper(evenSet); + readWriteHelper(oddSet); + } +} diff --git a/tests/shared/src/BitVectorHelperTests.h b/tests/shared/src/BitVectorHelperTests.h new file mode 100644 index 0000000000..1f52ba1ac9 --- /dev/null +++ b/tests/shared/src/BitVectorHelperTests.h @@ -0,0 +1,23 @@ +// +// BitVectorHelperTests.h +// tests/shared/src +// +// Copyright 2018 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 +// + +#ifndef hifi_BitVectorHelperTests_h +#define hifi_BitVectorHelperTests_h + +#include + +class BitVectorHelperTests : public QObject { + Q_OBJECT +private slots: + void sizeTest(); + void readWriteTest(); +}; + +#endif // hifi_BitVectorHelperTests_h From 3915a2d4ba12249d74f9d39e738703ce9c0fa31b Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 25 Jan 2018 11:07:39 -0800 Subject: [PATCH 15/21] Fix resource loading from source tree --- libraries/shared/src/PathUtils.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/libraries/shared/src/PathUtils.cpp b/libraries/shared/src/PathUtils.cpp index 35d7554f39..41db7281ac 100644 --- a/libraries/shared/src/PathUtils.cpp +++ b/libraries/shared/src/PathUtils.cpp @@ -29,7 +29,6 @@ #include #endif - #include "shared/GlobalAppProperties.h" #include "SharedUtil.h" @@ -41,8 +40,15 @@ QString TEMP_DIR_FORMAT { "%1-%2-%3" }; #if defined(Q_OS_OSX) static bool USE_SOURCE_TREE_RESOURCES = true; #else -static const QString USE_SOURCE_TREE_RESOURCES_FLAG("HIFI_USE_SOURCE_TREE_RESOURCES"); -static bool USE_SOURCE_TREE_RESOURCES = QProcessEnvironment::systemEnvironment().contains(USE_SOURCE_TREE_RESOURCES_FLAG); +static bool USE_SOURCE_TREE_RESOURCES() { + static bool result = false; + static std::once_flag once; + std::call_once(once, [&] { + const QString USE_SOURCE_TREE_RESOURCES_FLAG("HIFI_USE_SOURCE_TREE_RESOURCES"); + result = QProcessEnvironment::systemEnvironment().contains(USE_SOURCE_TREE_RESOURCES_FLAG); + }); + return result; +} #endif #endif @@ -77,7 +83,7 @@ const QString& PathUtils::resourcesPath() { #endif #if !defined(Q_OS_ANDROID) && defined(DEV_BUILD) - if (USE_SOURCE_TREE_RESOURCES) { + if (USE_SOURCE_TREE_RESOURCES()) { // For dev builds, optionally load content from the Git source tree staticResourcePath = projectRootPath() + "/interface/resources/"; } @@ -100,7 +106,7 @@ const QString& PathUtils::resourcesUrl() { #endif #if !defined(Q_OS_ANDROID) && defined(DEV_BUILD) - if (USE_SOURCE_TREE_RESOURCES) { + if (USE_SOURCE_TREE_RESOURCES()) { // For dev builds, optionally load content from the Git source tree staticResourcePath = QUrl::fromLocalFile(projectRootPath() + "/interface/resources/").toString(); } From afc71a5ac5090487961273f678a02b7363555cf8 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 25 Jan 2018 12:17:34 -0800 Subject: [PATCH 16/21] Fix Purchases sorting (again); Fix (i) icon loading --- .../hifi/commerce/common/SortableListModel.qml | 16 +++++++++------- .../qml/hifi/commerce/purchases/Purchases.qml | 8 ++++++-- .../src/ui/overlays/ContextOverlayInterface.cpp | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/common/SortableListModel.qml b/interface/resources/qml/hifi/commerce/common/SortableListModel.qml index 0951d25950..cfdd4abe04 100644 --- a/interface/resources/qml/hifi/commerce/common/SortableListModel.qml +++ b/interface/resources/qml/hifi/commerce/common/SortableListModel.qml @@ -22,7 +22,7 @@ ListModel { function swap(a, b) { if (a < b) { move(a, b, 1); - move (b - 1, a, 1); + move(b - 1, a, 1); } else if (a > b) { move(b, a, 1); move(a - 1, b, 1); @@ -34,16 +34,17 @@ ListModel { var piv = get(pivot)[sortColumnName]; swap(pivot, end - 1); var store = begin; + var i; - for (var i = begin; i < end - 1; ++i) { + for (i = begin; i < end - 1; ++i) { var currentElement = get(i)[sortColumnName]; if (isSortingDescending) { - if (currentElement < piv) { + if (currentElement > piv) { swap(store, i); ++store; } } else { - if (currentElement > piv) { + if (currentElement < piv) { swap(store, i); ++store; } @@ -56,16 +57,17 @@ ListModel { var piv = get(pivot)[sortColumnName].toLowerCase(); swap(pivot, end - 1); var store = begin; + var i; - for (var i = begin; i < end - 1; ++i) { + for (i = begin; i < end - 1; ++i) { var currentElement = get(i)[sortColumnName].toLowerCase(); if (isSortingDescending) { - if (currentElement < piv) { + if (currentElement > piv) { swap(store, i); ++store; } } else { - if (currentElement > piv) { + if (currentElement < piv) { swap(store, i); ++store; } diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index a9961dc17e..2743677683 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -317,6 +317,7 @@ Rectangle { HifiControlsUit.TextField { id: filterBar; + property string previousText: ""; colorScheme: hifi.colorSchemes.faintGray; hasClearButton: true; hasRoundedBorder: true; @@ -329,6 +330,8 @@ Rectangle { onTextChanged: { buildFilteredPurchasesModel(); + purchasesContentsList.positionViewAtIndex(0, ListView.Beginning) + filterBar.previousText = filterBar.text; } onAccepted: { @@ -647,7 +650,8 @@ Rectangle { function sortByDate() { filteredPurchasesModel.sortColumnName = "purchase_date"; - filteredPurchasesModel.isSortingDescending = false; + filteredPurchasesModel.isSortingDescending = true; + filteredPurchasesModel.valuesAreNumerical = true; filteredPurchasesModel.quickSort(); } @@ -677,7 +681,7 @@ Rectangle { } } - if (sameItemCount !== tempPurchasesModel.count || filterBar.text !== "") { + if (sameItemCount !== tempPurchasesModel.count || filterBar.text !== filterBar.previousText) { filteredPurchasesModel.clear(); for (var i = 0; i < tempPurchasesModel.count; i++) { filteredPurchasesModel.append(tempPurchasesModel.get(i)); diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index d690880f99..58a77883d8 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -168,8 +168,8 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& _contextOverlay->setColorPulse(CONTEXT_OVERLAY_UNHOVERED_COLORPULSE); _contextOverlay->setIgnoreRayIntersection(false); _contextOverlay->setDrawInFront(true); - _contextOverlay->setURL(PathUtils::resourcesPath() + "images/inspect-icon.png"); _contextOverlay->setIsFacingAvatar(true); + _contextOverlay->setURL(PathUtils::resourcesUrl() + "images/inspect-icon.png"); _contextOverlayID = qApp->getOverlays().addOverlay(_contextOverlay); } _contextOverlay->setWorldPosition(contextOverlayPosition); From bde5282541cbd039183758521baf080cee509dba Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 25 Jan 2018 12:43:49 -0800 Subject: [PATCH 17/21] Fix loading of the render config JSON --- libraries/render/src/render/Engine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/render/src/render/Engine.cpp b/libraries/render/src/render/Engine.cpp index 5f67d40d17..463b45451b 100644 --- a/libraries/render/src/render/Engine.cpp +++ b/libraries/render/src/render/Engine.cpp @@ -45,8 +45,8 @@ void Engine::load() { auto config = getConfiguration(); const QString configFile= "config/render.json"; - QUrl path(PathUtils::resourcesPath() + configFile); - QFile file(path.toString()); + QString path(PathUtils::resourcesPath() + configFile); + QFile file(path); if (!file.exists()) { qWarning() << "Engine configuration file" << path << "does not exist"; } else if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { From ac94327ec72edec08cdc5b188fd5d3028d574a3d Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 25 Jan 2018 12:44:55 -0800 Subject: [PATCH 18/21] Fix loading of the context overlay information icon --- interface/src/ui/overlays/ContextOverlayInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index d690880f99..d4138941ae 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -168,7 +168,7 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& _contextOverlay->setColorPulse(CONTEXT_OVERLAY_UNHOVERED_COLORPULSE); _contextOverlay->setIgnoreRayIntersection(false); _contextOverlay->setDrawInFront(true); - _contextOverlay->setURL(PathUtils::resourcesPath() + "images/inspect-icon.png"); + _contextOverlay->setURL(PathUtils::resourcesUrl() + "images/inspect-icon.png"); _contextOverlay->setIsFacingAvatar(true); _contextOverlayID = qApp->getOverlays().addOverlay(_contextOverlay); } From d4aef1ea8803c1e4213f96741b7efae060f746ab Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 25 Jan 2018 13:03:42 -0800 Subject: [PATCH 19/21] Fix URLs in QSS files to use QRC base path --- interface/resources/styles/global.qss | 10 +++++----- interface/resources/styles/import_dialog.qss | 6 +++--- interface/resources/styles/log_dialog.qss | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/interface/resources/styles/global.qss b/interface/resources/styles/global.qss index 2554f3b2c9..778e5759b3 100644 --- a/interface/resources/styles/global.qss +++ b/interface/resources/styles/global.qss @@ -41,14 +41,14 @@ QSpinBox, QDoubleSpinBox { QDoubleSpinBox::up-arrow, QSpinBox::up-arrow { - background-image: url(styles/up.svg); + background-image: url(:/styles/up.svg); background-repeat: no-repeat; background-position: center center; } QDoubleSpinBox::down-arrow, QSpinBox::down-arrow { - background-image: url(styles/down.svg); + background-image: url(:/styles/down.svg); background-repeat: no-repeat; background-position: center center; } @@ -88,7 +88,7 @@ QSlider { QSlider::groove:horizontal { border: none; - background-image: url(styles/slider-bg.svg); + background-image: url(:/styles/slider-bg.svg); background-repeat: no-repeat; background-position: center center; } @@ -96,7 +96,7 @@ QSlider::groove:horizontal { QSlider::handle:horizontal { width: 18px; height: 18px; - background-image: url(styles/slider-handle.svg); + background-image: url(:/styles/slider-handle.svg); background-repeat: no-repeat; background-position: center center; } @@ -107,7 +107,7 @@ QPushButton#closeButton { border-width: 1px; border-radius: 0; background-color: #fff; - background-image: url(styles/close.svg); + background-image: url(:/styles/close.svg); background-repeat: no-repeat; background-position: center center; } diff --git a/interface/resources/styles/import_dialog.qss b/interface/resources/styles/import_dialog.qss index 8fe04ae1b7..3c2dbdcce9 100644 --- a/interface/resources/styles/import_dialog.qss +++ b/interface/resources/styles/import_dialog.qss @@ -63,17 +63,17 @@ QPushButton#cancelButton { } #backButton { - background-image: url(icons/backButton.svg); + background-image: url(:/icons/backButton.svg); border-radius: 0px; } #forwardButton { - background-image: url(icons/forwardButton.svg); + background-image: url(:/icons/forwardButton.svg); border-radius: 0px; } #toParentButton { - background-image: url(icons/toParentButton.svg); + background-image: url(:/icons/toParentButton.svg); border-radius: 0px; } diff --git a/interface/resources/styles/log_dialog.qss b/interface/resources/styles/log_dialog.qss index 33473d2903..e0ec17549d 100644 --- a/interface/resources/styles/log_dialog.qss +++ b/interface/resources/styles/log_dialog.qss @@ -22,7 +22,7 @@ QLineEdit { } QPushButton#searchButton { - background: url(styles/search.svg); + background: url(:/styles/search.svg); background-repeat: none; background-position: left center; background-origin: content; @@ -55,7 +55,7 @@ QPushButton#searchPrevButton { QPushButton#revealLogButton { font-family: Helvetica, Arial, sans-serif; - background: url(styles/txt-file.svg); + background: url(:/styles/txt-file.svg); background-repeat: none; background-position: left center; background-origin: content; @@ -86,11 +86,11 @@ QCheckBox { } QCheckBox::indicator:unchecked { - image: url(styles/unchecked.svg); + image: url(:/styles/unchecked.svg); } QCheckBox::indicator:checked { - image: url(styles/checked.svg); + image: url(:/styles/checked.svg); } QComboBox { @@ -110,6 +110,6 @@ QComboBox::drop-down { } QComboBox::down-arrow { - image: url(styles/filter.png); + image: url(:/styles/filter.png); border-width: 0px; } \ No newline at end of file From 867bb99b51bde9f36eb9e69ebd5ec5bed7b707d6 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 25 Jan 2018 13:04:08 -0800 Subject: [PATCH 20/21] Fix help screen URL --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c2b22b3772..9379c85fdd 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2724,7 +2724,7 @@ void Application::showHelp() { queryString.addQueryItem("defaultTab", defaultTab); auto tabletScriptingInterface = DependencyManager::get(); TabletProxy* tablet = dynamic_cast(tabletScriptingInterface->getTablet(SYSTEM_TABLET)); - tablet->gotoWebScreen(PathUtils::resourcesPath() + INFO_HELP_PATH + "?" + queryString.toString()); + tablet->gotoWebScreen(PathUtils::resourcesUrl() + INFO_HELP_PATH + "?" + queryString.toString()); DependencyManager::get()->openTablet(); //InfoView::show(INFO_HELP_PATH, false, queryString.toString()); } From ab4e2d99f1939b2e5b6e7281ad69dfeea4e92850 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 25 Jan 2018 13:04:54 -0800 Subject: [PATCH 21/21] Don't try to set the current directory to a QRC path --- interface/src/ui/BaseLogDialog.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/ui/BaseLogDialog.cpp b/interface/src/ui/BaseLogDialog.cpp index 6830de6e35..969f9895de 100644 --- a/interface/src/ui/BaseLogDialog.cpp +++ b/interface/src/ui/BaseLogDialog.cpp @@ -39,7 +39,6 @@ BaseLogDialog::BaseLogDialog(QWidget* parent) : QDialog(parent, Qt::Window) { QFile styleSheet(PathUtils::resourcesPath() + "styles/log_dialog.qss"); if (styleSheet.open(QIODevice::ReadOnly)) { - QDir::setCurrent(PathUtils::resourcesPath()); setStyleSheet(styleSheet.readAll()); }