🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Questions regarding Beer Shadow Map [Hillaire20]

Started by
1 comment, last by PLCrashy 3 years, 1 month ago

Hi,

I'm trying to understand the concept of Beer Shadow Map introduced by Seb Hillaire in this presentation :

1:Right now I'm using a secondary ray march to evaluate the transmittance, but it's quite slow. As I understand it, the BSM could replace it with little quality loss but better performance, am I right ?

2: On this slide, he gives a few details on how to compute the transmittance from the BSM, but little is told about the BSM rendering part itself.

I suppose the BSM is rendered from an orthographic viewport, rendering a large portion of the world around the main view, just like a standard directional light shadow map. Maybe some kind of cascaded BSM could be used used too ?

I'm guessing the code to render it may look like this (dirty quick draft), but I'm not sure at all

vec3 renderBSM(vec3 rayOrigin, vec3 rayDir, float rayLength)
{
	float frontDepth = -1;
	float maxOpticalDepth = -1;
	float meanExtinction = 0;
	float densitySum = 0;
	int numSamples=0;
	
	for(int i=0;i<max_samples;++i)
	{
		vec3 p = rayOrigin + i * rayDir * rayLength;
		
		float s = sampleCloudDensity(p);
		
		if(s>0)
		{
			densitySum+=s;			
			//increase optical depth
			maxOpticalDepth+=rayLength;	
					
			//init front depth
			if(frontDepth < 0)
			{
				frontDepth = maxOpticalDepth;
			}			
			
			numSamples++;		
			
			//early break
			if(densitySum>=1.0f)
			{
				break;
			}	
		}
	}
	//how to compute meanExtinction ?? Like this ?
	if(numSamples>0)
	{
		meanExtinction=densitySum / numSamples;
	}
	return vec3(frontDepth, meanExtinction,maxOpticalDepth);
}

3: When rendering clouds in the main viewport, use this to evaluate the transmittance, but I'm not sure what the variable “d” means.

vec3 bsm = getBSM(p); //p is the current's sample position
//what is the d variable ? 
//The distance to the BSM camera ?
float OpticalDepth = min(bsm.b, bsm.g * max(0,d - bsm.r);
float Transmittance = exp(-OpticalDepth);

What do you think, does it looks like correct to you ?

Thanks !

Advertisement

Hi,

I've finally implemented it and and found the answers:

1:Right now I'm using a secondary ray march to evaluate the transmittance, but it's quite slow. As I understand it, the BSM could replace it with little quality loss but better performance, am I right ?

→In fact, BSM can't replace secondary ray march for small scale details, as it's not precise enough. But it's a good way to render long distance shadows

About the code to render BSM, here is the fixed code. I was almost right in the first post, except the max optical depth must be weighted by the sample density.

vec3 renderBSM(vec3 rayOrigin, vec3 rayDir, float rayLength,float tmin,float tmax)
{
	float frontDepth = -1;
	float maxOpticalDepth = 0.0f;
	float meanExtinction = 0;
	float extinctionAccumulator = 0;
	int numSamples=0;
	vec3 p = rayOrigin + rayDir*(tmin);
	
	float depth = tmin;
	
	for(int i=0;i<max_samples;++i)
	{
		p += rayDir * rayLength;
		//increase optical depth
		depth+=rayLength;
					
		float _sample = sampleCloudDensity(p);
		
		if(_sample>THRESHOLD)
		{
			//init front depth
			if(frontDepth < 0)
			{
				frontDepth = depth;
			}
			
			extinctionAccumulator+=_sample;		
			maxOpticalDepth+=_sample*rayLength;	//here, weight optical depth by sample 		

			numSamples++;		
			
			//early break
			if(extinctionAccumulator>=1.0f)
			{
				break;
			}
		}
	}
	if(numSamples>0)
	{
		meanExtinction=extinctionAccumulator / numSamples;
	}
	else
	{
		meanExtinction = 0.0f;
		frontDepth = tmax;//(max_samples) * rayLength  + startOffset;
		maxOpticalDepth = 0;
	}
	return vec3(frontDepth, meanExtinction,maxOpticalDepth);
}

Thanks

This topic is closed to new replies.

Advertisement