104 lines
4.0 KiB
Plaintext
104 lines
4.0 KiB
Plaintext
|
|
Shader "Custom/ImprovedPseudoShadow" {
|
|||
|
|
Properties {
|
|||
|
|
[Header(Base)]
|
|||
|
|
_MainTex ("Texture", 2D) = "white" {}
|
|||
|
|
_Color ("Main Color", Color) = (1,1,1,1)
|
|||
|
|
|
|||
|
|
[Header(Shadow)]
|
|||
|
|
_ShadowColor ("Shadow Color", Color) = (0.2, 0.2, 0.3, 1) // 默认偏蓝的阴影
|
|||
|
|
_ShadowThreshold ("Shadow Threshold", Range(-1,1)) = 0.0
|
|||
|
|
_ShadowSmoothness ("Shadow Smoothness", Range(0,1)) = 0.1
|
|||
|
|
|
|||
|
|
[Header(Lighting Mode)]
|
|||
|
|
_UseWorldLight ("Use Fixed World Light?", Range(0,1)) = 0
|
|||
|
|
_FakeLightDir ("Fake Light Dir (XYZ)", Vector) = (0.5, 1, 0.5, 0) // 模拟从右上方来的光
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
SubShader {
|
|||
|
|
Tags { "RenderType"="Transparent" }
|
|||
|
|
LOD 100
|
|||
|
|
|
|||
|
|
Pass {
|
|||
|
|
CGPROGRAM
|
|||
|
|
#pragma vertex vert
|
|||
|
|
#pragma fragment frag
|
|||
|
|
// 开启 GPU Instancing 支持
|
|||
|
|
#pragma multi_compile_instancing
|
|||
|
|
#include "UnityCG.cginc"
|
|||
|
|
|
|||
|
|
struct appdata {
|
|||
|
|
float4 vertex : POSITION;
|
|||
|
|
float3 normal : NORMAL;
|
|||
|
|
float2 uv : TEXCOORD0;
|
|||
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID // Instancing ID
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
struct v2f {
|
|||
|
|
float2 uv : TEXCOORD0;
|
|||
|
|
float4 vertex : SV_POSITION;
|
|||
|
|
float lightFactor : TEXCOORD1; // 传递光照因子
|
|||
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID // Instancing ID
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
sampler2D _MainTex;
|
|||
|
|
float4 _MainTex_ST;
|
|||
|
|
|
|||
|
|
// 声明 Instancing 属性变量
|
|||
|
|
UNITY_INSTANCING_BUFFER_START(Props)
|
|||
|
|
UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color)
|
|||
|
|
UNITY_DEFINE_INSTANCED_PROP(fixed4, _ShadowColor)
|
|||
|
|
UNITY_DEFINE_INSTANCED_PROP(float4, _FakeLightDir)
|
|||
|
|
UNITY_DEFINE_INSTANCED_PROP(float, _ShadowThreshold)
|
|||
|
|
UNITY_DEFINE_INSTANCED_PROP(float, _ShadowSmoothness)
|
|||
|
|
UNITY_DEFINE_INSTANCED_PROP(float, _UseWorldLight)
|
|||
|
|
UNITY_INSTANCING_BUFFER_END(Props)
|
|||
|
|
|
|||
|
|
v2f vert (appdata v) {
|
|||
|
|
v2f o;
|
|||
|
|
UNITY_SETUP_INSTANCE_ID(v);
|
|||
|
|
UNITY_TRANSFER_INSTANCE_ID(o, v);
|
|||
|
|
|
|||
|
|
o.vertex = UnityObjectToClipPos(v.vertex);
|
|||
|
|
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
|||
|
|
|
|||
|
|
float3 normalWorld = UnityObjectToWorldNormal(v.normal);
|
|||
|
|
float3 lightDir;
|
|||
|
|
|
|||
|
|
float useWorldLight = UNITY_ACCESS_INSTANCED_PROP(Props, _UseWorldLight);
|
|||
|
|
float3 fakeDir = normalize(UNITY_ACCESS_INSTANCED_PROP(Props, _FakeLightDir).xyz);
|
|||
|
|
float3 viewDir = normalize(WorldSpaceViewDir(v.vertex));
|
|||
|
|
// 用lerp实现分支
|
|||
|
|
lightDir = normalize(lerp(viewDir, fakeDir, useWorldLight));
|
|||
|
|
|
|||
|
|
float dotProduct = dot(normalWorld, lightDir);
|
|||
|
|
o.lightFactor = dotProduct;
|
|||
|
|
return o;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fixed4 frag (v2f i) : SV_Target {
|
|||
|
|
UNITY_SETUP_INSTANCE_ID(i);
|
|||
|
|
|
|||
|
|
// 获取属性
|
|||
|
|
fixed4 mainColor = UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
|
|||
|
|
fixed4 shadowColor = UNITY_ACCESS_INSTANCED_PROP(Props, _ShadowColor);
|
|||
|
|
float threshold = UNITY_ACCESS_INSTANCED_PROP(Props, _ShadowThreshold);
|
|||
|
|
float smoothness = UNITY_ACCESS_INSTANCED_PROP(Props, _ShadowSmoothness);
|
|||
|
|
|
|||
|
|
fixed4 texCol = tex2D(_MainTex, i.uv) * mainColor;
|
|||
|
|
|
|||
|
|
// 改进2:更平滑且可控的阈值计算 (Smoothstep)
|
|||
|
|
// lightFactor 越大说明越直接面对光源
|
|||
|
|
float lightIntensity = smoothstep(threshold, threshold + smoothness, i.lightFactor);
|
|||
|
|
|
|||
|
|
// 改进3:基于光照强度的颜色插值 (Lerp)
|
|||
|
|
// 0 (背光) -> ShadowColor
|
|||
|
|
// 1 (受光) -> Texture Color
|
|||
|
|
fixed3 finalRGB = lerp(shadowColor.rgb * texCol.rgb, texCol.rgb, lightIntensity);
|
|||
|
|
|
|||
|
|
return fixed4(finalRGB, texCol.a);
|
|||
|
|
}
|
|||
|
|
ENDCG
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
FallBack "VertexLit"
|
|||
|
|
}
|