mirror of
https://github.com/maxartz15/VolumetricLighting.git
synced 2024-12-22 06:28:27 +01:00
Improved transmission with an integral over slice depth - behaves nic…
This commit is contained in:
parent
6853822b7e
commit
9589c93f77
@ -455,7 +455,7 @@ public class VolumetricFog : MonoBehaviour
|
||||
// Compensate for more light and density being injected in per world space meter when near and far are closer.
|
||||
// TODO: Not quite correct yet.
|
||||
float depthCompensation = (farClip - nearClip) * 0.01f;
|
||||
m_InjectLightingAndDensity.SetFloat("_Density", m_GlobalDensityMult * 0.001f * depthCompensation);
|
||||
m_InjectLightingAndDensity.SetFloat("_Density", m_GlobalDensityMult * 0.128f * depthCompensation);
|
||||
m_InjectLightingAndDensity.SetFloat("_Intensity", m_GlobalIntensityMult);
|
||||
m_InjectLightingAndDensity.SetFloat("_Anisotropy", m_Anisotropy);
|
||||
m_InjectLightingAndDensity.SetTexture(kernel, "_VolumeInject", m_VolumeInject);
|
||||
|
@ -2,37 +2,41 @@
|
||||
// https://bartwronski.com/publications/
|
||||
|
||||
#pragma kernel CSMain
|
||||
#define VOLUME_DEPTH 128
|
||||
#define VOLUME_DEPTH 128.0
|
||||
|
||||
Texture3D _VolumeInject;
|
||||
RWTexture3D<float4> _VolumeScatter;
|
||||
|
||||
float Extinction(float density)
|
||||
float4 ScatterStep(float3 accumulatedLight, float accumulatedTransmittance, float3 sliceLight, float sliceDensity)
|
||||
{
|
||||
return exp(-density);
|
||||
}
|
||||
sliceDensity = max(sliceDensity, 0.000001);
|
||||
float sliceTransmittance = exp(-sliceDensity / VOLUME_DEPTH);
|
||||
|
||||
void WriteOutput(in uint3 pos, in float4 colorAndDensity)
|
||||
{
|
||||
_VolumeScatter[pos] = float4(colorAndDensity.rgb, Extinction(colorAndDensity.a));
|
||||
}
|
||||
// Seb Hillaire's improved transmission by calculating an integral over slice depth instead of
|
||||
// constant per slice value. Light still constant per slice, but that's acceptable. See slide 28 of
|
||||
// Physically-based & Unified Volumetric Rendering in Frostbite
|
||||
// http://www.frostbite.com/2015/08/physically-based-unified-volumetric-rendering-in-frostbite/
|
||||
float3 sliceLightIntegral = sliceLight * (1.0 - sliceTransmittance) / sliceDensity;
|
||||
|
||||
float4 AccumulateScattering(float4 colorAndDensityFront, float4 colorAndDensityBack)
|
||||
{
|
||||
float3 light = colorAndDensityFront.rgb + saturate(Extinction(colorAndDensityFront.a)) * colorAndDensityBack.rgb;
|
||||
return float4(light.rgb, colorAndDensityFront.a + colorAndDensityBack.a);
|
||||
accumulatedLight += sliceLightIntegral * accumulatedTransmittance;
|
||||
accumulatedTransmittance *= sliceTransmittance;
|
||||
|
||||
return float4(accumulatedLight, accumulatedTransmittance);
|
||||
}
|
||||
|
||||
[numthreads(32, 2, 1)]
|
||||
void CSMain (uint3 id : SV_DispatchThreadID)
|
||||
{
|
||||
float4 currentSlice = _VolumeInject[uint3(id.xy, 0)];
|
||||
WriteOutput(uint3(id.xy, 0), currentSlice);
|
||||
// Store transmission in .a, as opposed to density in _VolumeInject
|
||||
float4 accum = float4(0, 0, 0, 1);
|
||||
uint3 pos = uint3(id.xy, 0);
|
||||
uint steps = VOLUME_DEPTH;
|
||||
|
||||
for(uint z = 1; z < VOLUME_DEPTH; z++)
|
||||
for(uint z = 0; z < steps; z++)
|
||||
{
|
||||
float4 nextValue = _VolumeInject[uint3(id.xy, z)];
|
||||
currentSlice = AccumulateScattering(currentSlice, nextValue);
|
||||
WriteOutput(uint3(id.xy, z), currentSlice);
|
||||
pos.z = z;
|
||||
float4 slice = _VolumeInject[pos];
|
||||
accum = ScatterStep(accum.rgb, accum.a, slice.rgb, slice.a);
|
||||
_VolumeScatter[pos] = accum;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user