Files
ichni_Creator_Studio/Assets/ThemeBundles/Basic/Materials/PseudoShadow.shader

104 lines
4.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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"
}