Files
Temp.BattleRoyale.Map.Unity/Assets/LUMINATE/Shaders/HLSL/GapperGamesVolumetricFogInclude.hlsl
CortexCore a379dc5cd3 1
2024-05-13 01:28:33 +08:00

265 lines
7.9 KiB
HLSL

#ifndef VolumetricFog
#define VolumetricFog
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_SCREEN
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
float random3D(float3 uv)
{
float Coord = (uv.x + uv.y + uv.z);
float2 _uv = float2(Coord, Coord);
float2 noise = (frac(sin(dot(_uv, float2(12.9898, 78.233) * 2.0)) * 43758.5453));
return (abs(noise.x + noise.y) - 1);
}
float random(float2 uv)
{
float2 noise = (frac(sin(dot(uv, float2(12.9898, 78.233) * 2.0)) * 43758.5453));
return (abs(noise.x + noise.y) - 1);
}
float2 rayBoxDst(float3 boundsMin, float3 boundsMax, float3 rayOrigin, float3 invRaydir)
{
float3 t0 = (boundsMin - rayOrigin) * invRaydir;
float3 t1 = (boundsMax - rayOrigin) * invRaydir;
float3 tmin = min(t0, t1);
float3 tmax = max(t0, t1);
float dstA = max(max(tmin.x, tmin.y), tmin.z);
float dstB = min(tmax.x, min(tmax.y, tmax.z));
float dstToBox = max(0, dstA);
float dstInsideBox = max(0, dstB - dstToBox);
return float2(dstToBox, dstInsideBox);
}
float3 GetRay(float2 screenPos)
{
float3 viewVector = mul(unity_CameraInvProjection, float4(screenPos * 2 - 1, 0, -1));
float3 viewDir = mul(unity_CameraToWorld, float4(viewVector, 0));
float viewLength = length(viewDir);
float3 ray = viewDir / viewLength;
return ray;
}
float SceneDepth(float2 UV)
{
// return Linear01Depth(SHADERGRAPH_SAMPLE_SCENE_DEPTH(UV), _ZBufferParams);
return LinearEyeDepth(SHADERGRAPH_SAMPLE_SCENE_DEPTH(UV), _ZBufferParams);
//return SHADERGRAPH_SAMPLE_SCENE_DEPTH(UV), _ZBufferParams;
}
float3 saturation(float3 In, float Saturation)
{
float luma = dot(In, float3(0.2126729, 0.7151522, 0.0721750));
return luma.xxx + Saturation.xxx * (In - luma.xxx);
}
float3 GetLighting(float3 rayPos, Texture2D additional, sampler sampler_additional, float additionalLightsCount)
{
float3 color = 0;
UNITY_LOOP
for (int x = 0; x < additionalLightsCount; x++)
{
float width = 512;
float4 lightPosRange = SAMPLE_TEXTURE2D(additional, sampler_additional, float2(x / width, 0.15));
float3 lightPos = lightPosRange.xyz;
float lightRange = lightPosRange.w;
if (distance(lightPos, rayPos) < lightRange)
{
float4 lightVectorAngle = SAMPLE_TEXTURE2D(additional, sampler_additional, float2(x / width, 0.25));
float3 lightVector = normalize(lightVectorAngle.xyz);
float lightAngle = lightVectorAngle.w;
float isInCone = 1;
if (lightAngle > 0)
{
float3 rayVector = normalize(rayPos - lightPos);
float dp = dot(rayVector, lightVector);
if (acos(dp) * 57.2958 > lightAngle / 2)
{
isInCone = 0;
}
}
if (isInCone > 0)
{
float3 lightCol = SAMPLE_TEXTURE2D(additional, sampler_additional, float2(x / width, 0.05)).xyz;
float falloff = distance(lightPos, rayPos) / lightRange;
falloff = pow(1 - clamp(falloff, 0, 1), 3);
falloff += exp(-distance(lightPos, rayPos)) * lightRange;
color += falloff * lightCol * 0.1;
}
}
}
return color;
}
float GetShadows(float3 rayPos)
{
return MainLightRealtimeShadow(TransformWorldToShadowCoord(rayPos));
}
float Phase(float eyeCos, float anisotropy)
{
float numerator = (1 - pow(anisotropy, 2)) * (pow(eyeCos, 2) + 1);
float denominator = pow((pow(anisotropy, 2) + 1) - (anisotropy * eyeCos), 1.5) * (pow(anisotropy, 2) + 2);
float final = (numerator / denominator) * ((8 * PI) / 3);
return final;
}
float EyeCos(float3 viewDirection)
{
//Light Data
float3 dir = 0;
#ifndef SHADERGRAPH_PREVIEW
Light mainLight = GetMainLight(float4(0, 0, 0, 0), 0, 1);
dir = mainLight.direction;
#endif
//Calculations
float dotProduct = dot(viewDirection, dir);
dotProduct = (dotProduct + 1) * 0.5;
return dotProduct;
}
void RenderFog_float(float density, float anisotropy, float3 boxPos, float3 boxBounds, float steps, float stepSize, float depth, float4 screenPos, float lowResDist, float lowResMultiplier, float maxStepSize, float jitter, Texture2D additional, sampler sampler_additional, float additionalLightsCount, out float3 _color, out float3 _lightColor, out float3 _lightDir, out float _phase, out float _density)
{
//Initialize Variables
boxPos.xz += _WorldSpaceCameraPos.xz;
_color = 0;
_lightColor = 0;
_lightDir = 0;
_density = 0;
_phase = 0;
//Light Data
float3 lightDir = 0;
float3 lightCol = 0;
#ifndef SHADERGRAPH_PREVIEW
Light mainLight = GetMainLight(float4(0, 0, 0, 0), float3(0, 0, 0), 1);
lightDir = mainLight.direction;
lightCol = normalize(mainLight.color);
#endif
//Intersection Ray
float3 viewVector = mul(unity_CameraInvProjection, float4(screenPos.xy * 2 - 1, 0, -1));
float3 viewDir = mul(unity_CameraToWorld, float4(viewVector, 0));
float viewLength = length(viewDir);
float3 ray = GetRay(screenPos.xy);
//Volume Intersection
float3 posBL = boxPos - boxBounds / 2;
float3 posTR = boxPos + boxBounds / 2;
float2 boxDist = rayBoxDst(posBL, posTR, _WorldSpaceCameraPos, 1 / ray);
float distToBox = boxDist.x;
float distInBox = boxDist.y;
//Ray Setup
float3 entryPoint = _WorldSpaceCameraPos + ray * distToBox;
//float3 rayPos = entryPoint + ray * viewLength;
float3 rayPos = entryPoint;
//Calculate Depth
//depth = SceneDepth(screenPos.xy / screenPos.w) * viewLength;
//Early Exit Conditions
if (distInBox == 0 || distToBox > depth)
{
return;
}
//Calculate Phase
float phase = Phase(EyeCos(viewDir), anisotropy);
//Initialize Variables
float totalDensity = 0;
float3 totalLight = 0;
float distTravelled = 0;
float tempStepSize = stepSize;
float totalSteps = 0;
UNITY_LOOP
for (int i = 0; i < steps && distTravelled + distToBox < depth && distTravelled < distInBox; i++)
{
float rnd = abs(random(rayPos.xz + rayPos.yz)) * jitter;
rnd += 1;
tempStepSize *= rnd;
#ifdef MAIN_LIGHT_CALCULATE_SHADOWS
float3 lighting = GetLighting(rayPos, additional, sampler_additional, additionalLightsCount);
float shadows = GetShadows(rayPos);
float shadowsMin = dot(lightDir, float3(0, 1, 0));
shadowsMin = max(shadowsMin, 0);
shadowsMin = 1 - shadowsMin;
shadowsMin = pow(shadowsMin, 6);
shadows = shadowsMin + (shadows * (1 - shadowsMin));
shadows = clamp(shadows, 0, 1);
#else
float3 lighting = 1;
float shadows = 1;
#endif
float falloff = distance(_WorldSpaceCameraPos, rayPos);
falloff = exp(-falloff * 5);
totalLight += ((lighting * totalDensity * 0.5) + (shadows * lightCol * phase));
float minDens = length( lighting ) * density * 10;
minDens = clamp(minDens, 0, 1);
totalDensity += max(density, minDens) * tempStepSize * ((shadows * 0.5) + 0.5);
//Early Exit Conditions
if (exp(-totalDensity) == 0)
{
break;
}
//March Along Ray
distTravelled += tempStepSize;
rayPos += ray * tempStepSize;
totalSteps += 1;
if (distTravelled > lowResDist)
{
tempStepSize = clamp(distTravelled / lowResMultiplier, 0, maxStepSize);
}
}
//Normalize Density
float3 normalizedDensity = exp(-totalDensity);
//Normalize Light
float3 normalizedLight = totalLight / totalSteps;
_color = normalizedLight;
_lightColor = lightCol;
_lightDir = lightDir;
_density = (1 - normalizedDensity);
_phase = phase;
return;
}
#endif