100 lines
4.0 KiB
HLSL
100 lines
4.0 KiB
HLSL
|
#ifndef PHYSICALLY_BASED_SKY_RENDERING_HLSL
|
||
|
#define PHYSICALLY_BASED_SKY_RENDERING_HLSL
|
||
|
|
||
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
||
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
|
||
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightDefinition.cs.hlsl"
|
||
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
||
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSkyCommon.hlsl"
|
||
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/SkyUtils.hlsl"
|
||
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/AtmosphericScattering/AtmosphericScattering.hlsl"
|
||
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/CookieSampling.hlsl"
|
||
|
|
||
|
float3 _PBRSkyCameraPosPS;
|
||
|
int _RenderSunDisk;
|
||
|
|
||
|
float ComputeMoonPhase(CelestialBodyData moon, float3 V)
|
||
|
{
|
||
|
float3 M = moon.forward.xyz * moon.distanceFromCamera;
|
||
|
|
||
|
float radialDistance = moon.distanceFromCamera, rcpRadialDistance = rcp(radialDistance);
|
||
|
float2 t = IntersectSphere(moon.radius, dot(moon.forward.xyz, -V), radialDistance, rcpRadialDistance);
|
||
|
|
||
|
float3 N = normalize(M - t.x * V);
|
||
|
|
||
|
return saturate(-dot(N, moon.sunDirection));
|
||
|
}
|
||
|
|
||
|
float ComputeEarthshine(CelestialBodyData moon)
|
||
|
{
|
||
|
// Approximate earthshine: sun light reflected from earth
|
||
|
// cf. A Physically-Based Night Sky Model
|
||
|
|
||
|
// Compute the percentage of earth surface that is illuminated by the sun as seen from the moon
|
||
|
//float earthPhase = PI - acos(dot(sun.forward.xyz, -light.forward.xyz));
|
||
|
//float earthshine = 1.0f - sin(0.5f * earthPhase) * tan(0.5f * earthPhase) * log(rcp(tan(0.25f * earthPhase)));
|
||
|
|
||
|
// Cheaper approximation of the above (https://www.desmos.com/calculator/11ny6d5j1b)
|
||
|
float sinPhase = sqrt(max(1 - dot(moon.sunDirection, moon.forward), 0.0f)) * INV_SQRT2;
|
||
|
float earthshine = 1.0f - sinPhase * sqrt(sinPhase);
|
||
|
|
||
|
return earthshine * moon.earthshine;
|
||
|
}
|
||
|
|
||
|
float3 RenderSunDisk(inout float tFrag, float tExit, float3 V)
|
||
|
{
|
||
|
float3 radiance = 0;
|
||
|
|
||
|
// Intersect and shade emissive celestial bodies.
|
||
|
// Unfortunately, they don't write depth.
|
||
|
for (uint i = 0; i < _CelestialBodyCount; i++)
|
||
|
{
|
||
|
CelestialBodyData light = _CelestialBodyDatas[i];
|
||
|
|
||
|
// Celestial body must be outside the atmosphere (request from Pierre D).
|
||
|
float lightDist = max(light.distanceFromCamera, tExit);
|
||
|
|
||
|
if (asint(light.angularRadius) != 0 && lightDist < tFrag)
|
||
|
{
|
||
|
// We may be able to see the celestial body.
|
||
|
float3 L = -light.forward.xyz;
|
||
|
|
||
|
float LdotV = -dot(L, V);
|
||
|
float radInner = light.angularRadius;
|
||
|
|
||
|
if (LdotV >= light.flareCosInner) // Sun disk.
|
||
|
{
|
||
|
tFrag = lightDist;
|
||
|
float3 color = light.surfaceColor;
|
||
|
|
||
|
if (light.type != 0)
|
||
|
color *= ComputeMoonPhase(light, V) * INV_PI + ComputeEarthshine(light); // Lambertian BRDF
|
||
|
|
||
|
if (light.surfaceTextureScaleOffset.x > 0)
|
||
|
{
|
||
|
float2 proj = float2(dot(V, light.right), dot(V, light.up));
|
||
|
float2 angles = float2(FastASin(proj.x), FastASin(-proj.y));
|
||
|
float2 uv = angles * rcp(radInner) * 0.5 + 0.5;
|
||
|
color *= SampleCookie2D(uv, light.surfaceTextureScaleOffset);
|
||
|
}
|
||
|
|
||
|
radiance = color;
|
||
|
}
|
||
|
else if (LdotV >= light.flareCosOuter) // Flare region.
|
||
|
{
|
||
|
float rad = acos(LdotV);
|
||
|
float r = max(0, rad - radInner);
|
||
|
float w = saturate(1 - r * rcp(light.flareSize));
|
||
|
|
||
|
float3 color = light.flareColor;
|
||
|
color *= SafePositivePow(w, light.flareFalloff);
|
||
|
radiance += color;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return radiance;
|
||
|
}
|
||
|
|
||
|
#endif // PHYSICALLY_BASED_SKY_RENDERING_HLSL
|