fix:代码提初始化
This commit is contained in:
@@ -0,0 +1,395 @@
|
||||
Shader "Hidden/Volumetrics"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex ("Texture", any) = "white" {}
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
// No culling or depth
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
//#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
//#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
|
||||
float4x4 _LeftWorldFromView;
|
||||
float4x4 _RightWorldFromView;
|
||||
float4x4 _LeftViewFromScreen;
|
||||
float4x4 _RightViewFromScreen;
|
||||
|
||||
sampler2D _DitherTexture;
|
||||
|
||||
UNITY_DECLARE_SHADOWMAP(_CascadeShadowMapTexture);
|
||||
UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
|
||||
|
||||
/* #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
|
||||
UNITY_DECLARE_TEX2DARRAY(_EnviroCloudsTex);
|
||||
#else
|
||||
sampler2D _EnviroCloudsTex;
|
||||
#endif*/
|
||||
|
||||
uniform sampler3D _NoiseTexture;
|
||||
|
||||
uniform int _Steps;
|
||||
uniform float3 _CameraPosition;
|
||||
uniform float4 _VolumetricLight;
|
||||
uniform float4 _HeightFog;
|
||||
uniform float4 _HeightParams;
|
||||
uniform float4 _NoiseData;
|
||||
uniform float3 _WindDirection;
|
||||
uniform float4 _MieG;
|
||||
uniform float _MaxRayLength;
|
||||
uniform float _MaxRayLengthLights;
|
||||
|
||||
uniform float4 _AmbientColor;
|
||||
|
||||
uniform float3 _DirLightDir;
|
||||
//uniform float4 _DirLightColor;
|
||||
|
||||
uniform float4 _Randomness;
|
||||
#if !SHADER_API_GLES3
|
||||
struct PointLight
|
||||
{
|
||||
float3 pos;
|
||||
float range;
|
||||
float3 color;
|
||||
float padding;
|
||||
};
|
||||
StructuredBuffer<PointLight> _PointLights;
|
||||
float _PointLightsCount;
|
||||
|
||||
struct SpotLight
|
||||
{
|
||||
float3 pos;
|
||||
float range;
|
||||
float3 color;
|
||||
float3 lightDirection;
|
||||
float lightCosHalfAngle;
|
||||
//float2 angularFalloffParameters;
|
||||
//float2 distanceFalloffParameters;
|
||||
float padding;
|
||||
};
|
||||
|
||||
StructuredBuffer<SpotLight> _SpotLights;
|
||||
float _SpotLightsCount;
|
||||
#endif
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 position : SV_POSITION;
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
v2f vert (appdata_img v)
|
||||
{
|
||||
v2f o;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_OUTPUT(v2f, o);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
o.position = UnityObjectToClipPos(v.vertex);
|
||||
//o.position = v.vertex * float4(2,2,1,1) + float4(-1,-1,0,0);
|
||||
o.uv = v.texcoord;
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 GetCascadeWeights_SplitSpheres(float3 wpos)
|
||||
{
|
||||
float3 fromCenter0 = wpos - unity_ShadowSplitSpheres[0].xyz;
|
||||
float3 fromCenter1 = wpos - unity_ShadowSplitSpheres[1].xyz;
|
||||
float3 fromCenter2 = wpos - unity_ShadowSplitSpheres[2].xyz;
|
||||
float3 fromCenter3 = wpos - unity_ShadowSplitSpheres[3].xyz;
|
||||
float4 distances2 = float4(dot(fromCenter0,fromCenter0), dot(fromCenter1,fromCenter1), dot(fromCenter2,fromCenter2), dot(fromCenter3,fromCenter3));
|
||||
float4 weights = float4(distances2 >= unity_ShadowSplitSqRadii);
|
||||
return weights;
|
||||
}
|
||||
|
||||
float4 GetCascadeShadowCoord(float4 pos, float4 cascadeWeights)
|
||||
{
|
||||
return mul(unity_WorldToShadow[(int)dot(cascadeWeights, float4(1,1,1,1))], pos);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
float GetCascadeWeights_SplitSpheres(float3 positionWS)
|
||||
{
|
||||
float3 fromCenter0 = positionWS - unity_ShadowSplitSpheres[0].xyz;
|
||||
float3 fromCenter1 = positionWS - unity_ShadowSplitSpheres[1].xyz;
|
||||
float3 fromCenter2 = positionWS - unity_ShadowSplitSpheres[2].xyz;
|
||||
float3 fromCenter3 = positionWS - unity_ShadowSplitSpheres[3].xyz;
|
||||
float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
|
||||
|
||||
float4 weights = float4(distances2 >= unity_ShadowSplitSqRadii);
|
||||
weights.yzw = saturate(weights.yzw - weights.xyz);
|
||||
|
||||
return float(4.0) - dot(weights, float4(4, 3, 2, 1));
|
||||
}
|
||||
|
||||
float4 GetCascadeShadowCoord(float3 positionWS, half cascadeIndex)
|
||||
{
|
||||
float4 shadowCoord = mul(unity_WorldToShadow[cascadeIndex], float4(positionWS, 1.0));
|
||||
|
||||
return float4(shadowCoord.xyz, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
float anisotropy(float costheta)
|
||||
{
|
||||
float g = _MieG.x;
|
||||
float gsq = g*g;
|
||||
float denom = 1 + gsq - 2.0 * g * costheta;
|
||||
denom = denom * denom * denom;
|
||||
denom = sqrt(max(0, denom));
|
||||
return (1 - gsq) / denom;
|
||||
}
|
||||
|
||||
float anisotropyPointSpot(float costheta)
|
||||
{
|
||||
float g = 0.8;
|
||||
float gsq = g*g;
|
||||
float denom = 1 + gsq - 2.0 * g * costheta;
|
||||
denom = denom * denom * denom;
|
||||
denom = sqrt(max(0, denom));
|
||||
return (1 - gsq) / denom;
|
||||
}
|
||||
|
||||
float Attenuation(float distNorm)
|
||||
{
|
||||
return 1.0 / (1.0 + 25.0 * distNorm);
|
||||
}
|
||||
|
||||
float DirectionalLight(float3 wpos)
|
||||
{
|
||||
float atten = 1.0f;
|
||||
|
||||
float4 cascadeWeights = GetCascadeWeights_SplitSpheres(wpos);
|
||||
bool inside = dot(cascadeWeights, float4(1, 1, 1, 1)) < 4;
|
||||
|
||||
float4 samplePos = GetCascadeShadowCoord(float4(wpos, 1), cascadeWeights);
|
||||
|
||||
float shadows = UNITY_SAMPLE_SHADOW(_CascadeShadowMapTexture, samplePos.xyz).r;
|
||||
|
||||
atten = inside ? shadows : 1.0f;
|
||||
|
||||
if(shadows > 0.0f)
|
||||
atten = 1.0f;
|
||||
|
||||
return atten;
|
||||
}
|
||||
#if !SHADER_API_GLES3
|
||||
float3 PointLights(float3 pos)
|
||||
{
|
||||
float3 color = 0;
|
||||
|
||||
for (int i = 0; i < _PointLightsCount; i++)
|
||||
{
|
||||
float3 posToLight = _PointLights[i].pos - pos;
|
||||
float distNorm = dot(posToLight, posToLight) * _PointLights[i].range;
|
||||
float att = Attenuation(distNorm);
|
||||
|
||||
//#if ANISOTROPY
|
||||
float3 cameraToPos = normalize(pos - _WorldSpaceCameraPos.xyz);
|
||||
float costheta = dot(cameraToPos, normalize(posToLight));
|
||||
att *= anisotropyPointSpot(costheta);
|
||||
//#endif
|
||||
|
||||
color += _PointLights[i].color * att;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
float3 SpotLights(float3 pos)
|
||||
{
|
||||
float3 color = 0;
|
||||
for (int i = 0; i < _SpotLightsCount; i++)
|
||||
{
|
||||
float3 posToLight = _SpotLights[i].pos - pos;
|
||||
float distNorm = dot(posToLight, posToLight) * _SpotLights[i].range;
|
||||
float att = Attenuation(distNorm);
|
||||
|
||||
half3 lightVector = normalize(pos - _SpotLights[i].pos);
|
||||
half cosAngle = dot(_SpotLights[i].lightDirection.xyz, lightVector);
|
||||
|
||||
half angleAttenuation = 1;
|
||||
angleAttenuation = smoothstep(_SpotLights[i].lightCosHalfAngle, lerp(1, _SpotLights[i].lightCosHalfAngle, 0.8f), cosAngle);
|
||||
angleAttenuation = pow(angleAttenuation, 2.0f);
|
||||
att *= angleAttenuation;
|
||||
|
||||
#if ANISOTROPY
|
||||
float3 cameraToPos = normalize(pos - _CameraPos.xyz);
|
||||
float costheta = dot(cameraToPos, normalize(posToLight));
|
||||
att *= anisotropyPointSpot(costheta);
|
||||
#endif
|
||||
color += _SpotLights[i].color * att;
|
||||
|
||||
}
|
||||
return color;
|
||||
}
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------------------
|
||||
// GetDensity
|
||||
//-----------------------------------------------------------------------------------------
|
||||
float GetDensity(float3 wpos, inout float density, float depth, float3 rayDir)
|
||||
{
|
||||
density = 1.0f;
|
||||
|
||||
// #ifdef NOISE
|
||||
// float4 noise = tex3D(_NoiseTexture, frac(wpos * _NoiseData.x + float3(_Time.y * _WindDirection.x, 0, _Time.y * _WindDirection.y)));
|
||||
// float noiseFbm = (noise.g * 0.625) + (noise.b * 0.25) + (noise.a * 0.125);
|
||||
// noiseFbm = saturate(noiseFbm - _NoiseData.y);
|
||||
// density *= saturate(noiseFbm);
|
||||
// #endif
|
||||
return density;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float2 squareUV(float2 uv)
|
||||
{
|
||||
float width = _ScreenParams.x;
|
||||
float height = _ScreenParams.y;
|
||||
float scale = 1000;
|
||||
float x = uv.x * width;
|
||||
float y = uv.y * height;
|
||||
return float2 (x/scale, y/scale);
|
||||
}
|
||||
float2 WorldToScreenUV(float3 worldPos)
|
||||
{
|
||||
// Project world position into clip space
|
||||
float4 clipPos = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));
|
||||
|
||||
// Perspective divide
|
||||
clipPos.xyz /= clipPos.w;
|
||||
|
||||
// Convert from clip space (-1..1) to UV space (0..1)
|
||||
float2 uv = clipPos.xy * 0.5 + 0.5;
|
||||
|
||||
return uv;
|
||||
}
|
||||
|
||||
float4 RayMarch(float2 uv,float2 screenPos, float3 rayStart, float3 rayDir, float rayLength, float rayLengthLights, float linearDepth)
|
||||
{
|
||||
if (rayLength <= 0.01 || !all(isfinite(rayDir)))
|
||||
return float4(0, 0, 0, 0);
|
||||
|
||||
float2 interleavedPos = fmod(floor(saturate(screenPos.xy)), 8.0);
|
||||
interleavedPos = clamp(interleavedPos, 0.0, 7.999);
|
||||
|
||||
#if UNITY_SINGLE_PASS_STEREO
|
||||
float4 scaleOffset = unity_StereoScaleOffset[unity_StereoEyeIndex];
|
||||
interleavedPos = (interleavedPos - scaleOffset.zw) / scaleOffset.xy;
|
||||
#endif
|
||||
|
||||
float4 ditherUV = saturate(float4(interleavedPos / 8.0 + float2(0.5 / 8.0, 0.5 / 8.0),0,0));
|
||||
float offset = tex2Dlod(_DitherTexture, ditherUV).w; //+ _Randomness.xy
|
||||
|
||||
int stepCount = _Steps;
|
||||
|
||||
float stepSize = rayLength / stepCount;
|
||||
float3 step = rayDir * stepSize;
|
||||
|
||||
float stepSizeLights = rayLengthLights / stepCount;
|
||||
float3 stepLights = rayDir * stepSizeLights;
|
||||
|
||||
float3 currentPositionDithered = rayStart + step * offset;
|
||||
float3 currentPositionLightsDithered = rayStart + stepLights * offset;
|
||||
float3 currentPosition = rayStart + step;
|
||||
|
||||
float4 color = float4(0.0,0.0,0.0,0);
|
||||
float cosAngle;
|
||||
|
||||
float extinction = 0;
|
||||
float transmitance = 0;
|
||||
float ambient = 0;
|
||||
cosAngle = dot(_DirLightDir.xyz, -rayDir);
|
||||
|
||||
float ani = anisotropy(cosAngle);
|
||||
float4 lightsColor = float4(0,0,0,0);
|
||||
|
||||
[loop]
|
||||
for (int i = 0; i < stepCount; i++)
|
||||
{
|
||||
float density = GetDensity(currentPosition, density, linearDepth, rayDir);
|
||||
float2 shadowUV = WorldToScreenUV(currentPositionDithered);
|
||||
//float cloudsShadows = pow(UNITY_SAMPLE_SCREENSPACE_TEXTURE(_EnviroCloudsTex, shadowUV).b,0.25);
|
||||
|
||||
float atten = DirectionalLight(currentPositionDithered) * 0.1 ;//* (1-cloudsShadows);
|
||||
|
||||
float scattering = _VolumetricLight.x * density;
|
||||
extinction += _VolumetricLight.y * density;
|
||||
|
||||
transmitance += atten * scattering * exp(-extinction);
|
||||
#if !SHADER_API_GLES3
|
||||
lightsColor.rgb += PointLights(currentPositionLightsDithered) * stepSizeLights * density;
|
||||
lightsColor.rgb += SpotLights(currentPositionLightsDithered) * stepSizeLights * density;
|
||||
#endif
|
||||
currentPosition += step;
|
||||
currentPositionDithered += step;
|
||||
currentPositionLightsDithered += stepLights;
|
||||
}
|
||||
|
||||
//color.rgb = _DirLightColor.rgb * transmitance * ani;
|
||||
color.a = transmitance * ani;
|
||||
color.rgb += lightsColor.rgb * 0.1;
|
||||
|
||||
color = max(0, color);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
float4 frag (v2f i) : SV_Target
|
||||
{
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
|
||||
|
||||
float2 uv = i.uv.xy;
|
||||
|
||||
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv);
|
||||
float linearDepth = Linear01Depth(depth);
|
||||
|
||||
float4x4 proj, eyeToWorld;
|
||||
|
||||
if (unity_StereoEyeIndex == 0)
|
||||
{
|
||||
proj = _LeftViewFromScreen;
|
||||
eyeToWorld = _LeftWorldFromView;
|
||||
}
|
||||
else
|
||||
{
|
||||
proj = _RightViewFromScreen;
|
||||
eyeToWorld = _RightWorldFromView;
|
||||
}
|
||||
|
||||
//bit of matrix math to take the screen space coord (u,v,depth) and transform to world space
|
||||
float2 uvClip = i.uv * 2.0 - 1.0;
|
||||
float clipDepth = depth; // Fix for OpenGl Core thanks to Lars Bertram
|
||||
clipDepth = (UNITY_NEAR_CLIP_VALUE < 0) ? clipDepth * 2 - 1 : clipDepth;
|
||||
float4 clipPos = float4(uvClip, clipDepth, 1.0);
|
||||
float4 viewPos = mul(proj, clipPos); // inverse projection by clip position
|
||||
viewPos /= viewPos.w; // perspective division
|
||||
float3 wpos = mul(eyeToWorld, viewPos).xyz;
|
||||
|
||||
float3 rayStart = _WorldSpaceCameraPos;
|
||||
float3 rayDir = wpos - _WorldSpaceCameraPos;
|
||||
//rayDir *= linearDepth;
|
||||
|
||||
float rayLength = length(rayDir);
|
||||
rayDir /= rayLength;
|
||||
|
||||
float rayLengthLights = min(rayLength, _MaxRayLengthLights);
|
||||
rayLength = min(rayLength, _MaxRayLength);
|
||||
|
||||
float4 color = RayMarch(uv, i.position.xy, rayStart, rayDir, rayLength, rayLengthLights, linearDepth);
|
||||
|
||||
return color;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user