unity Shader新增

This commit is contained in:
Abin committed 2026-03-10 20:36:07 +08:00
1 parent 12dce37dbb
commit da3087b1d4
36 files changed
+8857

No files matched your search

@@ -0,0 +1,267 @@
Shader "Hidden/MobileFog"
{
Properties
{
_MainTex ("Main Texture", 2D) = "white" {}
_FogGradient ("Fog Gradient", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" }
ZTest Always ZWrite Off Cull Off
Pass
{
Name "MobileFog"
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_local _ _USE_FAST_MODE
#pragma multi_compile_local _ _USE_GRADIENT_COLOR
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float2 uv : TEXCOORD0;
float3 viewVector : TEXCOORD1;
};
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
TEXTURE2D(_FogGradient);
SAMPLER(sampler_FogGradient);
// 雾效参数
float _FogDensity;
float _FogStart;
float _FogEnd;
float _HeightFogDensity;
float _HeightFogBase;
float _HeightFogRange;
float4 _FogColor;
float4 _FogColorNear;
float4 _FogColorFar;
float _GradientDistance;
float _UseGradientColor;
float _Intensity;
float _UseFastMode;
// 噪波参数
float _NoiseScale;
float _NoiseIntensity;
float _NoiseSpeed;
Varyings vert(Attributes input)
{
Varyings output;
output.positionHCS = TransformObjectToHClip(input.positionOS.xyz);
output.uv = input.uv;
// 计算视图向量,用于重建世界坐标
float4 clipPos = float4(input.uv * 2.0 - 1.0, 1.0, 1.0);
float4 viewPos = mul(unity_CameraInvProjection, clipPos);
output.viewVector = viewPos.xyz / viewPos.w;
return output;
}
// 简单的2D噪波函数
float random(float2 st)
{
return frac(sin(dot(st.xy, float2(12.9898,78.233))) * 43758.5453123);
}
// Perlin噪波近似
float noise(float2 st)
{
float2 i = floor(st);
float2 f = frac(st);
// 四个角的随机值
float a = random(i);
float b = random(i + float2(1.0, 0.0));
float c = random(i + float2(0.0, 1.0));
float d = random(i + float2(1.0, 1.0));
// 平滑插值
float2 u = f * f * (3.0 - 2.0 * f);
return lerp(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
}
// 分形噪波
float fbm(float2 st, int octaves)
{
float value = 0.0;
float amplitude = 0.5;
float frequency = 1.0;
for (int i = 0; i < octaves; i++)
{
value += amplitude * noise(st * frequency);
amplitude *= 0.5;
frequency *= 2.0;
}
return value;
}
// 根据距离获取雾的颜色
float3 GetFogColor(float depth)
{
if (_UseGradientColor > 0.5)
{
// 计算距离插值因子 (0=近处, 1=远处)
float distanceFactor = saturate((depth - _FogStart) / max(_GradientDistance, 0.001));
// 在近处和远处颜色之间插值
return lerp(_FogColorNear.rgb, _FogColorFar.rgb, distanceFactor);
}
else
{
// 使用固定颜色
return _FogColor.rgb;
}
}
// 从渐变贴图采样颜色(可选的高级功能)
float3 GetFogColorFromTexture(float depth)
{
// 将深度映射到0-1范围
float t = saturate((depth - _FogStart) / max(_GradientDistance, 0.001));
return SAMPLE_TEXTURE2D_LOD(_FogGradient, sampler_FogGradient, float2(t, 0.5), 0).rgb;
}
// 计算基础深度雾(不受高度影响)
float CalculateDepthFog(float depth)
{
return saturate((depth - _FogStart) / max(_FogEnd - _FogStart, 0.001)) * _FogDensity;
}
// 计算基础深度雾(精确模式)
float CalculateDepthFogPrecise(float depth)
{
return 1.0 - exp(-_FogDensity * max(depth - _FogStart, 0.0));
}
// 计算带噪波的高度因子(0-1,用于调节深度雾密度)
float CalculateHeightFactorWithNoise(float height, float3 worldPos)
{
// 基础高度计算
float heightOffset = height - _HeightFogBase;
// 添加基于世界坐标的噪波扰动
float2 noiseCoord = worldPos.xz * _NoiseScale + _Time.y * _NoiseSpeed;
// 生成多层噪波
float heightNoise = fbm(noiseCoord, 3) * 2.0 - 1.0; // -1 到 1
float detailNoise = fbm(noiseCoord * 3.0, 2) * 0.5; // 细节噪波
// 组合噪波
float combinedNoise = (heightNoise + detailNoise * 0.3) * _NoiseIntensity;
// 将噪波应用到高度偏移
float noisyHeightOffset = heightOffset + combinedNoise;
// 计算标准化高度,使用更平滑的过渡
float normalizedHeight = noisyHeightOffset / max(_HeightFogRange, 0.001);
// 使用更自然的衰减曲线 (高度越低值越大,高度越高值越小)
float heightFactor = 1.0 / (1.0 + exp(normalizedHeight * 4.0 - 2.0)); // sigmoid函数
return heightFactor;
}
// 快速雾效计算(移动端优化)
float CalculateFogFast(float depth, float height, float3 worldPos)
{
// 计算独立的深度雾
float depthFog = CalculateDepthFog(depth);
// 计算高度调节因子 (0-1)
float heightFactor = CalculateHeightFactorWithNoise(height, worldPos);
// 计算独立的高度雾
float heightFog = _HeightFogDensity * heightFactor;
// 深度雾受高度影响:高度越低,深度雾越浓
float heightInfluencedDepthFog = depthFog * lerp(0.1, 1.0, heightFactor);
// 组合两种雾效:使用加法混合,但避免过饱和
float combinedFog = heightInfluencedDepthFog + heightFog;
return saturate(combinedFog);
}
// 高质量雾效计算
float CalculateFogPrecise(float depth, float height, float3 worldPos)
{
// 计算独立的指数深度雾
float depthFog = CalculateDepthFogPrecise(depth);
// 计算带噪波的平滑高度调节因子
float heightFactor = CalculateHeightFactorWithNoise(height, worldPos);
heightFactor = smoothstep(0.0, 1.0, heightFactor);
// 计算独立的高度雾
float heightFog = _HeightFogDensity * heightFactor;
// 深度雾受高度影响:使用更平滑的过渡
float heightInfluencedDepthFog = depthFog * lerp(0.1, 1.0, heightFactor);
// 使用更自然的组合方式:乘法混合避免过度叠加
float combinedFog = 1.0 - (1.0 - heightInfluencedDepthFog) * (1.0 - heightFog);
return saturate(combinedFog);
}
float4 frag(Varyings input) : SV_Target
{
float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv);
// 采样深度并转换为线性深度
float depth = SampleSceneDepth(input.uv);
float linearDepth = LinearEyeDepth(depth, _ZBufferParams);
// 重建世界坐标以获取高度信息
float3 worldPos = _WorldSpaceCameraPos + input.viewVector * linearDepth;
float height = worldPos.y;
// 根据设置选择计算模式
float fogFactor;
if (_UseFastMode > 0.5)
{
fogFactor = CalculateFogFast(linearDepth, height, worldPos);
}
else
{
fogFactor = CalculateFogPrecise(linearDepth, height, worldPos);
}
// 应用强度控制
fogFactor *= _Intensity;
// 根据距离获取雾的颜色
float3 fogColor = GetFogColor(linearDepth);
// 混合原色和雾色
float3 finalColor = lerp(color.rgb, fogColor, fogFactor);
return float4(finalColor, color.a);
}
ENDHLSL
}
}
Fallback Off
}