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()$>
<@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;
}

View file

@ -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<LightStage>();
if (lightStage) {
if (lightStage) {
// Allocate a default global light directional and ambient
auto lp = std::make_shared<model::Light>();

View file

@ -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<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
const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel,
surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters).asVarying();
surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters, hazeModel).asVarying();
task.addJob<RenderDeferred>("RenderDeferred", deferredLightingInputs);

View file

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