shaoxiadiablo/Assets/AGame/Res/Shaders/MY/MYPBRPlayer.shader

212 lines
6.0 KiB
Plaintext
Raw Permalink Normal View History

2025-05-18 01:04:31 +08:00
Shader "MY/PBR/Player"
{
Properties
{
_Color("Color", Color) = (1,1,1,1)
_RimColor("RimColor", Color) = (1,1,1,1)
_MainTex("Albedo", 2D) = "white" {}
_GlossMapScale("Smoothness Factor", Range(0.0, 1.0)) = 1.0
_SpecGlossMap("Specular", 2D) = "black" {}
}
SubShader
{
Lod 200
Tags{ "Queue" = "Geometry+20" "RenderType" = "Geometry" "LightMode" = "ForwardBase" "IgnoreProjector" = "True" }
Pass
{
CGPROGRAM
#pragma multi_compile_fwdbase
#pragma multi_compile_fog
#pragma vertex vert
#pragma fragment frag
#include "HLSLSupport.cginc"
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
uniform sampler2D _MainTex;
uniform half4 _MainTex_ST;
uniform sampler2D _SpecGlossMap;
uniform fixed _GlossMapScale;
uniform fixed4 _Color;
uniform half _MatCapPower;
uniform fixed3 _RimColor;
struct v2f_surf
{
UNITY_POSITION(pos);
half2 uv : TEXCOORD0;
half3 eyeVec : TEXCOORD1;
half3 normalWorld : TEXCOORD2;
half3 posWorld : TEXCOORD4;
half3 viewDir : TEXCOORD5;
half3 normal :TEXCOORD6;
LIGHTING_COORDS(7, 8)
};
struct PBROutput
{
fixed3 diffColor, specColor;
fixed oneMinusReflectivity, smoothness;
fixed3 normalWorld;
fixed3 eyeVec;
half3 posWorld;
};
half RoughnessToSP(half perceptualRoughness)
{
half m = perceptualRoughness * perceptualRoughness;
half sq = max(1e-4f, m*m);
half n = (2.0 / sq) - 2.0;
n = max(n, 1e-4f);
return n;
}
fixed4 BRDF_PBS(PBROutput s,UnityLight light, UnityIndirect gi)
{
fixed3 halfDir = Unity_SafeNormalize(half3(light.dir) - s.eyeVec);
fixed nl = saturate(dot(s.normalWorld, light.dir));
fixed nh = saturate(dot(s.normalWorld, halfDir));
fixed nv = saturate(dot(s.normalWorld, -s.eyeVec));
fixed lh = saturate(dot(light.dir, halfDir));
fixed perceptualRoughness = 1 - s.smoothness;
fixed roughness = perceptualRoughness * perceptualRoughness;
fixed specularPower = RoughnessToSP(perceptualRoughness);
half invV = lh * lh * s.smoothness + perceptualRoughness * perceptualRoughness;
fixed invF = lh;
half specularTerm = ((specularPower + 1) * pow(nh, specularPower)) / (8 * invV * invF + 1e-4h);
specularTerm = sqrt(max(1e-4f, specularTerm));
specularTerm = clamp(specularTerm, 0.0, 100.0);
fixed surfaceReduction = 0.28;
surfaceReduction = 1.0 - roughness * perceptualRoughness * surfaceReduction;
fixed grazingTerm = saturate(s.smoothness + (1 - s.oneMinusReflectivity));
fixed3 Fresnel = lerp(s.specColor, grazingTerm, Pow4(1 - nv));
fixed3 color = (s.diffColor + specularTerm * s.specColor) * light.color * nl + gi.diffuse * s.diffColor + surfaceReduction * gi.specular * Fresnel;
return fixed4(color, 1);
}
v2f_surf vert(appdata_full v)
{
v2f_surf o = (v2f_surf)0;
UNITY_INITIALIZE_OUTPUT(v2f_surf, o);
half4 posWorld = mul(unity_ObjectToWorld, v.vertex);
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.eyeVec = normalize(posWorld.xyz - _WorldSpaceCameraPos);
half3 normalWorld = UnityObjectToWorldNormal(v.normal);
o.normalWorld = normalWorld;
o.normal = UnityObjectToWorldNormal(v.normal);
o.viewDir = normalize(UnityWorldSpaceViewDir(mul(unity_ObjectToWorld, v.vertex).xyz));
return o;
}
fixed4 frag(v2f_surf i) : SV_Target
{
fixed4 specGloss = tex2D(_SpecGlossMap, i.uv);
specGloss.a *= _GlossMapScale;
fixed3 specColor = specGloss.rrr;
fixed smoothness = specGloss.a;
fixed oneMinusReflectivity = 1 - max(max(specColor.r, specColor.g), specColor.b);
fixed3 diffColor = _Color.rgb * tex2D(_MainTex, i.uv).rgb * oneMinusReflectivity;
PBROutput s = (PBROutput)0;
s.diffColor = diffColor;
s.specColor = specColor;
s.oneMinusReflectivity = oneMinusReflectivity;
s.smoothness = smoothness;
s.normalWorld = normalize(i.normalWorld);
s.eyeVec = normalize(i.eyeVec);
UnityLight mainLight;
mainLight.color = _LightColor0.rgb;
mainLight.dir = _WorldSpaceLightPos0.xyz;
half atten = LIGHT_ATTENUATION(i);
Unity_GlossyEnvironmentData g;
g.roughness = 1 - s.smoothness;
g.reflUVW = reflect(s.eyeVec, s.normalWorld);
UnityGI gi;
ResetUnityGI(gi);
gi.light = mainLight;
gi.light.color *= atten;
gi.indirect.diffuse = ShadeSHPerPixel(s.normalWorld, fixed3(0.3, 0.3, 0.3), s.posWorld);
//_RimColor.xyz = specGloss.bbb;
//边缘光
fixed3 rim = _RimColor * saturate(1 - saturate(dot(i.normal, i.viewDir)) * 1.8) *(0.2 + _MatCapPower);
fixed4 c = BRDF_PBS(s, gi.light, gi.indirect);
c.rgb += rim;
c.rgb += _RimColor * specGloss.b;
return fixed4(c.rgb, 1);
}
ENDCG
}
}
SubShader
{
Lod 100
Tags{ "Queue" = "Geometry+20" "IgnoreProjector" = "True" }
Pass
{
CGPROGRAM
#pragma vertex vert_surf
#pragma fragment frag_surf
#pragma multi_compile_fwdbase
#include "HLSLSupport.cginc"
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform half4 _MainTex_ST;
uniform half4 _Color;
uniform half3 _RimColor;
uniform half _MatCapPower;
struct v2f_surf
{
UNITY_POSITION(pos);
half2 uv : TEXCOORD0;
half3 normal : TEXCOORD1;
half3 viewDir : TEXCOORD2;
};
v2f_surf vert_surf(appdata_full v)
{
v2f_surf o = (v2f_surf)0;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
half3 worldN = UnityObjectToWorldNormal(v.normal);
o.normal = worldN;
o.viewDir = normalize(UnityWorldSpaceViewDir(mul(unity_ObjectToWorld, v.vertex).xyz));
return o;
}
fixed4 frag_surf(v2f_surf IN) : SV_Target
{
fixed4 albedo = tex2D(_MainTex, IN.uv);
fixed4 c = albedo;
c.rgb *= _Color.rgb;
c.rgb += _RimColor * saturate(1 - saturate(dot(IN.normal, IN.viewDir)) * 1.8) *(0.2 + _MatCapPower);
return c;
}
ENDCG
}
}
}