ºÝºÝߣ

ºÝºÝߣShare a Scribd company logo
Precomputed Atmospheric Scattering
1
Eric Bruneton, Fabrice Neyret? 2008 ??. [Bruneton08]
??? ?? ???? ??? ???( ???, ?? ??, ?? )? ??? ??? ?? ??
( Precomputed ) ?? ?? ???? ????? ??? ??? ?? ????.
UE4? Atmospheric Fog? ? ??? ??? ?????. ( ???? Atmospheric~
?? ???? ??? )
??? OpenGL? ??? ?? ??? ????? ??? ???? ? ??? ??.
UE4 ??? ?? ??? ?? ????. ( Precomputed ??? ?? ? ?? ?? ?? )
??? ??? ?? ???? ?. ?? ??? ?? ?? ??? ????.
? ppt? ?? ??? ???? ?? ?? ??? ?? ??? ??? ??? ????
??? ???? ???.
Precomputed Atmospheric Scattering
2
??? ?? ??? ?????.
?? ??? ???? ?? ??? ?????? ???? ?? ????.
Q. ?? ???? ???? ? ? ????
A. ? ? ??.
Q. ?? ???? ???? ? ? ?? ????
?? ??( Scattering )
???? ?? ?????? ??
???? ? ?? ?? ??? ??? ? ??.
3
A. ???? ?? ???? ??? ??? ????.
https://youtu.be/qybisPmc2xw?t=67
??? ?? ?? ???? ???? ???? ???? ??? ??( Scattering ) ??
??.
?? ?? ??? ? ? ?? ?? ?? ????.
?? ???? ??? ?? ???? ????? ?? ??? ?? ???? ??.
?? ??( Scattering )
4
??? ??? ???? ?? ?????.
??? ??? ??? ?? ??? ???? ??.
??? ?? ??? ??? ?? ???? ????? ???? ??? ??? ? ??
??? ?? ??? ??? ????.
??( Atmosphere )
?? ??
?? (?2) 78.084%
?? (?2) 20.946%
??? (??) 0.9340%
????? (??2) 0.04%
?? (??) 0.001818%
?? (??) 0.000524%
?? (??4) 0.000179%
??? (?2 ?) 0.001% ~ 5%
??
5
??? ??? ??? ??? ??? ?? 2?? ???? ??? ? ??.
???? ??? ??? ????? ???? ?? ????. ( Molecules )
??? ??? ??(?? ??, ??)? ???? ?? ???? ?? ??? ?? ???
? ? ?? ??? ??? ??( Rayleigh Scattering )?? ??.
??? ??? ?? ??? ??? ?? ??? ?? ??? 4 ??? ????? ????
?? ?? ????.
?, ??? ? ?? ??? ? ???? ??? ???.
?? ??? ????? ??? ??? ??? ????? ????? ? ?? ??? ??
?? ??? ? ???? ??.
?? ??( Atmospheric Scattering )
6
??? ??? ??? ??? ??? ??? ?? ??? ?? ? ?? ???? ???
???? ????.
???? ??? ?? ??? ??? ?? ???? ??? ??? ???? ???? ??
???? ??? ???? ?? ??? ?? ???? ??? ???? ??? ?? ??
??? ???? ????.
?? ??( Atmospheric Scattering )
7
???? ??? ??? ????? ??? ??? ????. ( Aerosol )
???? ??, ?? ??? ?? ??? ??? ?? ??? ???? ? ? ?? ???
? ??( Mie Scattering ) ?? ??.
? ??? ?? ?? ????? ??? ??, ??, ??? ??? ???.
??? ??? ? ??? ?? ??? ? ??? ??? ?? ??? ?? ??? ???
?? ???. ( ?? ? ??? ???? ?? ?? ??? ?? ??? ?? )
????? ?? ??? ??? ??? ???? ???? ??? ???? ?? ???
?? ???. ??? ??? ?????? ??? ?? ? ? ?? ?? ???.
?? ??( Atmospheric Scattering )
8
??? ??? ?? ?? ???.
?? ??? ??? ?? ? ??.
?? ??? ??? ??? ?? ???.
Out-Scattering
In-Scattering
??? ?
Absorption
9
???? ?? ?? ? ? ?? ?? ???.
??? ??? ??? ???? ?? ??? ??. ( Out-Scattering, Absorption )
???? ?? ??? ???? ??? ???? ??? ?? ?? ???? ????.
Transmittance ( ??? )
A
B
?? : A ???? ?? ?
? ? : B ???? ?? ?
Transmittance ¡ú ?(??) =
? ?
? ? 10
T x, x0 = ?? ????
?0 ¦Ò ?¡Ê{?,?} ??
?
? ??
??
?
= extinction coefficient (?? ??)
: ?? 1m? ???? ?? ??? ?? ????? ??? ???? ?? (= ?? )
?, ?? ??? ??? ????? ????1 ????2 ??? ???? ???? ??? ??
?, ?0 = ?? ?? ??
? = Rayleigh (???)
? = Mie (?)
y = ??
2. Absorption(??)
1. Scattering(??)
??
?
= ??
?
+ ??
?
Transmittance ( ??? )
11
?? ??( ??
?
)? ?? ???( scattering equation )?? ????.
??? ?? ??? ?(?, ?, ?)? ??? ??.
? : ??.
? : ?? ??.
? : ??.
? = 1.00029 : ??? ???.
? = 2.504 ? 1025 : ?? ??? ?? ?? ??. ( = ?3 ? ??? ? )
? ? : ?? ?.( density ratio ) ?????? 1?? ??? ??? ?? ?????
?? ????.
¡ù ??? ???? ??? ?? ???? Display of The Earth Taking into Account Atmospheric Scattering ???? ??? ?
??. ?????? ??? ? ? ?? ???.
? ?, ?, ? =
?2 ?2?1
2
2
? ?
?
1
?4 (1 + cos2 ?)
Scattering Equation ( ?? ??? )
12
??? ?? ??? ?(?, ?, ?)? ?? ??(?)?? ??? ?? ?? ????? ????.
??? ???? ?? ???? ??? ???? ?? ??? ??? ??? ??.
? ?, ? = ?
?
? ?, ?, ? ??
= ?
0
2?
?
0
?
? ?, ?, ? ????????
= ?
0
2?
?
0
?
?2 ?2 ? 1 2
2
? ?
?
1
?4 (1 + cos2 ?)????????
=
?2 ?2 ? 1 2
2
? ?
?
1
?4 ?
0
2?
?
0
?
(1 + cos2 ?)????????
=
?2 ?2 ? 1 2
2
? ?
?
1
?4 ?
0
2?
8
3
??
=
?2 ?2 ? 1 2
2
? ?
?
1
?4
16?
3
=
8?3 ?2 ? 1 2
3
? ?
?
1
?4 =
8?3 ?2 ? 1 2
3??4 ? ?
Scattering Equation ( ?? ??? )
13
??? ??? ? ?, ? ? ??? ?? ??( Rayleigh Scattering Coefficient )?
?? ? ?
?
? ????.
??? ??? ??? ?? ????? ? ?? ???? ??? ? ?
?
= ? ?
?
? ??.
? ??? ?? ?? ?? ? ?
?
? ? ?
?
?, ? = ? ?
?
(0, ?)? ? ? ??? ??? ???? ??
?? ?? ? ?
?
? ?? ??(? ?
?
)? ?? ??(? ?
?
)? ??? ?? ? ??.
???? ? ?? ? ?? ?? ?? ??? ??? ?? ?(? ? )? ????? ???
??? ???.
? ?? ?? ?? ?????? ??? ? ??.
? ?
?
= ? ?
?
+ ? ?
?
? ?
?
(?) =
8?3 ?2 ? 1 2
3??4 ? ?
? ?
?
(?) = ? ?
?
(0, ?)? ?
Scattering Coefficient ( ?? ?? )
14
??? ??? ?? ??? ????. ?? ?? ? ??? ??? ???? ??? ???
?? ??? ? ??.
?? ? ? ? ? ?? ???? ??? ?? 0??? ??? ??? ??? ?? ????.
??? ??? ?? ???? ??, ??, ??? ?? ?? ??? ???? ???
1976??? ???? ? ?? ?? ??? ??? ?? ??? ???? ??? ??.
Density ratio ( ?? ? )
? ? =
??????? ?
???????(0)
??(?) ??(??/?3)
0 1.2250
500 1.1673
1000 1.1117
1500 1.0581
2000 1.0066
2500 0.95695
3000 0.90912
3500 0.86323
4000 0.81913
4500 0.77677
?? : https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770009539.pdf
15
? ?? ?? ?? ?? ???? ??? 0 ? ?? 1, ??? 4000? ?? 0.66868? ?
?.
?? ??? ??? ?? ?? ?? ?? ???? ?? ?? ???? ?? ??? ???
? ???? ??.
??? ?? ??? ???? ???? ??? ?? ????? ???? ?? ?? ? ?
??.
Density ratio ( ?? ? )
0
0.2
0.4
0.6
0.8
1
1.2
1.4
0 5000 10000 15000 20000 25000 30000 35000
16
??? ???? ?? ??? ??? ??. ?? ?? ???? ??? ??.
? : ?? ??( scale height )
?? ??? ?? ?? ????( e = 2.71828 ) ? ??? ????? ???? ???
???, ? ??? ?? ?? ?? ????.
Density ratio ( ?? ? )
? ? = e?
?
?
?? ?? ?? ??(??)
Rayleigh 8.5
Mie 1.2
0
0.2
0.4
0.6
0.8
1
1.2
0 5000 10000 15000 20000 25000 30000 35000
??? ????? ?? ?
?? ?? ?
?? ?? ?
17
?? ???? ???? ?? ?? ????
???? ???? ?? ?? ?? ??
?
? ??? ?? ??? ? ? ??.
???? ?? ??? ?? ????
???? ?? ?? ?? ( x ~ x0 ) ? ????? ??? ?? ???? ???? ?? ?
? ?? ????. ??? ??? ?? ??? ?0, ? ?? ?? ? ?? ??? ?1?? ??
??.
? ? ???? ?? ??? ? ?? ??? ?????
Transmittance ( ??? )
T x, x0 = ?? ????
?0 ¦Ò ?¡Ê{?,?} ??
?
? ??
?1 = ?0(1 ? ? ?)
?1 = ?0(1 ?
? ?
2
)
?2 = ?1 1 ?
? ?
2
= ?0 1 ?
? ?
2
2
18
??? ???? ??? ?????
? ?? ?? ??? ?? 1m ? ????? ??? ????? ??? ??( ? )? ??
???? ??? ?? ????.
??? ?? ??? ?? ??? ???? ??? ? ? ???
? ? ?? ??? ??( Optical depth ) ? ??.
Transmittance ( ??? )
? = ?0 lim
?¡ú¡Þ
1 ?
? ?
?
?
?
?0
= ? = ??? ?
? = ?0 ??? ?
¡ß lim
?¡ú¡Þ
1 +
1
?
?
= e
? = ??? ? ?
? = ??? ????????
? ? ? ?
19
? = ???¦È
(¦È : ??? ?????? ???( zenith angle ))
? ¡Ã ??
r
?
Transmittance Table
20
Compute Shader? ???? Transmittance Table? ?????. cs_5_0? ???
??( Maximum Threads = 1024 ) ??? ???? ??? Dispatch ???.
??? ?? ?? T x, x0 = ?? ????
?0 ¦Ò ?¡Ê{?,?} ??
?
? ??
? ??? ???? ?? ? ? ??.
GetTransmittanceRMu ??? ??? UV? ?? ??(R)? ??? ???(Mu)? ??
?.
Transmittance Table
[numthreads(TRANSMITTANCE_W / TRANSMITTANCE_GROUP_X, TRANSMITTANCE_H / TRANSMITTANCE_GROUP_Y, 1)]
void main( uint3 DTid : SV_DispatchThreadID )
{
float r, muS;
GetTransmittanceRMu( DTid, r, muS );
float3 depth = betaR * OpticalDepth( HR, r, muS ) + betaMEx * OpticalDepth( HM, r, muS );
transmittanceBuffer[DTid.xy] = float4( exp( -depth ), 0.f );
}
void GetTransmittanceRMu( uint3 DTid, out float r, out float muS )
{
r = DTid.y / float( TRANSMITTANCE_H );
muS = DTid.x / float( TRANSMITTANCE_W );
#ifdef TRANSMITTANCE_NON_LINEAR
r = Rg + ( r * r ) * ( Rt - Rg );
muS = -0.15f + tan( 1.5f * muS ) / tan( 1.5f ) * ( 1.f + 0.15f );
#else
r = Rg + r * ( Rt - Rg );
muS = -0.15f + muS * ( 1.f + 0.15f ); // 0 ~ ( pi/2 + epsilon )
#endif
}
21
OpticalDepth? ??? ??? ????.
?? limit ??? ??? ??? ???? ??? ??? ??? ???? ???
????? ???.
Transmittance Table
float OpticalDepth( float H, float r, float mu )
{
float result = 0.f;
float dx = limit( r, mu ) / float( TRANSMITTANCE_INTEGRAL_SAMPLES );
float xi = 0.f;
float yi = exp( -( r - Rg ) / H );
for ( int i = 1; i <= TRANSMITTANCE_INTEGRAL_SAMPLES; ++i )
{
float xj = float( i ) * dx;
float yj = exp( -( sqrt( r * r + xj * xj + 2.f * xj * r * mu ) - Rg ) / H ); // law of cosines
result += ( yi + yj ) * 0.5f * dx;
xi = xj;
yi = yj;
}
return mu < -sqrt( 1.f - ( Rg / r ) * ( Rg / r ) ) ? 1e9f : result;
}
t
??? ???? ?? ?? ???? ???? ?? 22
?? ??? ???? ??? ???? ??? ? ??.
Transmittance Table
float limit( float r, float mu )
{
float dout = -r * mu + sqrt( r * r * ( mu * mu - 1.f ) + RL * RL );
float delta2 = r * r * ( mu * mu - 1.f ) + Rg * Rg;
if ( delta2 >= 0.f )
{
float din = -r * mu - sqrt( delta2 );
if ( din > 0.f )
{
dout = min( dout, din );
}
}
return dout;
}
float dout = -r * mu + sqrt( r * r * ( mu * mu - 1.f ) + RL * RL );
23
????? ?? ???? ????? ? ? ? ? ? ??? ?? ???? ?? ???? ??
?? ??? ?? ??? ??? ????.
??? ??? ??? ?? ??? ??? ? 2 ??? ??(?2 = ?2 + ?2 ? 2??????)?
?? ??? ??.
Transmittance Table
a
r * r + xj * xj + 2.f * xj * r * mu
24
?? ?? ?? ?? ??( Irradiance )? ???? ??? ????.
?? ??? ?? ??( ?? )? ??? ?? ?? ?( ? ¡Ã ??????? ???? ) ? ??? ???
??? ? =
?
??
? ??? ? ??.
? ???? ??? ?? ???? ???? ?? ??( ? : radiance )?? ??? ???
??? ?? ??? ?? ???? ?? ???? ??? ?, ? ???? ??? ?? ??
????, ?? ?? ? ? ???? ?? ?? ???.
?? ??? L =
¦µ
????????
? ??? ? ?? ?? ??? ?? ??? ??? ? ??.
Irradiance
E = ?
¦¸
???????
??
??
25
?? ?? ?? ?? ??? ??? ? ???? ???? ??? ?? ???? ????
??? ?? ???? ??? ? ??.
????? ? ???? ??? E = ?(?, ?0) ???? ? ???? ????.
Single Irradiance Table
E = ?(?, ?0)? ??? ????
[numthreads( IRRADIANCE_W / IRRADIANCE_GROUP_X, IRRADIANCE_H / IRRADIANCE_GROUP_Y, 1)]
void main( uint3 DTid : SV_DispatchThreadID )
{
float r, muS;
GetIrradianceRMuS( DTid, r, muS );
irradiance1Buffer[DTid.xy] = float4( Transmittance( r, muS ) * max( muS, 0.f ), 0.f );
}
? = ???¦È
(¦È : ??? ????? ???( zenith angle ))
? ¡Ã ??
26
?? ??? ?? ??? ????? ??. ???? ???, ?? ?? ???? ?? ??
?? 3D ???? ????.
??? 3D ???? 4?? ??? LUT( Look Up Table )? ???? ?? ???
??? ??.
Single Inscatter Table
? ¡Ã ??
? = ???¦È
(¦È : ??? ??????
???( zenith angle ))
? ? = ???¦È ??? (¦È ??? : ??? ???( zenith angle ))
? = ???? (? : ??? ??? ?? ?)
Rayleigh Inscatter Table? ?? ??? ??
27
?? ???? ?? ?? ? ?, ? ? ??? ??? ?? ??? ? ??.
? ? ? ?? ??? ?(?, ?, ?)? ?? ?? ? ?, ? ? ??? ??? ?? ? ??.
??? ?? ???? ?? ??? ?? ? ? ? ????
??? ???? ??? ?? ???? ?? ? ? ??.
? ? ? ?? ?? ?? ?? ??? ???? ?? ??( Phase Function )? ???.
Phase Function
?(?, ?, ?) = ? ?, ? ?(?)
? ? =
? ?, ?, ?
? ?, ?
? ? =
?2 ?2 ? 1 2
2
? ?
?
1
?4 1 + cos2 ?
3??4
8?3 ?2 ? 1 2 ? ?
=
3
16?
1 + cos2 ?
? ?, ?, ?
1
? ?,?
28
???, ? ?? ???? ?? ???? ??? ? ? ??.
?? ???? Inscatter ???? ????.
Single Inscatter Table
[numthreads( RES_MU_S, RES_MU / INSCATTER1_GROUP_Y, 1)]
void main( uint3 DTid : SV_DispatchThreadID )
{
float r;
float4 dhdH;
GetRdhdH( DTid.z, r, dhdH );
float mu, muS, nu;
GetMuMuSNu( DTid, r, dhdH, mu, muS, nu );
float3 ray, mie;
Inscatter( r, mu, muS, nu, ray, mie );
deltaSRBuffer[DTid] = float4( ray, 0.f );
deltaSMBuffer[DTid] = float4( mie, 0.f );
}
void Inscatter( float r, float mu, float muS, float nu, out float3 ray, out float3 mie )
{
ray = 0.f;
mie = 0.f;
float dx = limit( r, mu ) / float( INSCATTER_INTEGRAL_SAMPLES );
float3 rayi;
float3 miei;
Integrand( r, mu, muS, nu, 0.f, rayi, miei );
for ( int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i )
{
float xj = float( i ) * dx;
float3 rayj;
float3 miej;
Integrand( r, mu, muS, nu, xj, rayj, miej );
ray += ( rayi + rayj ) * 0.5f * dx;
mie += ( miei + miej ) * 0.5f * dx;
rayi = rayj;
miei = miej;
}
ray *= betaR;
mie *= betaMSca;
}
?? ??? ????? ???? ????.
¡ù ?? ??? ???? ???
????? ???? ????. 29
??? ?? ?? ??? ??? ??? ?? ??? ?? ???? ??? ???? ??.
Single Inscatter Table
void Integrand( float r, float mu, float muS, float nu, float t, out float3 ray, out float3 mie )
{
ray = 0.f;
mie = 0.f;
float ri = sqrt( r * r + t * t + 2.f * r * mu * t );
float muSi = ( nu * t + muS * r ) / ri;
ri = max( Rg, ri );
// ???? ??? ??? ???? ??? ??? ??? ??? ??? ??
// = ??? ??? ???? ?? ???? ?? 0
if ( muSi >= -sqrt( 1.f - Rg * Rg / ( ri * ri ) ) )
{
float3 ti = Transmittance( r, mu, t ) * Transmittance( ri, muSi );
ray = exp( -( ri - Rg ) / HR ) * ti;
mie = exp( -( ri - Rg ) / HM ) * ti;
}
}
t
30
???? ???? ??? ?? ??, ??? ?????. ??? ???? ??? ???
? ???? ??? ????? ??????? ??.
?? ?? ????? ???? ?? ????.
? ?[? ???] : ???? ??? ??? ?? ( ?? ?? ?? X )
? ?? : ?? ?? ( ???, ? ?? ?? ?? ?? ¡ð )
?? : ??? ?? ??
? ?,? : ? ??? red ?? ? ( ?? ?? ?? X )
Multiple Inscatter Table
R G B A
?? = ? ? ? ??? +
? ??
??
? ?,?
[numthreads( RES_MU_S, RES_MU / INSCATTER1_GROUP_Y, 1)]
void main( uint3 DTid : SV_DispatchThreadID )
{
float3 uvw = ( DTid.xyz + 0.5f ) / float3( RES_MU_S * RES_NU, RES_MU, RES_R );
float4 ray = deltaSRTex.SampleLevel( deltaSRSampler, uvw, 0 );
float4 mie = deltaSMTex.SampleLevel( deltaSMSampler, uvw, 0 );
float pitch = RES_MU_S * RES_NU;
float slicePitch = pitch * RES_MU;
inscatterBuffer[( DTid.z * slicePitch ) + ( DTid.y * pitch ) + DTid.x] = float4( ray.rgb, mie.r );
}
? ? ? ??? ? ? ?,?? ?? ???? ??? ???.
? ??
? ?
?
? ?? ???? ??? ???.
31
??? ???? ??? LUT? ?? ???? ?? ??? ?? ???? ??? ? ??
??? ? ??? ??? ??? ??? ?? ????.
??? ??? ?? ? ??? red ?? ?? ???? ???? ?? ??? ?? ???
?? ????.
?? ??? ? ??? ??? ????? ?? ?? ?? y?? ?? ?? v? ????
?? ?? ????.
Multiple Inscatter Table
? ? ? ??
? ?,?
??,?
? ?,?
?
? ?,?
?
? ?
?
? ?
?
[numthreads( RES_MU_S * RES_NU / INSCATTERS_GROUP_X, RES_MU / INSCATTERS_GROUP_Y, 1 )]
void main( uint3 DTid : SV_DispatchThreadID )
{
float r;
float4 dhdH;
GetRdhdH( g_threadGroupZ, r, dhdH );
float mu, muS, nu;
GetMuMuSNu( float3( DTid.xy, g_threadGroupZ ), r, dhdH, mu, muS, nu );
float3 raymie;
Inscatter( r, mu, muS, nu, raymie );
deltaJBuffer[DTid] = float4( raymie, 0.f );
}
y
32
?? ?? y? ???? ?? ?? ???? ??? Inscatter ??? ? ??? ?? ??
? ???? ??.
??? ?? ??? ?? ???? ??? ????. ?? ???? ?? ???? ???.
?? ?? ?? ??? ???? ???? ? ??? ???? ????.
Multiple Inscatter Table
void Inscatter( float r, float mu, float muS, float nu, out float3 raymie )
{
r = clamp( r, Rg, Rt );
mu = clamp( mu, -1.f, 1.f );
muS = clamp( muS, -1.f, 1.f );
// Using formula sum and differences of cosine
float var = sqrt( 1.f - mu * mu ) * sqrt( 1.f - muS * muS );
nu = clamp( nu, mu * muS - var, mu * muS + var );
// cos( theta to the horizon )
float cthetamin = -sqrt( 1.f - ( Rg * Rg ) / ( r * r ) );
float3 v = float3( sqrt( 1.0 - mu * mu ), 0.f, mu );
float sx = v.x == 0.f ? 0.f : ( nu - muS * mu ) / v.x;
float3 s = float3( sx, sqrt( max( 0.f, 1.f - sx * sx - muS * muS ) ), muS );
raymie = 0.f;
cthetamin
33
???? ?? ????? ?? ?? ?? ???? ? ??? ?? ??? ???? ???
?? ???? ???? ??? ??? ?? ??? ?(greflectance)? ???
(gtransp)? ??? ??.
Multiple Inscatter Table
// Compute equation(7)
// ?(0 ~ ?)? ?? ??
for ( int itheta = 0; itheta < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++itheta )
{
float theta = ( float( itheta ) + 0.5f ) * dtheta;
float ctheta = cos( theta );
float greflectance = 0.f;
float dground = 0.f;
float3 gtransp = 0.f;
// if ground visible in direction w compute transparency gtransp between x and ground
if ( ctheta < cthetamin )
{
greflectance = AVERAGE_GROUND_REFLECTANCE / M_PI;
dground = -r * ctheta - sqrt( r * r * ( ctheta * ctheta - 1.f ) + Rg * Rg );
gtransp = Transmittance( Rg, -(r * ctheta + dground) / Rg , dground );
}
34
Multiple Inscatter Table
// ?(0 ~ 2?)? ?? ??
for ( int iphi = 0; iphi < 2 * INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++iphi )
{
float phi = ( float( iphi ) + 0.5f ) * dphi;
float dw = dtheta * dphi * sin( theta );
float3 w = float3( cos( phi ) * sin( theta ), sin( phi ) * sin( theta ), ctheta );
float nu1 = dot( s, w );
float nu2 = dot( v, w );
float pr2 = PhaseFunctionR( nu2 );
float pm2 = PhaseFunctionM( nu2 );
float3 gnormal = ( float3( 0.f, 0.f, r ) + dground * w ) / Rg;
float3 girradiance = Irradiance( Rg, dot( gnormal, s ) );
// first term = light reflected from the ground and attenuated before reaching x
float3 raymie1 = greflectance * girradiance * gtransp;
???? ??? ?? ?? ??? ???? ????.
?? ???? ? ?? ??? ?? ?? ??? ? ? ??.
??? ???? ??? ?? ??.
? ? = ? ? + ?
¦¸
? ??, ? ? ?? ? ? ? ??
? ? = ?
¦¸
? ??, ? ? ?? ? ? ? ?? = ? ??, ? ? ?
¦¸
?? ? ? ? ??
? ? = ? ??, ? ? ?
???? ???? ? ??. Lambertian BRDF ??? ?? ??? ? ? ??.
35
????? ?? ? ? ??? ??? ( 1. ??? ?? ???? ?? ?? y? ????
2. ?? ?? y?? ?? ?? v? ???? ) ?? ???? 2? ????.
?? ??? ???? ??? ?? ??? ????. ??? ? ??? ??? ?? ??
????.
g_order? ???? ?? ?? ??? ?? ??? ???? ???? ?? ??? ??
?? ??? ?? ??? ??? ?? ????.
Multiple Inscatter Table
// second term = inscattered light = deltaS
// ???? ??? ?? ??? ??? ??? 1??? ??? ??? ?? ??? ?? ??? ?? 2? ??.
if ( g_order == 2 )
{
// ?? ?? ?? ???? ?? ??? ???? ????. ??? ? ?? ??? ???? ????? ??? ???? ?????.
float pr1 = PhaseFunctionR( nu1 );
float pm1 = PhaseFunctionM( nu1 );
float3 ray1 = Sample4D( deltaSRTex, deltaSRSampler, r, w.z, muS, nu1 ).rgb;
float3 mie1 = Sample4D( deltaSMTex, deltaSMSampler, r, w.z, muS, nu1 ).rgb;
raymie1 += ray1 * pr1 + mie1 * pm1;
}
else
{
// ?? ??? ?? ?? ??? ?? ??? ?? ????.
raymie1 += Sample4D( deltaSRTex, deltaSRSampler, r, w.z, muS, nu1 ).rgb;
}
// light coming from direction w and scattered in direction v
// Equation 7
raymie += raymie1 * ( betaR * exp( -( r - Rg ) / HR ) * pr2 + betaMSca * exp( -( r - Rg ) / HM ) * pm2 ) * dw;
}
}
}
1
2
36
?? ?? ??? ?? ??? ??? ? ???? ??? ?? ??? ?? ?? ???
?? ??? ???? ???.
?? ?? ??? ??? ?? ???? ????? ??? ???? ??.
Multiple Inscatter Table
y
[numthreads( RES_MU_S, RES_MU / INSCATTERN_GROUP_Y, 1 )]
void main( uint3 DTid : SV_DispatchThreadID )
{
float r;
float4 dhdH;
GetRdhdH( DTid.z, r, dhdH );
float mu, muS, nu;
GetMuMuSNu( DTid, r, dhdH, mu, muS, nu );
deltaSRBuffer[DTid] = float4( Inscatter( r, mu, muS, nu ), 0.f );
}
37
??? ???? ???? ?? ???? ???? ?? ???? ???? ????.
Multiple Inscatter Table
float3 Integrand( float r, float mu, float muS, float nu, float t )
{
float ri = sqrt( r * r + t * t + 2.f * r * t * mu );
float mui = ( r * mu + t ) / ri;
float muSi = ( nu * t + muS * r ) / ri;
return Sample4D( deltaJTex, deltaJSampler, ri, mui, muSi, nu ).rgb * Transmittance( r, mu, t );
}
float3 Inscatter( float r, float mu, float muS, float nu )
{
float3 raymie = 0.f;
float dx = limit( r, mu ) / float( INSCATTER_INTEGRAL_SAMPLES );
float xi = 0.f;
float3 raymiei = Integrand( r, mu, muS, nu, 0.f );
for ( int i = 0; i < INSCATTER_INTEGRAL_SAMPLES; ++i )
{
float xj = float( i ) * dx;
float3 raymiej = Integrand( r, mu, muS, nu, xj );
raymie += ( raymiei + raymiej ) * 0.5f * dx;
xi = xj;
raymiei = raymiej;
}
return raymie;
}
38
?? ?? ????? 31? ?????? ???? ? ?? ??? ?? ??? ?? ??
????.
???? ???? 2? ??? ???? ? ?? ??? ??? ?? ??. ? ? ????
??? ?? ??? ? ??? ?? ?? ????.
Multiple Inscatter Table
[numthreads( RES_MU_S, RES_MU / INSCATTERN_GROUP_Y, 1 )]
void main( uint3 DTid : SV_DispatchThreadID )
{
float r;
float4 dhdH;
GetRdhdH( DTid.z, r, dhdH );
float mu, muS, nu;
GetMuMuSNu( DTid, r, dhdH, mu, muS, nu );
float3 uvw = ( DTid.xyz + 0.5f ) / float3( RES_MU_S * RES_NU, RES_MU, RES_R );
float pitch = RES_MU_S * RES_NU;
float slicePitch = pitch * RES_MU;
inscatterBuffer[( DTid.z * slicePitch ) + ( DTid.y * pitch ) + DTid.x] +=
float4( deltaSRTex.SampleLevel( deltaSRSampler, uvw, 0 ).rgb / PhaseFunctionR( nu ), 0.f );
}
39
Multiple Inscatter Table
// 4?? ?? ??? ?????
for ( int order = 2; order <= 4; ++order )
{
int* gpuScatteringOrder = static_cast<int*>( renderer.LockBuffer( precomputeBuf ) );
gpuScatteringOrder[0] = order;
renderer.UnLockBuffer( precomputeBuf );
renderer.BindConstantBuffer( SHADER_TYPE::CS, 0, 1, &precomputeBuf );
// Compute deltaJ
renderer.BindShader( SHADER_TYPE::CS, csInscatterS );
renderer.BindShaderResource( SHADER_TYPE::CS, 1, 1, &deltaESrv );
renderer.BindRandomAccessResource( 0, 1, &deltaJRav );
// ??? ??? ?? ????? ???? Device Lost? ??. ??? ??? Dispatch.
for ( int i = 0; i < INSCATTERS_GROUP_Z; ++i )
{
gpuScatteringOrder = static_cast<int*>( renderer.LockBuffer( precomputeBuf ) );
gpuScatteringOrder[0] = order;
gpuScatteringOrder[1] = i;
renderer.UnLockBuffer( precomputeBuf );
renderer.BindConstantBuffer( SHADER_TYPE::CS, 0, 1, &precomputeBuf );
renderer.Dispatch( INSCATTERS_GROUP_X, INSCATTERS_GROUP_Y );
renderer.WaitGPU( );
}
¡­
// Compute deltaS
renderer.BindShader( SHADER_TYPE::CS, csInscatterN );
renderer.BindShaderResource( SHADER_TYPE::CS, 4, 1, &deltaJSrv );
renderer.BindShaderResource( SHADER_TYPE::CS, 2, 1, nullptr );
renderer.BindRandomAccessResource( 0, 1, &deltaSRRav );
renderer.Dispatch( INSCATTERN_GROUP_X, INSCATTERN_GROUP_Y, INSCATTERN_GROUP_Z );
¡­
} 40
?? Inscatter Table
Multiple Inscatter Table
? ¡Ã ??
? = ???¦È
(¦È : ??? ??????
???( zenith angle ))
? ? = ???¦È ??? (¦È ??? : ??? ???( zenith angle ))
? = ???? (? : ??? ??? ?? ?)
41
????? ?? ??? ?? ?? ??? ???? ??.
Multiple Irrdiance Table
[numthreads( IRRADIANCE_W / IRRADIANCE_GROUP_X, IRRADIANCE_H / IRRADIANCE_GROUP_Y, 1 )]
void main( uint3 DTid : SV_DispatchThreadID )
{
float r, muS;
GetIrradianceRMuS( DTid, r, muS );
float3 s = float3( max( sqrt( 1.0 - muS * muS ), 0.f ), 0.f, muS );
float3 result = 0.f;
// ????? ??? ??
for ( int iphi = 0; iphi < 2 * IRRADIANCE_INTEGRAL_SAMPLES; ++iphi )
{
float phi = ( float( iphi ) + 0.5f ) * dphi;
for ( int itheta = 0; itheta < IRRADIANCE_INTEGRAL_SAMPLES / 2; ++itheta )
{
float theta = ( float( itheta ) + 0.5f ) * dtheta;
float dw = sin( theta ) * dtheta * dphi;
float3 w = float3( cos( phi ) * sin( theta ), sin( phi ) * sin( theta ), cos( theta ) );
float nu = dot( s, w );
// ?? ?? ??? ????? ?????? ?? ??? ????? ???? ??? ??.
if ( g_order == 2 )
{
float pr = PhaseFunctionR( nu );
float pm = PhaseFunctionM( nu );
float3 ray = Sample4D( deltaSRTex, deltaSRSampler, r, w.z, muS, nu ).rgb;
float3 mie = Sample4D( deltaSMTex, deltaSMSampler, r, w.z, muS, nu ).rgb;
result += ( ray * pr + mie * pm ) * w.z * dw;
}
else
{
result += Sample4D( deltaSRTex, deltaSRSampler, r, w.z, muS, nu ).rgb * w.z * dw;
}
}
}
irradianceBuffer[DTid.xy] = float4( result, 0.f );
} 42
?? Irradiance Table
Multiple Irradiance Table
? = ???¦È
(¦È : ??? ????? ???( zenith angle ))
? ¡Ã ??
43
?? ???? ??? ?? ?, ?? ?, ??? ?? ?? ??? ?? ??? ????.
Rendering
VS_OUTPUT main( uint vertexID : SV_VertexID )
{
VS_OUTPUT output = (VS_OUTPUT)0;
float2 uv = float2( ( vertexID & 1 ) << 1, vertexID & 2 );
float4 pos = float4( float2( -1.f, 1.f ) + uv * float2( 2.f, -2.f ), 0.f, 1.f );
output.position = pos;
float4x4 invVewProjection = mul( g_invProjectionMatrix, g_invViewMatrix );
float4 worldPos = mul( float4( pos.xy, 1.f, 1.f ), invVewProjection );
output.worldPos = worldPos.xyz / worldPos.w;
return output;
}
float4 main( PS_INPUT input ) : SV_Target
{
float3 viewRay = normalize( input.wolrdPos - g_cameraPos.xyz );
float scale = 0.00001f; // ?? ??? ??? ?? ??? ?
float3 viewPos = g_cameraPos.xyz * scale;
viewPos.y += Rg + HeightOffset;
float r = length( viewPos );
float mu = dot( viewPos, viewRay ) / r;
float t = -r * mu - sqrt( r * r * ( mu * mu - 1.f ) + Rg * Rg );
float3 attenuation;
float3 inscatterColor = InscatterColor( viewPos, t, viewRay, r, mu, attenuation );
float3 groundColor = GroundColor( viewPos, t, viewRay, r, mu, attenuation );
float3 sunColor = SunColor( viewPos, t, viewRay, r, mu );
return float4( HDR( sunColor + inscatterColor + groundColor ), 1.f );
}
44
Rendering - Inscatter Color
float3 InscatterColor( float3 x, float t, float3 viewRay, float r, float mu, out float3 attenuation )
{
float3 result = 0.f;
attenuation = 1.f;
// ?? ??? ?? ?? ? ??? ???? ??? ??
float d = -r * mu - sqrt( r * r * ( mu * mu - 1.f ) + Rt * Rt );
if ( d > 0.f )
{
x += d * viewRay;
t -= d;
mu = ( r * mu + d ) / Rt;
r = Rt;
}
static const float EPS = 0.005f;
// ?? ??? ??? ???? ??? ??
if ( r < Rg + HeightOffset + EPS )
{
float diff = ( Rg + HeightOffset + EPS ) - r;
x -= diff * viewRay;
t -= diff;
mu = dot( x, viewRay ) / r;
r = Rg + HeightOffset + EPS;
}
if ( r <= Rt )
{
float nu = dot( viewRay, g_sunDir.xyz );
float muS = dot( x, g_sunDir.xyz ) / r;
float4 inscatter = max( Sample4D( inscatterTex, inscatterSampler, r, mu, muS, nu ), 0.f );
if ( t > 0.f )
{
float3 x0 = x + t * viewRay;
float altitude0 = length( x0 );
float mu0 = dot( x0, viewRay ) / altitude0;
float muS0 = dot( x0, g_sunDir.xyz ) / altitude0;
// ??? ??? ??? ??? ???? ????? ??
attenuation = AnalyticTransmittance( r, mu, t );
45
Rendering - Inscatter Color
if ( altitude0 > Rg + HeightOffset )
{
// ??? ??? ??? ??? ??
inscatter = max( inscatter - attenuation.rgbr * Sample4D( inscatterTex, inscatterSampler, altitude0,
mu0, muS0, nu ), 0.f );
// ???? ??? ? ???? ??? ??? ???? ??? ???? ? ??? ?? ??? ??
float muHoriz = -sqrt( 1.f - ( Rg / r ) * ( Rg / r ) );
if ( abs( mu - muHoriz ) < EPS )
{
float a = ( ( mu - muHoriz ) + EPS ) / ( 2.f * EPS );
mu = muHoriz - EPS;
altitude0 = sqrt( r * r + t * t + 2.f * r * t * mu );
mu0 = ( r * mu + t ) / altitude0;
float4 inscatter0 = Sample4D( inscatterTex, inscatterSampler, r, mu, muS, nu );
float4 inscatter1 = Sample4D( inscatterTex, inscatterSampler, altitude0, mu0, muS0, nu );
float4 inscatterA = max( inscatter0 - attenuation.rgbr * inscatter1, 0.f );
mu = muHoriz + EPS;
altitude0 = sqrt( r * r + t * t + 2.f * r * t * mu );
mu0 = ( r * mu + t ) / altitude0;
inscatter0 = Sample4D( inscatterTex, inscatterSampler, r, mu, muS, nu );
inscatter1 = Sample4D( inscatterTex, inscatterSampler, altitude0, mu0, muS0, nu );
float4 inscatterB = max( inscatter0 - attenuation.rgbr * inscatter1, 0.f );
inscatter = lerp( inscatterA, inscatterB, a );
}
}
}
inscatter.w *= smoothstep( 0.f, 0.02f, muS );
float phaseR = PhaseFunctionR( nu );
float phaseM = PhaseFunctionM( nu );
// Mie ??? ??
result = max( inscatter.rgb * phaseR + getMie( inscatter ) * phaseM, 0.f );
}
return result * ISun;
} 46
Rendering - Inscatter Color
Transmittance Table? ????? Inscatter Table? ?? ???? ??? ??
???? ?? ? ?? ?? ???? ???? ?? ?? ?? ???? ?? ????
??? ???.
?? ???? ??? ?? ???? ?? ???? ??? ??? ??? ?? ???
??.
? ??? a ~ c ?? ?? ???? S a ¡ú c = ????
?
??[?0]? ?? ?? a ~ b? b ~ c ??
? ?? ????? ???? ??? ?? ??? ? ??.
a
b
c
?
?
?
?? ?0 = ?
?
?
??[?0] + ?
?
?
??[?0]
47
Rendering - Inscatter Color
?? a ~ b ??? ??? ????
? ?? ?????? ??? ?? ??? ? ??.
????? ??? ??.
32? ppt?? ???? Mie ??? ??? getMie ???? ????.
getMie ??? ? ? ? ??
? ?,?
??,?
? ?,?
?
? ?,?
?
? ?
?
? ?
? ? ??? ?? ??? ???? ?????.
?
?
?
??[?0] = ?
?
?
?? ?0 ? ?
?
?
??[?0]
S a ¡ú ? = S a ¡ú c ? ?(? ¡ú ?)S b ¡ú c ¡ß ? = ? ? ¡ú ? = ?(? ¡ú ?)?(? ¡ú ?)
inscatter = max( inscatter - attenuation.rgbr * Sample4D( inscatterTex, inscatterSampler, altitude0, mu0, muS0, nu ), 0.f );
float4 inscatterA = max( inscatter0 - attenuation.rgbr * inscatter1, 0.f );
float4 inscatterB = max( inscatter0 - attenuation.rgbr * inscatter1, 0.f );
? ? ? ??
? ?,?
??,?
? ?,?
?
? ?
? (¡ß ? ?,?
?
= ? ?,?
?
= ? ?,?
?
)
return rayMie.rgb * rayMie.w / max( rayMie.r, 1e-4 ) * ( betaR.r / betaR ); 48
Rendering ¨C Ground Color
float3 GroundColor( float3 x, float t, float3 viewRay, float r, float mu, float3 attenuation )
{
float3 result = 0.f;
if ( t > 0.f )
{
float3 x0 = x + t * viewRay;
float altitude0 = length( x0 );
float3 n = x0 / altitude0;
float muS = dot( n, g_sunDir.xyz );
// ???? ???? ??? ???? 0??.
float3 sunLight = TransmittanceWithShadow( altitude0, muS );
float3 groundSkyLight = Irradiance( altitude0, muS );
float3 sceneColor = float3( 0.35f, 0.35f, 0.35f );
float3 reflectance = sceneColor * float3( 0.2f, 0.2f, 0.2f );
if ( altitude0 > Rg + HeightOffset )
{
reflectance = float3( 0.4f, 0.4f, 0.4f );
}
// ??? ??? ??
float3 groundColor = reflectance * ISun / M_PI * ( max( muS, 0.f ) ) * ( sunLight + groundSkyLight );
result = attenuation * groundColor;
}
return result;
}
?? ?? ??? ??? ????. ?????? ???? ?? ?? ?? ?? ????.
49
Rendering ¨C Sun Color
float3 SunColor( float3 x, float t, float3 viewRay, float r, float mu )
{
if ( t > 0.f )
{
return 0.f;
}
else
{
float3 transmittance = r <= Rt ? TransmittanceWithShadow( r, mu ) : 1.f;
float isun = step( cos( M_PI / 180 ), dot( viewRay, g_sunDir.xyz ) ) * ISun;
return transmittance * isun;
}
}
??? ?? ?? ??? ??? ?? ??? ??? ?? 1? ?? ?? ? ??? ??
??( Radiant Intensity )? ???? ???? ????.
50
+ + =
Inscatter color Ground color Sun color Final result
Reference
? ??? ??? : https://www.flaticon.com/authors/simpleicon
? https://www.alanzucconi.com/2017/10/10/atmospheric-scattering-1/
? https://ebruneton.github.io/precomputed_atmospheric_scattering/
51
Appendix
?? ???? ??? ?? ??? ???
? = ?? , ? = ??
? =
?? ? ??
??
, ? ? =
?? ? ??
?
, ? =
?? ? ??
?
?? = ?? = ?2 + 2??? + ?2
? ?,? =
?? ? ??
??
=
?? + ?? ? ??
??
=
?? ? + ??
??
52
?
?d
?
?
?
?
? ?
?
? ?,?
?
float muSi = ( nu * t + muS * r ) / ri; // 38? ppt

