chunk 1: core gameplay scripts scenes runtime assets

This commit is contained in:
2026-04-06 11:02:34 +03:00
parent fa0388bc79
commit 0d11a097d8
703 changed files with 2292651 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
TEXTURE2D_X_FLOAT(_HalfResCameraDepthTexture);
float4 _HalfResCameraDepthTexture_TexelSize;
// Samples the half resolution camera depth texture and returns the depth considering UNITY_REVERSED_Z.
float SampleDownsampledSceneDepthConsiderReversedZ(float2 uv)
{
float depth = SAMPLE_TEXTURE2D_X(_HalfResCameraDepthTexture, sampler_PointClamp, UnityStereoTransformScreenSpaceTex(uv)).r;
#if !UNITY_REVERSED_Z
depth = lerp(UNITY_NEAR_CLIP_VALUE, 1.0, depth);
#endif
return depth;
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8b8ef91968a1bb147a1e3f10a9e896ef
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,58 @@
#include "./DeclareDownsampledDepthTexture.hlsl"
#define KERNEL_RADIUS 4
#define BLUR_DEPTH_FALLOFF 0.5
static const float KernelWeights[] = { 0.2026, 0.1790, 0.1240, 0.0672, 0.0285 };
// Blurs the RGB channels of the given texture using depth aware gaussian blur, which uses the half resolution camera depth to apply weights to the blur.
// The alpha channel is not blurred so the original value is returned.
float4 DepthAwareGaussianBlur(float2 uv, float2 dir, TEXTURE2D_X(textureToBlur), SAMPLER(sampler_TextureToBlur), float2 textureToBlurTexelSizeXy)
{
float4 centerSample = SAMPLE_TEXTURE2D_X(textureToBlur, sampler_TextureToBlur, uv);
float centerRawDepth = SampleDownsampledSceneDepthConsiderReversedZ(uv);
float centerLinearEyeDepth = LinearEyeDepth(centerRawDepth, _ZBufferParams);
float3 rgbResult = centerSample.rgb * KernelWeights[0];
float weights = KernelWeights[0];
float2 texelSizeTimesDir = textureToBlurTexelSizeXy * dir;
UNITY_UNROLL
for (int i = -KERNEL_RADIUS; i < 0; ++i)
{
float2 uvOffset = (float)i * texelSizeTimesDir;
float2 uvSample = uv + uvOffset;
float rawDepth = SampleDownsampledSceneDepthConsiderReversedZ(uvSample);
float linearEyeDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
float depthDiff = abs(centerLinearEyeDepth - linearEyeDepth);
float r2 = BLUR_DEPTH_FALLOFF * depthDiff;
float g = exp(-r2 * r2);
float weight = g * KernelWeights[-i];
float3 rgb = SAMPLE_TEXTURE2D_X(textureToBlur, sampler_TextureToBlur, uvSample).rgb;
rgbResult += (rgb * weight);
weights += weight;
}
UNITY_UNROLL
for (i = 1; i <= KERNEL_RADIUS; ++i)
{
float2 uvOffset = (float)i * texelSizeTimesDir;
float2 uvSample = uv + uvOffset;
float rawDepth = SampleDownsampledSceneDepthConsiderReversedZ(uvSample);
float linearEyeDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
float depthDiff = abs(centerLinearEyeDepth - linearEyeDepth);
float r2 = BLUR_DEPTH_FALLOFF * depthDiff;
float g = exp(-r2 * r2);
float weight = g * KernelWeights[i];
float3 rgb = SAMPLE_TEXTURE2D_X(textureToBlur, sampler_TextureToBlur, uvSample).rgb;
rgbResult += (rgb * weight);
weights += weight;
}
return float4(rgbResult / weights, centerSample.a);
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6e38164e69d451d46b41c46d4f3187f4
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,49 @@
Shader "Hidden/DownsampleDepth"
{
SubShader
{
Tags
{
"RenderPipeline" = "UniversalPipeline"
}
Pass
{
Name "DownsampleDepth"
ZTest Always
ZWrite Off
Cull Off
Blend Off
ColorMask R
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
#pragma target 4.5
#pragma editor_sync_compilation
#pragma vertex Vert
#pragma fragment Frag
float Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float4 depths = GATHER_RED_TEXTURE2D_X(_CameraDepthTexture, sampler_CameraDepthTexture, input.texcoord);
float minDepth = Min3(depths.x, depths.y, min(depths.z, depths.w));
float maxDepth = Max3(depths.x, depths.y, max(depths.z, depths.w));
return (uint(input.positionCS.x + input.positionCS.y) & 1) > 0 ? minDepth : maxDepth;
}
ENDHLSL
}
}
Fallback Off
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: cffeaeec0396a2c4dad475266cc8dfeb
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,360 @@
Shader "Hidden/VolumetricFog"
{
SubShader
{
Tags
{
"RenderPipeline" = "UniversalPipeline"
}
Pass
{
Name "VolumetricFog"
ZTest Always
ZWrite Off
Cull Off
Blend Off
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Random.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/VolumeRendering.hlsl"
#include "./DeclareDownsampledDepthTexture.hlsl"
#pragma multi_compile _ _FORWARD_PLUS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile_fragment _ _LIGHT_COOKIES
#pragma multi_compile_fragment _ _MAIN_LIGHT_CONTRIBUTION_DISABLED
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS_CONTRIBUTION_DISABLED
#pragma vertex Vert
#pragma fragment Frag
int _FrameCount;
uint _CustomAdditionalLightsCount;
float _Distance;
float _BaseHeight;
float _MaximumHeight;
float _GroundHeight;
float _Density;
float _Absortion;
float _MainLightAnisotropy;
float _MainLightScattering;
float3 _MainLightColorTint;
float _AdditionalLightsAnisotropy;
float _AdditionalLightsScattering;
float _AdditionalLightsRadiusSq;
int _MaxSteps;
// Gets the fog density at the given world height.
float GetFogDensity(float posWSy)
{
float t = saturate((posWSy - _BaseHeight) / (_MaximumHeight - _BaseHeight));
t = 1.0 - t;
t = lerp(t, 0.0, posWSy < _GroundHeight);
return _Density * t;
}
// Gets the main light color at one raymarch step.
float3 GetStepMainLightColor(float3 currPosWS, float phaseMainLight, float density)
{
#if _MAIN_LIGHT_CONTRIBUTION_DISABLED
return float3(0.0, 0.0, 0.0);
#endif
// get the main light with shadow attenuation already set
Light mainLight = GetMainLight(TransformWorldToShadowCoord(currPosWS));
#if _LIGHT_COOKIES
// when light cookies are enabled and one is set for the main light, also factor it
mainLight.color *= SampleMainLightCookie(currPosWS);
#endif
// return the final color
return (mainLight.color * _MainLightColorTint) * (mainLight.shadowAttenuation * phaseMainLight * density * _MainLightScattering);
}
// Gets the accumulated color from additional lights at one raymarch step.
float3 GetStepAdditionalLightsColor(float2 texcoord, float3 currPosWS, float3 rd, float density)
{
#if _ADDITIONAL_LIGHTS_CONTRIBUTION_DISABLED
return float3(0.0, 0.0, 0.0);
#endif
#if _FORWARD_PLUS
// Forward+ rendering path needs this data before the light loop
InputData inputData = (InputData)0;
inputData.normalizedScreenSpaceUV = texcoord;
inputData.positionWS = currPosWS;
#endif
// initialize the accumulated color from additional lights
float3 additionalLightsColor = float3(0.0, 0.0, 0.0);
// loop differently throught lights in Forward+ while considering Forward and Deferred too
LIGHT_LOOP_BEGIN(_CustomAdditionalLightsCount)
Light additionalLight = GetAdditionalPerObjectLight(lightIndex, currPosWS);
additionalLight.shadowAttenuation = AdditionalLightRealtimeShadow(lightIndex, currPosWS, additionalLight.direction);
#if _LIGHT_COOKIES
// when light cookies are enabled and a cookie is set for this additional light also factor it
additionalLight.color *= SampleAdditionalLightCookie(lightIndex, currPosWS);
#endif
// calculate the phase function for this additional light
float phaseAdditionalLight = CornetteShanksPhaseFunction(_AdditionalLightsAnisotropy, dot(rd, additionalLight.direction));
// See unity.render-pipelines.universal\ShaderLibrary\RealtimeLights.hlsl - GetAdditionalPerObjectLight
#if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA
float4 additionalLightPos = _AdditionalLightsBuffer[lightIndex].position;
#else
float4 additionalLightPos = _AdditionalLightsPosition[lightIndex];
#endif
// Note: This is useful for both spotlights and pointlights. For the latter it is specially true when the point light is inside some geometry and casts shadows.
// Gradually reduce additional lights scattering to zero at their origin to try to avoid flicker-aliasing.
float3 distToPos = additionalLightPos.xyz - currPosWS;
float distToPosMagnitudeSq = dot(distToPos, distToPos);
float newScattering = smoothstep(0.0, _AdditionalLightsRadiusSq, distToPosMagnitudeSq) * _AdditionalLightsScattering;
// Note: If directional lights are also considered as additional lights when more than 1 is used, ignore the previous code when it is a directional light.
// They store direction in additionalLightPos.xyz and have .w set to 0, while point and spotlights have it set to 1.
newScattering = lerp(1.0, newScattering, additionalLightPos.w);
// accumulate the total color for additional lights
additionalLightsColor += (additionalLight.color * (additionalLight.shadowAttenuation * additionalLight.distanceAttenuation * phaseAdditionalLight * density * newScattering));
LIGHT_LOOP_END
return additionalLightsColor;
}
float4 Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
// prepare the ray origin and direction
float depth = SampleDownsampledSceneDepthConsiderReversedZ(input.texcoord);
float3 posWS = ComputeWorldSpacePosition(input.texcoord, depth, UNITY_MATRIX_I_VP);
float3 ro = GetCameraPositionWS();
float3 offset = posWS - ro;
float offsetLength = length(offset);
float3 rd = offset / offsetLength;
// calculate the step length and jitter
float stepLength = _Distance / (float)_MaxSteps;
float jitter = stepLength * InterleavedGradientNoise(input.positionCS.xy, _FrameCount);
// calculate the phase function for the main light and part of the extinction factor
float phaseMainLight = CornetteShanksPhaseFunction(_MainLightAnisotropy, dot(rd, GetMainLight().direction));
float minusStepLengthTimesAbsortion = -stepLength * _Absortion;
// initialize the volumetric fog color and transmittance
float3 volumetricFogColor = float3(0.0, 0.0, 0.0);
float transmittance = 1.0;
UNITY_LOOP
for (int i = 0; i < _MaxSteps; ++i)
{
// calculate the distance we are at
float dist = jitter + i * stepLength;
// perform depth test to break out early
UNITY_BRANCH
if (dist >= offsetLength)
break;
// calculate the current world position
float3 currPosWS = ro + rd * dist;
// calculate density
float density = GetFogDensity(currPosWS.y);
// keep marching when there is not enough density
UNITY_BRANCH
if (density <= 0.0)
continue;
// calculate attenuation
float stepAttenuation = exp(minusStepLengthTimesAbsortion * density);
// attenuate transmittance
transmittance *= stepAttenuation;
// calculate the colors at this step and accumulate them
float3 mainLightColor = GetStepMainLightColor(currPosWS, phaseMainLight, density);
float3 additionalLightsColor = GetStepAdditionalLightsColor(input.texcoord, currPosWS, rd, density);
// TODO: add ambient?
float3 stepColor = mainLightColor + additionalLightsColor;
volumetricFogColor += (stepColor * (transmittance * stepLength));
}
return float4(volumetricFogColor, transmittance);
}
ENDHLSL
}
Pass
{
Name "VolumetricFogHorizontalBlur"
ZTest Always
ZWrite Off
Cull Off
Blend Off
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
#include "./DepthAwareGaussianBlur.hlsl"
#pragma vertex Vert
#pragma fragment Frag
#if UNITY_VERSION < 202320
float4 _BlitTexture_TexelSize;
#endif
float4 Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
return DepthAwareGaussianBlur(input.texcoord, float2(1.0, 0.0), _BlitTexture, sampler_LinearClamp, _BlitTexture_TexelSize.xy);
}
ENDHLSL
}
Pass
{
Name "VolumetricFogVerticalBlur"
ZTest Always
ZWrite Off
Cull Off
Blend Off
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
#include "./DepthAwareGaussianBlur.hlsl"
#pragma vertex Vert
#pragma fragment Frag
#if UNITY_VERSION < 202320
float4 _BlitTexture_TexelSize;
#endif
float4 Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
return DepthAwareGaussianBlur(input.texcoord, float2(0.0, 1.0), _BlitTexture, sampler_LinearClamp, _BlitTexture_TexelSize.xy);
}
ENDHLSL
}
Pass
{
Name "VolumetricFogComposition"
ZTest Always
ZWrite Off
Cull Off
Blend Off
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
#include "./DeclareDownsampledDepthTexture.hlsl"
#pragma vertex Vert
#pragma fragment Frag
TEXTURE2D_X(_VolumetricFogTexture);
SAMPLER(sampler_BlitTexture);
float4 Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
// get the full resolution depth and convert it to linear eye depth
float fullResDepth = LoadSceneDepth(input.positionCS.xy);
float linearFullResDepth = LinearEyeDepth(fullResDepth, _ZBufferParams);
// get the texel size from the downsampled depth texture
float2 texelSize = _HalfResCameraDepthTexture_TexelSize.xy;
// calculate the UVs to sample the downsampled depths
float2 topLeftUv = input.texcoord - (texelSize * 0.5);
float2 uvs[4] =
{
topLeftUv + float2(0.0, texelSize.y),
topLeftUv + texelSize.xy,
topLeftUv + float2(texelSize.x, 0.0),
topLeftUv,
};
// initialize variables to validate the depths
int numValidDepths = 0;
float relativeDepthThreshold = linearFullResDepth * 0.1;
// initialize the minimum depth distance towards the full resolution depth
float minDepthDist = 1e12;
float2 nearestUv;
UNITY_UNROLL
for (int i = 0; i < 4; ++i)
{
// sample the lower resolution depth and convert to linear eye depth
float2 uv = uvs[i];
float depth = SampleDownsampledSceneDepthConsiderReversedZ(uv);
float linearEyeDepth = LinearEyeDepth(depth, _ZBufferParams);
// check the depth distance
float depthDist = abs(linearFullResDepth - linearEyeDepth);
// update the minimum when necessary
UNITY_FLATTEN
if (depthDist < minDepthDist)
{
minDepthDist = depthDist;
nearestUv = uvs[i];
}
// count the number of valid depths according to the threshold, as we will act differently if all of them are valid or not
numValidDepths += (depthDist < relativeDepthThreshold);
}
float4 volumetricFog;
// use bilinear sampling if depths are similar, and point sampling otherwise
UNITY_BRANCH
if (numValidDepths == 4)
volumetricFog = SAMPLE_TEXTURE2D_X(_VolumetricFogTexture, sampler_LinearClamp, input.texcoord);
else
volumetricFog = SAMPLE_TEXTURE2D_X(_VolumetricFogTexture, sampler_PointClamp, nearestUv);
float4 cameraColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_BlitTexture, input.texcoord);
// attenuate the camera color with the fog and add the fog on top
return float4(cameraColor.rgb * volumetricFog.a + volumetricFog.rgb, cameraColor.a);
}
ENDHLSL
}
}
Fallback Off
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 08f816187f9af0244a95556ee0cab83f
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant: