mirror of
				https://github.com/maxartz15/VolumetricLighting.git
				synced 2025-11-04 07:15:51 +01:00 
			
		
		
		
	Improved transmission with an integral over slice depth - behaves nic…
This commit is contained in:
		@@ -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;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user