mirror of
https://github.com/maxartz15/VolumetricLighting.git
synced 2024-11-09 16:52:57 +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.
|
// Compensate for more light and density being injected in per world space meter when near and far are closer.
|
||||||
// TODO: Not quite correct yet.
|
// TODO: Not quite correct yet.
|
||||||
float depthCompensation = (farClip - nearClip) * 0.01f;
|
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("_Intensity", m_GlobalIntensityMult);
|
||||||
m_InjectLightingAndDensity.SetFloat("_Anisotropy", m_Anisotropy);
|
m_InjectLightingAndDensity.SetFloat("_Anisotropy", m_Anisotropy);
|
||||||
m_InjectLightingAndDensity.SetTexture(kernel, "_VolumeInject", m_VolumeInject);
|
m_InjectLightingAndDensity.SetTexture(kernel, "_VolumeInject", m_VolumeInject);
|
||||||
|
@ -2,37 +2,41 @@
|
|||||||
// https://bartwronski.com/publications/
|
// https://bartwronski.com/publications/
|
||||||
|
|
||||||
#pragma kernel CSMain
|
#pragma kernel CSMain
|
||||||
#define VOLUME_DEPTH 128
|
#define VOLUME_DEPTH 128.0
|
||||||
|
|
||||||
Texture3D _VolumeInject;
|
Texture3D _VolumeInject;
|
||||||
RWTexture3D<float4> _VolumeScatter;
|
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)
|
// 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
|
||||||
_VolumeScatter[pos] = float4(colorAndDensity.rgb, Extinction(colorAndDensity.a));
|
// 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)
|
accumulatedLight += sliceLightIntegral * accumulatedTransmittance;
|
||||||
{
|
accumulatedTransmittance *= sliceTransmittance;
|
||||||
float3 light = colorAndDensityFront.rgb + saturate(Extinction(colorAndDensityFront.a)) * colorAndDensityBack.rgb;
|
|
||||||
return float4(light.rgb, colorAndDensityFront.a + colorAndDensityBack.a);
|
return float4(accumulatedLight, accumulatedTransmittance);
|
||||||
}
|
}
|
||||||
|
|
||||||
[numthreads(32, 2, 1)]
|
[numthreads(32, 2, 1)]
|
||||||
void CSMain (uint3 id : SV_DispatchThreadID)
|
void CSMain (uint3 id : SV_DispatchThreadID)
|
||||||
{
|
{
|
||||||
float4 currentSlice = _VolumeInject[uint3(id.xy, 0)];
|
// Store transmission in .a, as opposed to density in _VolumeInject
|
||||||
WriteOutput(uint3(id.xy, 0), currentSlice);
|
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)];
|
pos.z = z;
|
||||||
currentSlice = AccumulateScattering(currentSlice, nextValue);
|
float4 slice = _VolumeInject[pos];
|
||||||
WriteOutput(uint3(id.xy, z), currentSlice);
|
accum = ScatterStep(accum.rgb, accum.a, slice.rgb, slice.a);
|
||||||
|
_VolumeScatter[pos] = accum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user