Rasagar/Library/PackageCache/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSky.shader

211 lines
6.2 KiB
Plaintext
Raw Normal View History

2024-08-26 13:07:20 -07:00
Shader "Hidden/HDRP/Sky/PbrSky"
{
HLSLINCLUDE
#pragma vertex Vert
// #pragma enable_d3d11_debug_symbols
#pragma editor_sync_compilation
#pragma target 4.5
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch
#pragma multi_compile_fragment _ LOCAL_SKY
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSkyRendering.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Sky/PhysicallyBasedSky/PhysicallyBasedSkyEvaluation.hlsl"
int _HasGroundAlbedoTexture; // bool...
int _HasGroundEmissionTexture; // bool...
int _HasSpaceEmissionTexture; // bool...
float _GroundEmissionMultiplier;
float _SpaceEmissionMultiplier;
// 3x3, but Unity can only set 4x4...
float4x4 _PlanetRotation;
float4x4 _SpaceRotation;
TEXTURECUBE(_GroundAlbedoTexture);
TEXTURECUBE(_GroundEmissionTexture);
TEXTURECUBE(_SpaceEmissionTexture);
struct Attributes
{
uint vertexID : SV_VertexID;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings Vert(Attributes input)
{
Varyings output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID, UNITY_RAW_FAR_CLIP_VALUE);
return output;
}
float4 RenderSky(Varyings input)
{
const float R = _PlanetaryRadius;
const float3 V = GetSkyViewDirWS(input.positionCS.xy);
const bool renderSunDisk = _RenderSunDisk != 0;
float3 N; float r; // These params correspond to the entry point
#ifdef LOCAL_SKY
const float3 O = _PBRSkyCameraPosPS;
float tEntry = IntersectAtmosphere(O, V, N, r).x;
float tExit = IntersectAtmosphere(O, V, N, r).y;
float cosChi = -dot(N, V);
float cosHor = ComputeCosineOfHorizonAngle(r);
#else
N = float3(0, 1, 0);
r = _PlanetaryRadius;
float cosChi = -dot(N, V);
float cosHor = 0.0f;
const float3 O = N * r;
float tEntry = 0.0f;
float tExit = IntersectSphere(_AtmosphericRadius, -dot(N, V), r).y;
#endif
bool rayIntersectsAtmosphere = (tEntry >= 0);
bool lookAboveHorizon = (cosChi >= cosHor);
float tFrag = FLT_INF;
float3 radiance = 0;
if (renderSunDisk)
radiance = RenderSunDisk(tFrag, tExit, V);
if (rayIntersectsAtmosphere && !lookAboveHorizon) // See the ground?
{
float tGround = tEntry + IntersectSphere(R, cosChi, r).x;
if (tGround < tFrag)
{
// Closest so far.
// Make it negative to communicate to EvaluatePbrAtmosphere that we intersected the ground.
tFrag = -tGround;
radiance = 0;
float3 gP = O + tGround * -V;
float3 gN = normalize(gP);
if (_HasGroundEmissionTexture)
{
float4 ts = SAMPLE_TEXTURECUBE(_GroundEmissionTexture, s_trilinear_clamp_sampler, mul(gN, (float3x3)_PlanetRotation));
radiance += _GroundEmissionMultiplier * ts.rgb;
}
float3 albedo = _GroundAlbedo.xyz;
if (_HasGroundAlbedoTexture)
{
albedo *= SAMPLE_TEXTURECUBE(_GroundAlbedoTexture, s_trilinear_clamp_sampler, mul(gN, (float3x3)_PlanetRotation)).rgb;
}
float3 gBrdf = INV_PI * albedo;
// Shade the ground.
for (uint i = 0; i < _CelestialLightCount; i++)
{
CelestialBodyData light = _CelestialBodyDatas[i];
float3 L = -light.forward.xyz;
float3 intensity = light.color.rgb;
#ifdef LOCAL_SKY
intensity *= SampleGroundIrradianceTexture(dot(gN, L));
#else
float3 opticalDepth = ComputeAtmosphericOpticalDepth(r, dot(N, L), true);
intensity *= TransmittanceFromOpticalDepth(opticalDepth) * saturate(dot(N, L));
#endif
radiance += gBrdf * intensity;
}
}
}
else if (tFrag == FLT_INF) // See the stars?
{
if (_HasSpaceEmissionTexture)
{
// V points towards the camera.
float4 ts = SAMPLE_TEXTURECUBE(_SpaceEmissionTexture, s_trilinear_clamp_sampler, mul(-V, (float3x3)_SpaceRotation));
radiance += _SpaceEmissionMultiplier * ts.rgb;
}
}
float3 skyColor = 0, skyOpacity = 0;
#ifdef LOCAL_SKY
if (rayIntersectsAtmosphere)
EvaluatePbrAtmosphere(_PBRSkyCameraPosPS, V, tFrag, renderSunDisk, skyColor, skyOpacity);
#else
if (lookAboveHorizon)
EvaluateDistantAtmosphere(-V, skyColor, skyOpacity);
#endif
skyColor += radiance * (1 - skyOpacity);
skyColor *= _IntensityMultiplier;
return float4(skyColor, 1.0);
}
float4 FragBaking(Varyings input) : SV_Target
{
return RenderSky(input); // The cube map is not pre-exposed
}
float4 FragRender(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float4 value = RenderSky(input);
value.rgb *= GetCurrentExposureMultiplier(); // Only the full-screen pass is pre-exposed
return value;
}
ENDHLSL
SubShader
{
Tags{ "RenderPipeline" = "HDRenderPipeline" }
Pass
{
Name "PBRSky Cubemap"
ZWrite Off
ZTest Always
Blend Off
Cull Off
HLSLPROGRAM
#pragma fragment FragBaking
ENDHLSL
}
Pass
{
Name "PBRSky"
ZWrite Off
ZTest LEqual
Blend Off
Cull Off
HLSLPROGRAM
#pragma fragment FragRender
ENDHLSL
}
}
Fallback Off
}