2016-11-01 13:25:56 +01:00
|
|
|
// Based on 'Volumetric fog: Unified, compute shader based solution to atmospheric scattering, ACM Siggraph 2014'
|
|
|
|
// https://bartwronski.com/publications/
|
|
|
|
|
|
|
|
#pragma kernel CSMain
|
2017-04-06 13:53:09 +02:00
|
|
|
#define VOLUME_DEPTH 128.0
|
2016-11-01 13:25:56 +01:00
|
|
|
|
|
|
|
Texture3D _VolumeInject;
|
|
|
|
RWTexture3D<float4> _VolumeScatter;
|
|
|
|
|
2017-04-06 13:53:09 +02:00
|
|
|
float4 ScatterStep(float3 accumulatedLight, float accumulatedTransmittance, float3 sliceLight, float sliceDensity)
|
2016-11-01 13:25:56 +01:00
|
|
|
{
|
2017-04-06 13:53:09 +02:00
|
|
|
sliceDensity = max(sliceDensity, 0.000001);
|
|
|
|
float sliceTransmittance = exp(-sliceDensity / VOLUME_DEPTH);
|
2016-11-01 13:25:56 +01:00
|
|
|
|
2017-04-06 13:53:09 +02:00
|
|
|
// 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;
|
2016-11-01 13:25:56 +01:00
|
|
|
|
2017-04-06 13:53:09 +02:00
|
|
|
accumulatedLight += sliceLightIntegral * accumulatedTransmittance;
|
|
|
|
accumulatedTransmittance *= sliceTransmittance;
|
|
|
|
|
|
|
|
return float4(accumulatedLight, accumulatedTransmittance);
|
2016-11-01 13:25:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
[numthreads(32, 2, 1)]
|
|
|
|
void CSMain (uint3 id : SV_DispatchThreadID)
|
|
|
|
{
|
2017-04-06 13:53:09 +02:00
|
|
|
// 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;
|
2016-11-01 13:25:56 +01:00
|
|
|
|
2017-04-06 13:53:09 +02:00
|
|
|
for(uint z = 0; z < steps; z++)
|
2016-11-01 13:25:56 +01:00
|
|
|
{
|
2017-04-06 13:53:09 +02:00
|
|
|
pos.z = z;
|
|
|
|
float4 slice = _VolumeInject[pos];
|
|
|
|
accum = ScatterStep(accum.rgb, accum.a, slice.rgb, slice.a);
|
|
|
|
_VolumeScatter[pos] = accum;
|
2016-11-01 13:25:56 +01:00
|
|
|
}
|
|
|
|
}
|