From 5a7fed022cca3d291d71907283231b7a4e4da4d0 Mon Sep 17 00:00:00 2001 From: Nissim Hadar Date: Sat, 30 Sep 2017 00:04:28 -0700 Subject: [PATCH] Merging haze branch. --- .../render-utils/src/DeferredGlobalLight.slh | 51 ++++++++++++++++++- .../src/DeferredLightingEffect.cpp | 19 +++++-- .../render-utils/src/DeferredLightingEffect.h | 6 ++- .../render-utils/src/RenderDeferredTask.cpp | 2 +- libraries/render/src/task/Varying.h | 4 +- 5 files changed, 72 insertions(+), 10 deletions(-) diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index 57ca33eaca..ae560686e1 100644 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -101,6 +101,8 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness <$declareDeferredCurvature()$> <@endif@> +<@include Haze.slh@> + vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, float roughness <@if supportScattering@> @@ -120,7 +122,6 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu color += ambientDiffuse; color += ambientSpecular; - // Directional vec3 directionalDiffuse; vec3 directionalSpecular; @@ -132,6 +133,54 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu color += directionalDiffuse; color += directionalSpecular; + // Attenuate the light if haze effect selected + if ((hazeParams.hazeMode & HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) == HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) { + // Directional light attenuation is simulated by assuming the light source is at a fixed height above the + // fragment. This height is where the haze density is reduced by 95% from the haze at the fragment's height + // + // The distance is computed from the height and the directional light orientation + // The distance is limited to height * 1,000, which gives an angle of ~0.057 degrees + + // Get directional light + Light light = getLight(); + vec3 lightDirection = getLightDirection(light); + + // Height at which haze density is reduced by 95% + float height_95p = -log(0.05) / hazeParams.hazeAltitudeFactorKeyLight; + + // Note that the sine will always be positive + float sin_pitch = sqrt(1.0 - lightDirection.y * lightDirection.y); + + float distance; + const float minimumSinPitch = 0.001; + if (sin_pitch < minimumSinPitch) { + distance = height_95p / minimumSinPitch; + } + else { + distance = height_95p / sin_pitch; + } + + // Position of fragment in world coordinates + vec4 worldFragPos = invViewMat * vec4(position, 0.0); + + // Integration is from the fragment towards the light source + // Note that the haze base reference affects only the haze density as function of altitude + float hazeDensityDistribution = + hazeParams.hazeRangeFactorKeyLight * + exp(-hazeParams.hazeAltitudeFactorKeyLight * (worldFragPos.y - hazeParams.hazeBaseReference)); + + float hazeIntegral = hazeDensityDistribution * distance; + + // Note that t is constant and equal to -log(0.05) + // float t = hazeParams.hazeAltitudeFactor * height_95p; + // hazeIntegral *= (1.0 - exp (-t)) / t; + hazeIntegral *= 0.3171178; + + float hazeAmount = 1.0 - exp(-hazeIntegral); + + color = mix(color, vec3(0.0, 0.0, 0.0), hazeAmount); + } + return color; } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 201cec5b2d..20292af679 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -76,7 +76,7 @@ enum DeferredShader_BufferSlot { LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT, LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, - + HAZE_MODEL_BUFFER_SLOT }; static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations); @@ -169,6 +169,7 @@ static gpu::ShaderPointer makeLightProgram(const char* vertSource, const char* f slotBindings.insert(gpu::Shader::Binding(std::string("cameraCorrectionBuffer"), CAMERA_CORRECTION_BUFFER_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), LIGHTING_MODEL_BUFFER_SLOT)); + slotBindings.insert(gpu::Shader::Binding(std::string("hazeBuffer"), HAZE_MODEL_BUFFER_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("subsurfaceScatteringParametersBuffer"), SCATTERING_PARAMETERS_BUFFER_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_GPU_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), LIGHT_AMBIENT_SLOT)); @@ -438,6 +439,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, const DeferredFrameTransformPointer& frameTransform, const DeferredFramebufferPointer& deferredFramebuffer, const LightingModelPointer& lightingModel, + const model::HazePointer& haze, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource) { @@ -538,6 +540,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, batch.setUniformBuffer(locations->shadowTransformBuffer, globalShadow->getBuffer()); } } + batch.setPipeline(program); } @@ -547,7 +550,10 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, // Setup the global lighting deferredLightingEffect->setupKeyLightBatch(args, batch, locations->lightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT); - + + // Haze + batch.setUniformBuffer(HAZE_MODEL_BUFFER_SLOT, haze->getParametersBuffer()); + batch.draw(gpu::TRIANGLE_STRIP, 4); deferredLightingEffect->unsetKeyLightBatch(batch, locations->lightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT); @@ -566,7 +572,8 @@ void RenderDeferredLocals::run(const render::RenderContextPointer& renderContext const DeferredFrameTransformPointer& frameTransform, const DeferredFramebufferPointer& deferredFramebuffer, const LightingModelPointer& lightingModel, - const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const LightClustersPointer& lightClusters) { + const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, + const LightClustersPointer& lightClusters) { bool points = lightingModel->isPointLightEnabled(); bool spots = lightingModel->isSpotLightEnabled(); @@ -675,6 +682,8 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs auto lightClusters = inputs.get6(); auto args = renderContext->args; + const auto haze = inputs.get7(); + if (!_gpuTimer) { _gpuTimer = std::make_shared < gpu::RangeTimer>(__FUNCTION__); } @@ -684,7 +693,7 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs args->_batch = &batch; _gpuTimer->begin(batch); - setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource); + setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, haze, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource); lightsJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lightClusters); @@ -720,7 +729,7 @@ void DefaultLightingSetup::run(const RenderContextPointer& renderContext) { } auto lightStage = renderContext->_scene->getStage(); - if (lightStage) { + if (lightStage) { // Allocate a default global light directional and ambient auto lp = std::make_shared(); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 1f8ba88e27..4266efc7b8 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -121,6 +121,7 @@ public: const DeferredFrameTransformPointer& frameTransform, const DeferredFramebufferPointer& deferredFramebuffer, const LightingModelPointer& lightingModel, + const model::HazePointer& haze, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource); @@ -155,7 +156,10 @@ using RenderDeferredConfig = render::GPUJobConfig; class RenderDeferred { public: - using Inputs = render::VaryingSet7 < DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer, AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer, LightClustersPointer>; + using Inputs = render::VaryingSet8 < + DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer, + AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer, LightClustersPointer, model::HazePointer>; + using Config = RenderDeferredConfig; using JobModel = render::Job::ModelI; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index e4f0c31a14..e3029c453c 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -152,7 +152,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren // DeferredBuffer is complete, now let's shade it into the LightingBuffer const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, - surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters).asVarying(); + surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters, hazeModel).asVarying(); task.addJob("RenderDeferred", deferredLightingInputs); diff --git a/libraries/render/src/task/Varying.h b/libraries/render/src/task/Varying.h index 7b7b9907fb..cd2f9a2d2f 100644 --- a/libraries/render/src/task/Varying.h +++ b/libraries/render/src/task/Varying.h @@ -285,10 +285,10 @@ public: const T5& get5() const { return std::get<5>((*this)).template get(); } T5& edit5() { return std::get<5>((*this)).template edit(); } - + const T6& get6() const { return std::get<6>((*this)).template get(); } T6& edit6() { return std::get<6>((*this)).template edit(); } - + Varying asVarying() const { return Varying((*this)); } };