You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
3.4 KiB
137 lines
3.4 KiB
#ifndef UNITY_PATH_TRACING_SKY_SAMPLING_INCLUDED
|
|
#define UNITY_PATH_TRACING_SKY_SAMPLING_INCLUDED
|
|
|
|
#ifdef COMPUTE_PATH_TRACING_SKY_SAMPLING_DATA
|
|
#define PTSKY_TEXTURE2D(name) RW_TEXTURE2D(float, name)
|
|
#else
|
|
#define PTSKY_TEXTURE2D(name) TEXTURE2D(name)
|
|
#endif
|
|
|
|
TEXTURE2D_X(_SkyCameraTexture);
|
|
PTSKY_TEXTURE2D(_PathTracingSkyCDFTexture);
|
|
PTSKY_TEXTURE2D(_PathTracingSkyMarginalTexture);
|
|
|
|
uint _PathTracingSkyTextureWidth;
|
|
uint _PathTracingSkyTextureHeight;
|
|
|
|
// Equiareal mapping
|
|
float2 MapSkyDirectionToUV(float3 dir)
|
|
{
|
|
float cosTheta = dir.y;
|
|
float phi = atan2(-dir.z, -dir.x);
|
|
|
|
return float2(0.5 - phi * INV_TWO_PI, (cosTheta + 1.0) * 0.5);
|
|
}
|
|
|
|
// Equiareal mapping
|
|
float3 MapUVToSkyDirection(float u, float v)
|
|
{
|
|
float phi = TWO_PI * (1.0 - u);
|
|
float cosTheta = 2.0 * v - 1.0;
|
|
|
|
return TransformGLtoDX(SphericalToCartesian(phi, cosTheta));
|
|
}
|
|
|
|
// // Standard latlon mapping (for reference)
|
|
// float2 MapSkyDirectionToUV(float3 dir)
|
|
// {
|
|
// float theta = acos(-dir.y);
|
|
// float phi = atan2(-dir.z, -dir.x);
|
|
|
|
// return float2(0.5 - phi * INV_TWO_PI, theta * INV_PI);
|
|
// }
|
|
|
|
// // Standard latlon mapping (for reference)
|
|
// float3 MapUVToSkyDirection(float u, float v)
|
|
// {
|
|
// float phi = TWO_PI * (1.0 - u);
|
|
// float cosTheta = cos((1.0 - v) * PI);
|
|
|
|
// return TransformGLtoDX(SphericalToCartesian(phi, cosTheta));
|
|
// }
|
|
|
|
float3 MapUVToSkyDirection(float2 uv)
|
|
{
|
|
return MapUVToSkyDirection(uv.x, uv.y);
|
|
}
|
|
|
|
#ifndef COMPUTE_PATH_TRACING_SKY_SAMPLING_DATA
|
|
|
|
bool IsSkyEnabled()
|
|
{
|
|
return _EnvLightSkyEnabled;
|
|
}
|
|
|
|
bool IsSkySamplingEnabled()
|
|
{
|
|
return _PathTracingSkyTextureWidth;
|
|
}
|
|
|
|
float GetSkyCDF(PTSKY_TEXTURE2D(cdf), uint i, uint j)
|
|
{
|
|
return cdf[uint2(i, j)].x;
|
|
}
|
|
|
|
// Dichotomic search
|
|
float SampleSkyCDF(PTSKY_TEXTURE2D(cdf), uint size, uint j, float smp)
|
|
{
|
|
uint i = 0;
|
|
for (uint halfsize = size >> 1, offset = halfsize; offset > 0; offset >>= 1)
|
|
{
|
|
if (smp < GetSkyCDF(cdf, halfsize, j))
|
|
{
|
|
// i is already in the right half (lower one)
|
|
halfsize -= offset >> 1;
|
|
}
|
|
else
|
|
{
|
|
// i has to move to the other half (upper one)
|
|
i += offset;
|
|
halfsize += offset >> 1;
|
|
}
|
|
}
|
|
|
|
// MarginalTexture[0] stores the PDF normalization factor, so we need a test on i == 0
|
|
float cdfInf = i > 0 ? GetSkyCDF(cdf, i, j) : 0.0;
|
|
float cdfSup = i < size ? GetSkyCDF(cdf, i + 1, j) : 1.0;
|
|
|
|
return (i + (smp - cdfInf) / (cdfSup - cdfInf)) / size;
|
|
}
|
|
|
|
float GetSkyPDFNormalizationFactor()
|
|
{
|
|
return _PathTracingSkyMarginalTexture[uint2(0, 0)].x;
|
|
}
|
|
|
|
// This PDF approximation is valid only if PDF/CDF tables are computed with equiareal mapping
|
|
float GetSkyPDFFromValue(float3 value)
|
|
{
|
|
return Luminance(value) * GetSkyPDFNormalizationFactor();
|
|
}
|
|
|
|
float4 GetSkyBackground(uint2 pixelCoord)
|
|
{
|
|
return _SkyCameraTexture[COORD_TEXTURE2D_X(pixelCoord)];
|
|
}
|
|
|
|
float3 GetSkyValue(float3 dir)
|
|
{
|
|
return SampleSkyTexture(dir, 0.0, 0).rgb;
|
|
}
|
|
|
|
float2 SampleSky(float smpU, float smpV)
|
|
{
|
|
float v = SampleSkyCDF(_PathTracingSkyMarginalTexture, _PathTracingSkyTextureHeight, 0, smpV);
|
|
float u = SampleSkyCDF(_PathTracingSkyCDFTexture, _PathTracingSkyTextureWidth, v * _PathTracingSkyTextureHeight, smpU);
|
|
|
|
return float2(u, v);
|
|
}
|
|
|
|
float2 SampleSky(float2 smp)
|
|
{
|
|
return SampleSky(smp.x, smp.y);
|
|
}
|
|
|
|
#endif // COMPUTE_PATH_TRACING_SKY_SAMPLING_DATA
|
|
|
|
#endif // UNITY_PATH_TRACING_SKY_SAMPLING_INCLUDED
|