Merging haze branch.

This commit is contained in:
Nissim Hadar 2017-09-30 00:04:28 -07:00
parent 95f8f1ffc5
commit 5a7fed022c
5 changed files with 72 additions and 10 deletions

View file

@ -101,6 +101,8 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness
<$declareDeferredCurvature()$> <$declareDeferredCurvature()$>
<@endif@> <@endif@>
<@include Haze.slh@>
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal,
vec3 albedo, vec3 fresnel, float metallic, float roughness vec3 albedo, vec3 fresnel, float metallic, float roughness
<@if supportScattering@> <@if supportScattering@>
@ -120,7 +122,6 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
color += ambientDiffuse; color += ambientDiffuse;
color += ambientSpecular; color += ambientSpecular;
// Directional // Directional
vec3 directionalDiffuse; vec3 directionalDiffuse;
vec3 directionalSpecular; vec3 directionalSpecular;
@ -132,6 +133,54 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
color += directionalDiffuse; color += directionalDiffuse;
color += directionalSpecular; 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; return color;
} }

View file

@ -76,7 +76,7 @@ enum DeferredShader_BufferSlot {
LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT, LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT,
LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT,
LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_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); 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("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("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("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("subsurfaceScatteringParametersBuffer"), SCATTERING_PARAMETERS_BUFFER_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_GPU_SLOT)); slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_GPU_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), LIGHT_AMBIENT_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 DeferredFrameTransformPointer& frameTransform,
const DeferredFramebufferPointer& deferredFramebuffer, const DeferredFramebufferPointer& deferredFramebuffer,
const LightingModelPointer& lightingModel, const LightingModelPointer& lightingModel,
const model::HazePointer& haze,
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer,
const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource) { const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource) {
@ -538,6 +540,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
batch.setUniformBuffer(locations->shadowTransformBuffer, globalShadow->getBuffer()); batch.setUniformBuffer(locations->shadowTransformBuffer, globalShadow->getBuffer());
} }
} }
batch.setPipeline(program); batch.setPipeline(program);
} }
@ -547,7 +550,10 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
// Setup the global lighting // Setup the global lighting
deferredLightingEffect->setupKeyLightBatch(args, batch, locations->lightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT); 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); batch.draw(gpu::TRIANGLE_STRIP, 4);
deferredLightingEffect->unsetKeyLightBatch(batch, locations->lightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT); 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 DeferredFrameTransformPointer& frameTransform,
const DeferredFramebufferPointer& deferredFramebuffer, const DeferredFramebufferPointer& deferredFramebuffer,
const LightingModelPointer& lightingModel, const LightingModelPointer& lightingModel,
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const LightClustersPointer& lightClusters) { const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
const LightClustersPointer& lightClusters) {
bool points = lightingModel->isPointLightEnabled(); bool points = lightingModel->isPointLightEnabled();
bool spots = lightingModel->isSpotLightEnabled(); bool spots = lightingModel->isSpotLightEnabled();
@ -675,6 +682,8 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs
auto lightClusters = inputs.get6(); auto lightClusters = inputs.get6();
auto args = renderContext->args; auto args = renderContext->args;
const auto haze = inputs.get7();
if (!_gpuTimer) { if (!_gpuTimer) {
_gpuTimer = std::make_shared < gpu::RangeTimer>(__FUNCTION__); _gpuTimer = std::make_shared < gpu::RangeTimer>(__FUNCTION__);
} }
@ -684,7 +693,7 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs
args->_batch = &batch; args->_batch = &batch;
_gpuTimer->begin(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); lightsJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lightClusters);
@ -720,7 +729,7 @@ void DefaultLightingSetup::run(const RenderContextPointer& renderContext) {
} }
auto lightStage = renderContext->_scene->getStage<LightStage>(); auto lightStage = renderContext->_scene->getStage<LightStage>();
if (lightStage) { if (lightStage) {
// Allocate a default global light directional and ambient // Allocate a default global light directional and ambient
auto lp = std::make_shared<model::Light>(); auto lp = std::make_shared<model::Light>();

View file

@ -121,6 +121,7 @@ public:
const DeferredFrameTransformPointer& frameTransform, const DeferredFrameTransformPointer& frameTransform,
const DeferredFramebufferPointer& deferredFramebuffer, const DeferredFramebufferPointer& deferredFramebuffer,
const LightingModelPointer& lightingModel, const LightingModelPointer& lightingModel,
const model::HazePointer& haze,
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer, const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer,
const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource); const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource);
@ -155,7 +156,10 @@ using RenderDeferredConfig = render::GPUJobConfig;
class RenderDeferred { class RenderDeferred {
public: 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 Config = RenderDeferredConfig;
using JobModel = render::Job::ModelI<RenderDeferred, Inputs, Config>; using JobModel = render::Job::ModelI<RenderDeferred, Inputs, Config>;

View file

@ -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 // DeferredBuffer is complete, now let's shade it into the LightingBuffer
const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel,
surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters).asVarying(); surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters, hazeModel).asVarying();
task.addJob<RenderDeferred>("RenderDeferred", deferredLightingInputs); task.addJob<RenderDeferred>("RenderDeferred", deferredLightingInputs);

View file

@ -285,10 +285,10 @@ public:
const T5& get5() const { return std::get<5>((*this)).template get<T5>(); } const T5& get5() const { return std::get<5>((*this)).template get<T5>(); }
T5& edit5() { return std::get<5>((*this)).template edit<T5>(); } T5& edit5() { return std::get<5>((*this)).template edit<T5>(); }
const T6& get6() const { return std::get<6>((*this)).template get<T6>(); } const T6& get6() const { return std::get<6>((*this)).template get<T6>(); }
T6& edit6() { return std::get<6>((*this)).template edit<T6>(); } T6& edit6() { return std::get<6>((*this)).template edit<T6>(); }
Varying asVarying() const { return Varying((*this)); } Varying asVarying() const { return Varying((*this)); }
}; };