More Related Content

Precomputed atmospheric scattering(?? ?? ?? ??)

  • 2. Eric Bruneton, Fabrice Neyret? 2008 ??. [Bruneton08] ??? ?? ???? ??? ???( ???, ?? ??, ?? )? ??? ??? ?? ?? ( Precomputed ) ?? ?? ???? ????? ??? ??? ?? ????. UE4? Atmospheric Fog? ? ??? ??? ?????. ( ???? Atmospheric~ ?? ???? ??? ) ??? OpenGL? ??? ?? ??? ????? ??? ???? ? ??? ??. UE4 ??? ?? ??? ?? ????. ( Precomputed ??? ?? ? ?? ?? ?? ) ??? ??? ?? ???? ?. ?? ??? ?? ?? ??? ????. ? ppt? ?? ??? ???? ?? ?? ??? ?? ??? ??? ??? ???? ??? ???? ???. Precomputed Atmospheric Scattering 2
  • 3. ??? ?? ??? ?????. ?? ??? ???? ?? ??? ?????? ???? ?? ????. Q. ?? ???? ???? ? ? ???? A. ? ? ??. Q. ?? ???? ???? ? ? ?? ???? ?? ??( Scattering ) ???? ?? ?????? ?? ???? ? ?? ?? ??? ??? ? ??. 3
  • 4. A. ???? ?? ???? ??? ??? ????. https://youtu.be/qybisPmc2xw?t=67 ??? ?? ?? ???? ???? ???? ???? ??? ??( Scattering ) ?? ??. ?? ?? ??? ? ? ?? ?? ?? ????. ?? ???? ??? ?? ???? ????? ?? ??? ?? ???? ??. ?? ??( Scattering ) 4
  • 5. ??? ??? ???? ?? ?????. ??? ??? ??? ?? ??? ???? ??. ??? ?? ??? ??? ?? ???? ????? ???? ??? ??? ? ?? ??? ?? ??? ??? ????. ??( Atmosphere ) ?? ?? ?? (?2) 78.084% ?? (?2) 20.946% ??? (??) 0.9340% ????? (??2) 0.04% ?? (??) 0.001818% ?? (??) 0.000524% ?? (??4) 0.000179% ??? (?2 ?) 0.001% ~ 5% ?? 5
  • 6. ??? ??? ??? ??? ??? ?? 2?? ???? ??? ? ??. ???? ??? ??? ????? ???? ?? ????. ( Molecules ) ??? ??? ??(?? ??, ??)? ???? ?? ???? ?? ??? ?? ??? ? ? ?? ??? ??? ??( Rayleigh Scattering )?? ??. ??? ??? ?? ??? ??? ?? ??? ?? ??? 4 ??? ????? ???? ?? ?? ????. ?, ??? ? ?? ??? ? ???? ??? ???. ?? ??? ????? ??? ??? ??? ????? ????? ? ?? ??? ?? ?? ??? ? ???? ??. ?? ??( Atmospheric Scattering ) 6
  • 7. ??? ??? ??? ??? ??? ??? ?? ??? ?? ? ?? ???? ??? ???? ????. ???? ??? ?? ??? ??? ?? ???? ??? ??? ???? ???? ?? ???? ??? ???? ?? ??? ?? ???? ??? ???? ??? ?? ?? ??? ???? ????. ?? ??( Atmospheric Scattering ) 7
  • 8. ???? ??? ??? ????? ??? ??? ????. ( Aerosol ) ???? ??, ?? ??? ?? ??? ??? ?? ??? ???? ? ? ?? ??? ? ??( Mie Scattering ) ?? ??. ? ??? ?? ?? ????? ??? ??, ??, ??? ??? ???. ??? ??? ? ??? ?? ??? ? ??? ??? ?? ??? ?? ??? ??? ?? ???. ( ?? ? ??? ???? ?? ?? ??? ?? ??? ?? ) ????? ?? ??? ??? ??? ???? ???? ??? ???? ?? ??? ?? ???. ??? ??? ?????? ??? ?? ? ? ?? ?? ???. ?? ??( Atmospheric Scattering ) 8
  • 9. ??? ??? ?? ?? ???. ?? ??? ??? ?? ? ??. ?? ??? ??? ??? ?? ???. Out-Scattering In-Scattering ??? ? Absorption 9
  • 10. ???? ?? ?? ? ? ?? ?? ???. ??? ??? ??? ???? ?? ??? ??. ( Out-Scattering, Absorption ) ???? ?? ??? ???? ??? ???? ??? ?? ?? ???? ????. Transmittance ( ??? ) A B ?? : A ???? ?? ? ? ? : B ???? ?? ? Transmittance ¡ú ?(??) = ? ? ? ? 10
  • 11. T x, x0 = ?? ???? ?0 ¦Ò ?¡Ê{?,?} ?? ? ? ?? ?? ? = extinction coefficient (?? ??) : ?? 1m? ???? ?? ??? ?? ????? ??? ???? ?? (= ?? ) ?, ?? ??? ??? ????? ????1 ????2 ??? ???? ???? ??? ?? ?, ?0 = ?? ?? ?? ? = Rayleigh (???) ? = Mie (?) y = ?? 2. Absorption(??) 1. Scattering(??) ?? ? = ?? ? + ?? ? Transmittance ( ??? ) 11
  • 12. ?? ??( ?? ? )? ?? ???( scattering equation )?? ????. ??? ?? ??? ?(?, ?, ?)? ??? ??. ? : ??. ? : ?? ??. ? : ??. ? = 1.00029 : ??? ???. ? = 2.504 ? 1025 : ?? ??? ?? ?? ??. ( = ?3 ? ??? ? ) ? ? : ?? ?.( density ratio ) ?????? 1?? ??? ??? ?? ????? ?? ????. ¡ù ??? ???? ??? ?? ???? Display of The Earth Taking into Account Atmospheric Scattering ???? ??? ? ??. ?????? ??? ? ? ?? ???. ? ?, ?, ? = ?2 ?2?1 2 2 ? ? ? 1 ?4 (1 + cos2 ?) Scattering Equation ( ?? ??? ) 12
  • 13. ??? ?? ??? ?(?, ?, ?)? ?? ??(?)?? ??? ?? ?? ????? ????. ??? ???? ?? ???? ??? ???? ?? ??? ??? ??? ??. ? ?, ? = ? ? ? ?, ?, ? ?? = ? 0 2? ? 0 ? ? ?, ?, ? ???????? = ? 0 2? ? 0 ? ?2 ?2 ? 1 2 2 ? ? ? 1 ?4 (1 + cos2 ?)???????? = ?2 ?2 ? 1 2 2 ? ? ? 1 ?4 ? 0 2? ? 0 ? (1 + cos2 ?)???????? = ?2 ?2 ? 1 2 2 ? ? ? 1 ?4 ? 0 2? 8 3 ?? = ?2 ?2 ? 1 2 2 ? ? ? 1 ?4 16? 3 = 8?3 ?2 ? 1 2 3 ? ? ? 1 ?4 = 8?3 ?2 ? 1 2 3??4 ? ? Scattering Equation ( ?? ??? ) 13
  • 14. ??? ??? ? ?, ? ? ??? ?? ??( Rayleigh Scattering Coefficient )? ?? ? ? ? ? ????. ??? ??? ??? ?? ????? ? ?? ???? ??? ? ? ? = ? ? ? ? ??. ? ??? ?? ?? ?? ? ? ? ? ? ? ? ?, ? = ? ? ? (0, ?)? ? ? ??? ??? ???? ?? ?? ?? ? ? ? ? ?? ??(? ? ? )? ?? ??(? ? ? )? ??? ?? ? ??. ???? ? ?? ? ?? ?? ?? ??? ??? ?? ?(? ? )? ????? ??? ??? ???. ? ?? ?? ?? ?????? ??? ? ??. ? ? ? = ? ? ? + ? ? ? ? ? ? (?) = 8?3 ?2 ? 1 2 3??4 ? ? ? ? ? (?) = ? ? ? (0, ?)? ? Scattering Coefficient ( ?? ?? ) 14
  • 15. ??? ??? ?? ??? ????. ?? ?? ? ??? ??? ???? ??? ??? ?? ??? ? ??. ?? ? ? ? ? ?? ???? ??? ?? 0??? ??? ??? ??? ?? ????. ??? ??? ?? ???? ??, ??, ??? ?? ?? ??? ???? ??? 1976??? ???? ? ?? ?? ??? ??? ?? ??? ???? ??? ??. Density ratio ( ?? ? ) ? ? = ??????? ? ???????(0) ??(?) ??(??/?3) 0 1.2250 500 1.1673 1000 1.1117 1500 1.0581 2000 1.0066 2500 0.95695 3000 0.90912 3500 0.86323 4000 0.81913 4500 0.77677 ?? : https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770009539.pdf 15
  • 16. ? ?? ?? ?? ?? ???? ??? 0 ? ?? 1, ??? 4000? ?? 0.66868? ? ?. ?? ??? ??? ?? ?? ?? ?? ???? ?? ?? ???? ?? ??? ??? ? ???? ??. ??? ?? ??? ???? ???? ??? ?? ????? ???? ?? ?? ? ? ??. Density ratio ( ?? ? ) 0 0.2 0.4 0.6 0.8 1 1.2 1.4 0 5000 10000 15000 20000 25000 30000 35000 16
  • 17. ??? ???? ?? ??? ??? ??. ?? ?? ???? ??? ??. ? : ?? ??( scale height ) ?? ??? ?? ?? ????( e = 2.71828 ) ? ??? ????? ???? ??? ???, ? ??? ?? ?? ?? ????. Density ratio ( ?? ? ) ? ? = e? ? ? ?? ?? ?? ??(??) Rayleigh 8.5 Mie 1.2 0 0.2 0.4 0.6 0.8 1 1.2 0 5000 10000 15000 20000 25000 30000 35000 ??? ????? ?? ? ?? ?? ? ?? ?? ? 17
  • 18. ?? ???? ???? ?? ?? ???? ???? ???? ?? ?? ?? ?? ? ? ??? ?? ??? ? ? ??. ???? ?? ??? ?? ???? ???? ?? ?? ?? ( x ~ x0 ) ? ????? ??? ?? ???? ???? ?? ? ? ?? ????. ??? ??? ?? ??? ?0, ? ?? ?? ? ?? ??? ?1?? ?? ??. ? ? ???? ?? ??? ? ?? ??? ????? Transmittance ( ??? ) T x, x0 = ?? ???? ?0 ¦Ò ?¡Ê{?,?} ?? ? ? ?? ?1 = ?0(1 ? ? ?) ?1 = ?0(1 ? ? ? 2 ) ?2 = ?1 1 ? ? ? 2 = ?0 1 ? ? ? 2 2 18
  • 19. ??? ???? ??? ????? ? ?? ?? ??? ?? 1m ? ????? ??? ????? ??? ??( ? )? ?? ???? ??? ?? ????. ??? ?? ??? ?? ??? ???? ??? ? ? ??? ? ? ?? ??? ??( Optical depth ) ? ??. Transmittance ( ??? ) ? = ?0 lim ?¡ú¡Þ 1 ? ? ? ? ? ? ?0 = ? = ??? ? ? = ?0 ??? ? ¡ß lim ?¡ú¡Þ 1 + 1 ? ? = e ? = ??? ? ? ? = ??? ???????? ? ? ? ? 19
  • 20. ? = ???¦È (¦È : ??? ?????? ???( zenith angle )) ? ¡Ã ?? r ? Transmittance Table 20
  • 21. Compute Shader? ???? Transmittance Table? ?????. cs_5_0? ??? ??( Maximum Threads = 1024 ) ??? ???? ??? Dispatch ???. ??? ?? ?? T x, x0 = ?? ???? ?0 ¦Ò ?¡Ê{?,?} ?? ? ? ?? ? ??? ???? ?? ? ? ??. GetTransmittanceRMu ??? ??? UV? ?? ??(R)? ??? ???(Mu)? ?? ?. Transmittance Table [numthreads(TRANSMITTANCE_W / TRANSMITTANCE_GROUP_X, TRANSMITTANCE_H / TRANSMITTANCE_GROUP_Y, 1)] void main( uint3 DTid : SV_DispatchThreadID ) { float r, muS; GetTransmittanceRMu( DTid, r, muS ); float3 depth = betaR * OpticalDepth( HR, r, muS ) + betaMEx * OpticalDepth( HM, r, muS ); transmittanceBuffer[DTid.xy] = float4( exp( -depth ), 0.f ); } void GetTransmittanceRMu( uint3 DTid, out float r, out float muS ) { r = DTid.y / float( TRANSMITTANCE_H ); muS = DTid.x / float( TRANSMITTANCE_W ); #ifdef TRANSMITTANCE_NON_LINEAR r = Rg + ( r * r ) * ( Rt - Rg ); muS = -0.15f + tan( 1.5f * muS ) / tan( 1.5f ) * ( 1.f + 0.15f ); #else r = Rg + r * ( Rt - Rg ); muS = -0.15f + muS * ( 1.f + 0.15f ); // 0 ~ ( pi/2 + epsilon ) #endif } 21
  • 22. OpticalDepth? ??? ??? ????. ?? limit ??? ??? ??? ???? ??? ??? ??? ???? ??? ????? ???. Transmittance Table float OpticalDepth( float H, float r, float mu ) { float result = 0.f; float dx = limit( r, mu ) / float( TRANSMITTANCE_INTEGRAL_SAMPLES ); float xi = 0.f; float yi = exp( -( r - Rg ) / H ); for ( int i = 1; i <= TRANSMITTANCE_INTEGRAL_SAMPLES; ++i ) { float xj = float( i ) * dx; float yj = exp( -( sqrt( r * r + xj * xj + 2.f * xj * r * mu ) - Rg ) / H ); // law of cosines result += ( yi + yj ) * 0.5f * dx; xi = xj; yi = yj; } return mu < -sqrt( 1.f - ( Rg / r ) * ( Rg / r ) ) ? 1e9f : result; } t ??? ???? ?? ?? ???? ???? ?? 22
  • 23. ?? ??? ???? ??? ???? ??? ? ??. Transmittance Table float limit( float r, float mu ) { float dout = -r * mu + sqrt( r * r * ( mu * mu - 1.f ) + RL * RL ); float delta2 = r * r * ( mu * mu - 1.f ) + Rg * Rg; if ( delta2 >= 0.f ) { float din = -r * mu - sqrt( delta2 ); if ( din > 0.f ) { dout = min( dout, din ); } } return dout; } float dout = -r * mu + sqrt( r * r * ( mu * mu - 1.f ) + RL * RL ); 23
  • 24. ????? ?? ???? ????? ? ? ? ? ? ??? ?? ???? ?? ???? ?? ?? ??? ?? ??? ??? ????. ??? ??? ??? ?? ??? ??? ? 2 ??? ??(?2 = ?2 + ?2 ? 2??????)? ?? ??? ??. Transmittance Table a r * r + xj * xj + 2.f * xj * r * mu 24
  • 25. ?? ?? ?? ?? ??( Irradiance )? ???? ??? ????. ?? ??? ?? ??( ?? )? ??? ?? ?? ?( ? ¡Ã ??????? ???? ) ? ??? ??? ??? ? = ? ?? ? ??? ? ??. ? ???? ??? ?? ???? ???? ?? ??( ? : radiance )?? ??? ??? ??? ?? ??? ?? ???? ?? ???? ??? ?, ? ???? ??? ?? ?? ????, ?? ?? ? ? ???? ?? ?? ???. ?? ??? L = ¦µ ???????? ? ??? ? ?? ?? ??? ?? ??? ??? ? ??. Irradiance E = ? ¦¸ ??????? ?? ?? 25
  • 26. ?? ?? ?? ?? ??? ??? ? ???? ???? ??? ?? ???? ???? ??? ?? ???? ??? ? ??. ????? ? ???? ??? E = ?(?, ?0) ???? ? ???? ????. Single Irradiance Table E = ?(?, ?0)? ??? ???? [numthreads( IRRADIANCE_W / IRRADIANCE_GROUP_X, IRRADIANCE_H / IRRADIANCE_GROUP_Y, 1)] void main( uint3 DTid : SV_DispatchThreadID ) { float r, muS; GetIrradianceRMuS( DTid, r, muS ); irradiance1Buffer[DTid.xy] = float4( Transmittance( r, muS ) * max( muS, 0.f ), 0.f ); } ? = ???¦È (¦È : ??? ????? ???( zenith angle )) ? ¡Ã ?? 26
  • 27. ?? ??? ?? ??? ????? ??. ???? ???, ?? ?? ???? ?? ?? ?? 3D ???? ????. ??? 3D ???? 4?? ??? LUT( Look Up Table )? ???? ?? ??? ??? ??. Single Inscatter Table ? ¡Ã ?? ? = ???¦È (¦È : ??? ?????? ???( zenith angle )) ? ? = ???¦È ??? (¦È ??? : ??? ???( zenith angle )) ? = ???? (? : ??? ??? ?? ?) Rayleigh Inscatter Table? ?? ??? ?? 27
  • 28. ?? ???? ?? ?? ? ?, ? ? ??? ??? ?? ??? ? ??. ? ? ? ?? ??? ?(?, ?, ?)? ?? ?? ? ?, ? ? ??? ??? ?? ? ??. ??? ?? ???? ?? ??? ?? ? ? ? ???? ??? ???? ??? ?? ???? ?? ? ? ??. ? ? ? ?? ?? ?? ?? ??? ???? ?? ??( Phase Function )? ???. Phase Function ?(?, ?, ?) = ? ?, ? ?(?) ? ? = ? ?, ?, ? ? ?, ? ? ? = ?2 ?2 ? 1 2 2 ? ? ? 1 ?4 1 + cos2 ? 3??4 8?3 ?2 ? 1 2 ? ? = 3 16? 1 + cos2 ? ? ?, ?, ? 1 ? ?,? 28
  • 29. ???, ? ?? ???? ?? ???? ??? ? ? ??. ?? ???? Inscatter ???? ????. Single Inscatter Table [numthreads( RES_MU_S, RES_MU / INSCATTER1_GROUP_Y, 1)] void main( uint3 DTid : SV_DispatchThreadID ) { float r; float4 dhdH; GetRdhdH( DTid.z, r, dhdH ); float mu, muS, nu; GetMuMuSNu( DTid, r, dhdH, mu, muS, nu ); float3 ray, mie; Inscatter( r, mu, muS, nu, ray, mie ); deltaSRBuffer[DTid] = float4( ray, 0.f ); deltaSMBuffer[DTid] = float4( mie, 0.f ); } void Inscatter( float r, float mu, float muS, float nu, out float3 ray, out float3 mie ) { ray = 0.f; mie = 0.f; float dx = limit( r, mu ) / float( INSCATTER_INTEGRAL_SAMPLES ); float3 rayi; float3 miei; Integrand( r, mu, muS, nu, 0.f, rayi, miei ); for ( int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i ) { float xj = float( i ) * dx; float3 rayj; float3 miej; Integrand( r, mu, muS, nu, xj, rayj, miej ); ray += ( rayi + rayj ) * 0.5f * dx; mie += ( miei + miej ) * 0.5f * dx; rayi = rayj; miei = miej; } ray *= betaR; mie *= betaMSca; } ?? ??? ????? ???? ????. ¡ù ?? ??? ???? ??? ????? ???? ????. 29
  • 30. ??? ?? ?? ??? ??? ??? ?? ??? ?? ???? ??? ???? ??. Single Inscatter Table void Integrand( float r, float mu, float muS, float nu, float t, out float3 ray, out float3 mie ) { ray = 0.f; mie = 0.f; float ri = sqrt( r * r + t * t + 2.f * r * mu * t ); float muSi = ( nu * t + muS * r ) / ri; ri = max( Rg, ri ); // ???? ??? ??? ???? ??? ??? ??? ??? ??? ?? // = ??? ??? ???? ?? ???? ?? 0 if ( muSi >= -sqrt( 1.f - Rg * Rg / ( ri * ri ) ) ) { float3 ti = Transmittance( r, mu, t ) * Transmittance( ri, muSi ); ray = exp( -( ri - Rg ) / HR ) * ti; mie = exp( -( ri - Rg ) / HM ) * ti; } } t 30
  • 31. ???? ???? ??? ?? ??, ??? ?????. ??? ???? ??? ??? ? ???? ??? ????? ??????? ??. ?? ?? ????? ???? ?? ????. ? ?[? ???] : ???? ??? ??? ?? ( ?? ?? ?? X ) ? ?? : ?? ?? ( ???, ? ?? ?? ?? ?? ¡ð ) ?? : ??? ?? ?? ? ?,? : ? ??? red ?? ? ( ?? ?? ?? X ) Multiple Inscatter Table R G B A ?? = ? ? ? ??? + ? ?? ?? ? ?,? [numthreads( RES_MU_S, RES_MU / INSCATTER1_GROUP_Y, 1)] void main( uint3 DTid : SV_DispatchThreadID ) { float3 uvw = ( DTid.xyz + 0.5f ) / float3( RES_MU_S * RES_NU, RES_MU, RES_R ); float4 ray = deltaSRTex.SampleLevel( deltaSRSampler, uvw, 0 ); float4 mie = deltaSMTex.SampleLevel( deltaSMSampler, uvw, 0 ); float pitch = RES_MU_S * RES_NU; float slicePitch = pitch * RES_MU; inscatterBuffer[( DTid.z * slicePitch ) + ( DTid.y * pitch ) + DTid.x] = float4( ray.rgb, mie.r ); } ? ? ? ??? ? ? ?,?? ?? ???? ??? ???. ? ?? ? ? ? ? ?? ???? ??? ???. 31
  • 32. ??? ???? ??? LUT? ?? ???? ?? ??? ?? ???? ??? ? ?? ??? ? ??? ??? ??? ??? ?? ????. ??? ??? ?? ? ??? red ?? ?? ???? ???? ?? ??? ?? ??? ?? ????. ?? ??? ? ??? ??? ????? ?? ?? ?? y?? ?? ?? v? ???? ?? ?? ????. Multiple Inscatter Table ? ? ? ?? ? ?,? ??,? ? ?,? ? ? ?,? ? ? ? ? ? ? ? [numthreads( RES_MU_S * RES_NU / INSCATTERS_GROUP_X, RES_MU / INSCATTERS_GROUP_Y, 1 )] void main( uint3 DTid : SV_DispatchThreadID ) { float r; float4 dhdH; GetRdhdH( g_threadGroupZ, r, dhdH ); float mu, muS, nu; GetMuMuSNu( float3( DTid.xy, g_threadGroupZ ), r, dhdH, mu, muS, nu ); float3 raymie; Inscatter( r, mu, muS, nu, raymie ); deltaJBuffer[DTid] = float4( raymie, 0.f ); } y 32
  • 33. ?? ?? y? ???? ?? ?? ???? ??? Inscatter ??? ? ??? ?? ?? ? ???? ??. ??? ?? ??? ?? ???? ??? ????. ?? ???? ?? ???? ???. ?? ?? ?? ??? ???? ???? ? ??? ???? ????. Multiple Inscatter Table void Inscatter( float r, float mu, float muS, float nu, out float3 raymie ) { r = clamp( r, Rg, Rt ); mu = clamp( mu, -1.f, 1.f ); muS = clamp( muS, -1.f, 1.f ); // Using formula sum and differences of cosine float var = sqrt( 1.f - mu * mu ) * sqrt( 1.f - muS * muS ); nu = clamp( nu, mu * muS - var, mu * muS + var ); // cos( theta to the horizon ) float cthetamin = -sqrt( 1.f - ( Rg * Rg ) / ( r * r ) ); float3 v = float3( sqrt( 1.0 - mu * mu ), 0.f, mu ); float sx = v.x == 0.f ? 0.f : ( nu - muS * mu ) / v.x; float3 s = float3( sx, sqrt( max( 0.f, 1.f - sx * sx - muS * muS ) ), muS ); raymie = 0.f; cthetamin 33
  • 34. ???? ?? ????? ?? ?? ?? ???? ? ??? ?? ??? ???? ??? ?? ???? ???? ??? ??? ?? ??? ?(greflectance)? ??? (gtransp)? ??? ??. Multiple Inscatter Table // Compute equation(7) // ?(0 ~ ?)? ?? ?? for ( int itheta = 0; itheta < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++itheta ) { float theta = ( float( itheta ) + 0.5f ) * dtheta; float ctheta = cos( theta ); float greflectance = 0.f; float dground = 0.f; float3 gtransp = 0.f; // if ground visible in direction w compute transparency gtransp between x and ground if ( ctheta < cthetamin ) { greflectance = AVERAGE_GROUND_REFLECTANCE / M_PI; dground = -r * ctheta - sqrt( r * r * ( ctheta * ctheta - 1.f ) + Rg * Rg ); gtransp = Transmittance( Rg, -(r * ctheta + dground) / Rg , dground ); } 34
  • 35. Multiple Inscatter Table // ?(0 ~ 2?)? ?? ?? for ( int iphi = 0; iphi < 2 * INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++iphi ) { float phi = ( float( iphi ) + 0.5f ) * dphi; float dw = dtheta * dphi * sin( theta ); float3 w = float3( cos( phi ) * sin( theta ), sin( phi ) * sin( theta ), ctheta ); float nu1 = dot( s, w ); float nu2 = dot( v, w ); float pr2 = PhaseFunctionR( nu2 ); float pm2 = PhaseFunctionM( nu2 ); float3 gnormal = ( float3( 0.f, 0.f, r ) + dground * w ) / Rg; float3 girradiance = Irradiance( Rg, dot( gnormal, s ) ); // first term = light reflected from the ground and attenuated before reaching x float3 raymie1 = greflectance * girradiance * gtransp; ???? ??? ?? ?? ??? ???? ????. ?? ???? ? ?? ??? ?? ?? ??? ? ? ??. ??? ???? ??? ?? ??. ? ? = ? ? + ? ¦¸ ? ??, ? ? ?? ? ? ? ?? ? ? = ? ¦¸ ? ??, ? ? ?? ? ? ? ?? = ? ??, ? ? ? ¦¸ ?? ? ? ? ?? ? ? = ? ??, ? ? ? ???? ???? ? ??. Lambertian BRDF ??? ?? ??? ? ? ??. 35
  • 36. ????? ?? ? ? ??? ??? ( 1. ??? ?? ???? ?? ?? y? ???? 2. ?? ?? y?? ?? ?? v? ???? ) ?? ???? 2? ????. ?? ??? ???? ??? ?? ??? ????. ??? ? ??? ??? ?? ?? ????. g_order? ???? ?? ?? ??? ?? ??? ???? ???? ?? ??? ?? ?? ??? ?? ??? ??? ?? ????. Multiple Inscatter Table // second term = inscattered light = deltaS // ???? ??? ?? ??? ??? ??? 1??? ??? ??? ?? ??? ?? ??? ?? 2? ??. if ( g_order == 2 ) { // ?? ?? ?? ???? ?? ??? ???? ????. ??? ? ?? ??? ???? ????? ??? ???? ?????. float pr1 = PhaseFunctionR( nu1 ); float pm1 = PhaseFunctionM( nu1 ); float3 ray1 = Sample4D( deltaSRTex, deltaSRSampler, r, w.z, muS, nu1 ).rgb; float3 mie1 = Sample4D( deltaSMTex, deltaSMSampler, r, w.z, muS, nu1 ).rgb; raymie1 += ray1 * pr1 + mie1 * pm1; } else { // ?? ??? ?? ?? ??? ?? ??? ?? ????. raymie1 += Sample4D( deltaSRTex, deltaSRSampler, r, w.z, muS, nu1 ).rgb; } // light coming from direction w and scattered in direction v // Equation 7 raymie += raymie1 * ( betaR * exp( -( r - Rg ) / HR ) * pr2 + betaMSca * exp( -( r - Rg ) / HM ) * pm2 ) * dw; } } } 1 2 36
  • 37. ?? ?? ??? ?? ??? ??? ? ???? ??? ?? ??? ?? ?? ??? ?? ??? ???? ???. ?? ?? ??? ??? ?? ???? ????? ??? ???? ??. Multiple Inscatter Table y [numthreads( RES_MU_S, RES_MU / INSCATTERN_GROUP_Y, 1 )] void main( uint3 DTid : SV_DispatchThreadID ) { float r; float4 dhdH; GetRdhdH( DTid.z, r, dhdH ); float mu, muS, nu; GetMuMuSNu( DTid, r, dhdH, mu, muS, nu ); deltaSRBuffer[DTid] = float4( Inscatter( r, mu, muS, nu ), 0.f ); } 37
  • 38. ??? ???? ???? ?? ???? ???? ?? ???? ???? ????. Multiple Inscatter Table float3 Integrand( float r, float mu, float muS, float nu, float t ) { float ri = sqrt( r * r + t * t + 2.f * r * t * mu ); float mui = ( r * mu + t ) / ri; float muSi = ( nu * t + muS * r ) / ri; return Sample4D( deltaJTex, deltaJSampler, ri, mui, muSi, nu ).rgb * Transmittance( r, mu, t ); } float3 Inscatter( float r, float mu, float muS, float nu ) { float3 raymie = 0.f; float dx = limit( r, mu ) / float( INSCATTER_INTEGRAL_SAMPLES ); float xi = 0.f; float3 raymiei = Integrand( r, mu, muS, nu, 0.f ); for ( int i = 0; i < INSCATTER_INTEGRAL_SAMPLES; ++i ) { float xj = float( i ) * dx; float3 raymiej = Integrand( r, mu, muS, nu, xj ); raymie += ( raymiei + raymiej ) * 0.5f * dx; xi = xj; raymiei = raymiej; } return raymie; } 38
  • 39. ?? ?? ????? 31? ?????? ???? ? ?? ??? ?? ??? ?? ?? ????. ???? ???? 2? ??? ???? ? ?? ??? ??? ?? ??. ? ? ???? ??? ?? ??? ? ??? ?? ?? ????. Multiple Inscatter Table [numthreads( RES_MU_S, RES_MU / INSCATTERN_GROUP_Y, 1 )] void main( uint3 DTid : SV_DispatchThreadID ) { float r; float4 dhdH; GetRdhdH( DTid.z, r, dhdH ); float mu, muS, nu; GetMuMuSNu( DTid, r, dhdH, mu, muS, nu ); float3 uvw = ( DTid.xyz + 0.5f ) / float3( RES_MU_S * RES_NU, RES_MU, RES_R ); float pitch = RES_MU_S * RES_NU; float slicePitch = pitch * RES_MU; inscatterBuffer[( DTid.z * slicePitch ) + ( DTid.y * pitch ) + DTid.x] += float4( deltaSRTex.SampleLevel( deltaSRSampler, uvw, 0 ).rgb / PhaseFunctionR( nu ), 0.f ); } 39
  • 40. Multiple Inscatter Table // 4?? ?? ??? ????? for ( int order = 2; order <= 4; ++order ) { int* gpuScatteringOrder = static_cast<int*>( renderer.LockBuffer( precomputeBuf ) ); gpuScatteringOrder[0] = order; renderer.UnLockBuffer( precomputeBuf ); renderer.BindConstantBuffer( SHADER_TYPE::CS, 0, 1, &precomputeBuf ); // Compute deltaJ renderer.BindShader( SHADER_TYPE::CS, csInscatterS ); renderer.BindShaderResource( SHADER_TYPE::CS, 1, 1, &deltaESrv ); renderer.BindRandomAccessResource( 0, 1, &deltaJRav ); // ??? ??? ?? ????? ???? Device Lost? ??. ??? ??? Dispatch. for ( int i = 0; i < INSCATTERS_GROUP_Z; ++i ) { gpuScatteringOrder = static_cast<int*>( renderer.LockBuffer( precomputeBuf ) ); gpuScatteringOrder[0] = order; gpuScatteringOrder[1] = i; renderer.UnLockBuffer( precomputeBuf ); renderer.BindConstantBuffer( SHADER_TYPE::CS, 0, 1, &precomputeBuf ); renderer.Dispatch( INSCATTERS_GROUP_X, INSCATTERS_GROUP_Y ); renderer.WaitGPU( ); } ¡­ // Compute deltaS renderer.BindShader( SHADER_TYPE::CS, csInscatterN ); renderer.BindShaderResource( SHADER_TYPE::CS, 4, 1, &deltaJSrv ); renderer.BindShaderResource( SHADER_TYPE::CS, 2, 1, nullptr ); renderer.BindRandomAccessResource( 0, 1, &deltaSRRav ); renderer.Dispatch( INSCATTERN_GROUP_X, INSCATTERN_GROUP_Y, INSCATTERN_GROUP_Z ); ¡­ } 40
  • 41. ?? Inscatter Table Multiple Inscatter Table ? ¡Ã ?? ? = ???¦È (¦È : ??? ?????? ???( zenith angle )) ? ? = ???¦È ??? (¦È ??? : ??? ???( zenith angle )) ? = ???? (? : ??? ??? ?? ?) 41
  • 42. ????? ?? ??? ?? ?? ??? ???? ??. Multiple Irrdiance Table [numthreads( IRRADIANCE_W / IRRADIANCE_GROUP_X, IRRADIANCE_H / IRRADIANCE_GROUP_Y, 1 )] void main( uint3 DTid : SV_DispatchThreadID ) { float r, muS; GetIrradianceRMuS( DTid, r, muS ); float3 s = float3( max( sqrt( 1.0 - muS * muS ), 0.f ), 0.f, muS ); float3 result = 0.f; // ????? ??? ?? for ( int iphi = 0; iphi < 2 * IRRADIANCE_INTEGRAL_SAMPLES; ++iphi ) { float phi = ( float( iphi ) + 0.5f ) * dphi; for ( int itheta = 0; itheta < IRRADIANCE_INTEGRAL_SAMPLES / 2; ++itheta ) { float theta = ( float( itheta ) + 0.5f ) * dtheta; float dw = sin( theta ) * dtheta * dphi; float3 w = float3( cos( phi ) * sin( theta ), sin( phi ) * sin( theta ), cos( theta ) ); float nu = dot( s, w ); // ?? ?? ??? ????? ?????? ?? ??? ????? ???? ??? ??. if ( g_order == 2 ) { float pr = PhaseFunctionR( nu ); float pm = PhaseFunctionM( nu ); float3 ray = Sample4D( deltaSRTex, deltaSRSampler, r, w.z, muS, nu ).rgb; float3 mie = Sample4D( deltaSMTex, deltaSMSampler, r, w.z, muS, nu ).rgb; result += ( ray * pr + mie * pm ) * w.z * dw; } else { result += Sample4D( deltaSRTex, deltaSRSampler, r, w.z, muS, nu ).rgb * w.z * dw; } } } irradianceBuffer[DTid.xy] = float4( result, 0.f ); } 42
  • 43. ?? Irradiance Table Multiple Irradiance Table ? = ???¦È (¦È : ??? ????? ???( zenith angle )) ? ¡Ã ?? 43
  • 44. ?? ???? ??? ?? ?, ?? ?, ??? ?? ?? ??? ?? ??? ????. Rendering VS_OUTPUT main( uint vertexID : SV_VertexID ) { VS_OUTPUT output = (VS_OUTPUT)0; float2 uv = float2( ( vertexID & 1 ) << 1, vertexID & 2 ); float4 pos = float4( float2( -1.f, 1.f ) + uv * float2( 2.f, -2.f ), 0.f, 1.f ); output.position = pos; float4x4 invVewProjection = mul( g_invProjectionMatrix, g_invViewMatrix ); float4 worldPos = mul( float4( pos.xy, 1.f, 1.f ), invVewProjection ); output.worldPos = worldPos.xyz / worldPos.w; return output; } float4 main( PS_INPUT input ) : SV_Target { float3 viewRay = normalize( input.wolrdPos - g_cameraPos.xyz ); float scale = 0.00001f; // ?? ??? ??? ?? ??? ? float3 viewPos = g_cameraPos.xyz * scale; viewPos.y += Rg + HeightOffset; float r = length( viewPos ); float mu = dot( viewPos, viewRay ) / r; float t = -r * mu - sqrt( r * r * ( mu * mu - 1.f ) + Rg * Rg ); float3 attenuation; float3 inscatterColor = InscatterColor( viewPos, t, viewRay, r, mu, attenuation ); float3 groundColor = GroundColor( viewPos, t, viewRay, r, mu, attenuation ); float3 sunColor = SunColor( viewPos, t, viewRay, r, mu ); return float4( HDR( sunColor + inscatterColor + groundColor ), 1.f ); } 44
  • 45. Rendering - Inscatter Color float3 InscatterColor( float3 x, float t, float3 viewRay, float r, float mu, out float3 attenuation ) { float3 result = 0.f; attenuation = 1.f; // ?? ??? ?? ?? ? ??? ???? ??? ?? float d = -r * mu - sqrt( r * r * ( mu * mu - 1.f ) + Rt * Rt ); if ( d > 0.f ) { x += d * viewRay; t -= d; mu = ( r * mu + d ) / Rt; r = Rt; } static const float EPS = 0.005f; // ?? ??? ??? ???? ??? ?? if ( r < Rg + HeightOffset + EPS ) { float diff = ( Rg + HeightOffset + EPS ) - r; x -= diff * viewRay; t -= diff; mu = dot( x, viewRay ) / r; r = Rg + HeightOffset + EPS; } if ( r <= Rt ) { float nu = dot( viewRay, g_sunDir.xyz ); float muS = dot( x, g_sunDir.xyz ) / r; float4 inscatter = max( Sample4D( inscatterTex, inscatterSampler, r, mu, muS, nu ), 0.f ); if ( t > 0.f ) { float3 x0 = x + t * viewRay; float altitude0 = length( x0 ); float mu0 = dot( x0, viewRay ) / altitude0; float muS0 = dot( x0, g_sunDir.xyz ) / altitude0; // ??? ??? ??? ??? ???? ????? ?? attenuation = AnalyticTransmittance( r, mu, t ); 45
  • 46. Rendering - Inscatter Color if ( altitude0 > Rg + HeightOffset ) { // ??? ??? ??? ??? ?? inscatter = max( inscatter - attenuation.rgbr * Sample4D( inscatterTex, inscatterSampler, altitude0, mu0, muS0, nu ), 0.f ); // ???? ??? ? ???? ??? ??? ???? ??? ???? ? ??? ?? ??? ?? float muHoriz = -sqrt( 1.f - ( Rg / r ) * ( Rg / r ) ); if ( abs( mu - muHoriz ) < EPS ) { float a = ( ( mu - muHoriz ) + EPS ) / ( 2.f * EPS ); mu = muHoriz - EPS; altitude0 = sqrt( r * r + t * t + 2.f * r * t * mu ); mu0 = ( r * mu + t ) / altitude0; float4 inscatter0 = Sample4D( inscatterTex, inscatterSampler, r, mu, muS, nu ); float4 inscatter1 = Sample4D( inscatterTex, inscatterSampler, altitude0, mu0, muS0, nu ); float4 inscatterA = max( inscatter0 - attenuation.rgbr * inscatter1, 0.f ); mu = muHoriz + EPS; altitude0 = sqrt( r * r + t * t + 2.f * r * t * mu ); mu0 = ( r * mu + t ) / altitude0; inscatter0 = Sample4D( inscatterTex, inscatterSampler, r, mu, muS, nu ); inscatter1 = Sample4D( inscatterTex, inscatterSampler, altitude0, mu0, muS0, nu ); float4 inscatterB = max( inscatter0 - attenuation.rgbr * inscatter1, 0.f ); inscatter = lerp( inscatterA, inscatterB, a ); } } } inscatter.w *= smoothstep( 0.f, 0.02f, muS ); float phaseR = PhaseFunctionR( nu ); float phaseM = PhaseFunctionM( nu ); // Mie ??? ?? result = max( inscatter.rgb * phaseR + getMie( inscatter ) * phaseM, 0.f ); } return result * ISun; } 46
  • 47. Rendering - Inscatter Color Transmittance Table? ????? Inscatter Table? ?? ???? ??? ?? ???? ?? ? ?? ?? ???? ???? ?? ?? ?? ???? ?? ???? ??? ???. ?? ???? ??? ?? ???? ?? ???? ??? ??? ??? ?? ??? ??. ? ??? a ~ c ?? ?? ???? S a ¡ú c = ???? ? ??[?0]? ?? ?? a ~ b? b ~ c ?? ? ?? ????? ???? ??? ?? ??? ? ??. a b c ? ? ? ?? ?0 = ? ? ? ??[?0] + ? ? ? ??[?0] 47
  • 48. Rendering - Inscatter Color ?? a ~ b ??? ??? ???? ? ?? ?????? ??? ?? ??? ? ??. ????? ??? ??. 32? ppt?? ???? Mie ??? ??? getMie ???? ????. getMie ??? ? ? ? ?? ? ?,? ??,? ? ?,? ? ? ?,? ? ? ? ? ? ? ? ? ??? ?? ??? ???? ?????. ? ? ? ??[?0] = ? ? ? ?? ?0 ? ? ? ? ??[?0] S a ¡ú ? = S a ¡ú c ? ?(? ¡ú ?)S b ¡ú c ¡ß ? = ? ? ¡ú ? = ?(? ¡ú ?)?(? ¡ú ?) inscatter = max( inscatter - attenuation.rgbr * Sample4D( inscatterTex, inscatterSampler, altitude0, mu0, muS0, nu ), 0.f ); float4 inscatterA = max( inscatter0 - attenuation.rgbr * inscatter1, 0.f ); float4 inscatterB = max( inscatter0 - attenuation.rgbr * inscatter1, 0.f ); ? ? ? ?? ? ?,? ??,? ? ?,? ? ? ? ? (¡ß ? ?,? ? = ? ?,? ? = ? ?,? ? ) return rayMie.rgb * rayMie.w / max( rayMie.r, 1e-4 ) * ( betaR.r / betaR ); 48
  • 49. Rendering ¨C Ground Color float3 GroundColor( float3 x, float t, float3 viewRay, float r, float mu, float3 attenuation ) { float3 result = 0.f; if ( t > 0.f ) { float3 x0 = x + t * viewRay; float altitude0 = length( x0 ); float3 n = x0 / altitude0; float muS = dot( n, g_sunDir.xyz ); // ???? ???? ??? ???? 0??. float3 sunLight = TransmittanceWithShadow( altitude0, muS ); float3 groundSkyLight = Irradiance( altitude0, muS ); float3 sceneColor = float3( 0.35f, 0.35f, 0.35f ); float3 reflectance = sceneColor * float3( 0.2f, 0.2f, 0.2f ); if ( altitude0 > Rg + HeightOffset ) { reflectance = float3( 0.4f, 0.4f, 0.4f ); } // ??? ??? ?? float3 groundColor = reflectance * ISun / M_PI * ( max( muS, 0.f ) ) * ( sunLight + groundSkyLight ); result = attenuation * groundColor; } return result; } ?? ?? ??? ??? ????. ?????? ???? ?? ?? ?? ?? ????. 49
  • 50. Rendering ¨C Sun Color float3 SunColor( float3 x, float t, float3 viewRay, float r, float mu ) { if ( t > 0.f ) { return 0.f; } else { float3 transmittance = r <= Rt ? TransmittanceWithShadow( r, mu ) : 1.f; float isun = step( cos( M_PI / 180 ), dot( viewRay, g_sunDir.xyz ) ) * ISun; return transmittance * isun; } } ??? ?? ?? ??? ??? ?? ??? ??? ?? 1? ?? ?? ? ??? ?? ??( Radiant Intensity )? ???? ???? ????. 50 + + = Inscatter color Ground color Sun color Final result
  • 51. Reference ? ??? ??? : https://www.flaticon.com/authors/simpleicon ? https://www.alanzucconi.com/2017/10/10/atmospheric-scattering-1/ ? https://ebruneton.github.io/precomputed_atmospheric_scattering/ 51
  • 52. Appendix ?? ???? ??? ?? ??? ??? ? = ?? , ? = ?? ? = ?? ? ?? ?? , ? ? = ?? ? ?? ? , ? = ?? ? ?? ? ?? = ?? = ?2 + 2??? + ?2 ? ?,? = ?? ? ?? ?? = ?? + ?? ? ?? ?? = ?? ? + ?? ?? 52 ? ?d ? ? ? ? ? ? ? ? ?,? ? float muSi = ( nu * t + muS * r ) / ri; // 38? ppt