155 lines
4.6 KiB
Plaintext
155 lines
4.6 KiB
Plaintext
Shader "MY/PBR/VertexLit"
|
|
{
|
|
Properties
|
|
{
|
|
_Color("Color", Color) = (1,1,1,1)
|
|
_MainTex("主贴图", 2D) = "white"{}
|
|
_NormalTex("法线", 2D) = "bump"{}
|
|
_MetalnessTex("金属遮罩", 2D) = "black"{}
|
|
_Metalness("金属系数", Range(0,1)) = 0.35
|
|
_Smoothness("Smoothness", Range(0,1)) = 0.35
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
Tags{ "RenderType" = "Geometry" "IgnoreProjector" = "False" }
|
|
ColorMask RGB
|
|
Pass
|
|
{
|
|
Name "FORWARD"
|
|
Tags{ "LightMode" = "ForwardBase" }
|
|
ColorMask RGB
|
|
CGPROGRAM
|
|
#pragma vertex vert_surf
|
|
#pragma fragment frag_surf
|
|
|
|
#include "HLSLSupport.cginc"
|
|
#include "UnityCG.cginc"
|
|
#include "Lighting.cginc"
|
|
#include "AutoLight.cginc"
|
|
|
|
uniform sampler2D _MainTex;
|
|
uniform half4 _MainTex_ST;
|
|
uniform sampler2D _NormalTex;
|
|
uniform sampler2D _MetalnessTex;
|
|
|
|
uniform fixed4 _Color;
|
|
uniform fixed _Reflect;
|
|
uniform fixed _Metalness;
|
|
uniform fixed _Smoothness;
|
|
uniform fixed _MatCapPower;
|
|
|
|
struct v2f_surf
|
|
{
|
|
UNITY_POSITION(pos);
|
|
half4 uv : TEXCOORD0;
|
|
half4 tSpace0 : TEXCOORD1;
|
|
half4 tSpace1 : TEXCOORD2;
|
|
half4 tSpace2 : TEXCOORD3;
|
|
half3 sh : TEXCOORD4;
|
|
LIGHTING_COORDS(5, 6)
|
|
half4 uv1 : TEXCOORD7;
|
|
};
|
|
|
|
struct PBROutput
|
|
{
|
|
fixed3 Albedo;
|
|
fixed3 Normal;
|
|
fixed3 Emission;
|
|
fixed Metallic;
|
|
fixed Smoothness;
|
|
fixed Alpha;
|
|
};
|
|
|
|
inline fixed3 BRDF_PBS(PBROutput s, fixed3 viewDir, UnityGI gi)
|
|
{
|
|
fixed reflect;
|
|
fixed3 specColor;
|
|
fixed3 Albedo = s.Albedo;
|
|
s.Albedo = DiffuseAndSpecularFromMetallic(s.Albedo, s.Metallic, specColor, reflect);
|
|
fixed3 normal = normalize(s.Normal);
|
|
fixed3 lightdir = gi.light.dir;
|
|
fixed3 lightcolor = gi.light.color;
|
|
|
|
fixed Roughness = 1 - s.Smoothness;
|
|
fixed3 halfDir = normalize(lightdir + viewDir);
|
|
fixed nv = abs(dot(normal, viewDir));
|
|
fixed nl = saturate(dot(normal, lightdir));
|
|
fixed nh = saturate(dot(normal, halfDir));
|
|
fixed lv = saturate(dot(lightdir, viewDir));
|
|
fixed lh = saturate(dot(lightdir, halfDir));
|
|
|
|
fixed diffuseTerm = DisneyDiffuse(nv, nl, lh, Roughness) * nl;
|
|
fixed roughness = Roughness * Roughness;
|
|
|
|
roughness = max(roughness, 0.002);
|
|
fixed V = SmithJointGGXVisibilityTerm(nl, nv, roughness);
|
|
fixed D = GGXTerm(nh, roughness);
|
|
|
|
fixed specularTerm = V * D * UNITY_PI;
|
|
specularTerm = sqrt(max(1e-4h, specularTerm));
|
|
specularTerm = max(0, specularTerm * nl);
|
|
|
|
return s.Albedo * (gi.indirect.diffuse + lightcolor * diffuseTerm) + specularTerm * lightcolor * FresnelTerm(specColor, lh);
|
|
}
|
|
|
|
|
|
v2f_surf vert_surf(appdata_full v)
|
|
{
|
|
v2f_surf o = (v2f_surf)0;
|
|
o.pos = UnityObjectToClipPos(v.vertex);
|
|
o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
|
|
half3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
|
|
fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
|
|
fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
|
|
fixed tangentSign = v.tangent.w * unity_WorldTransformParams.w;
|
|
fixed3 worldBinormal = cross(worldNormal, worldTangent) * tangentSign;
|
|
o.tSpace0 = half4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);
|
|
o.tSpace1 = half4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);
|
|
o.tSpace2 = half4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);
|
|
o.sh = ShadeSHPerVertex(worldNormal, o.sh);
|
|
return o;
|
|
}
|
|
|
|
fixed4 frag_surf(v2f_surf IN) : SV_Target
|
|
{
|
|
fixed4 albedo = tex2D(_MainTex, IN.uv.xy);
|
|
fixed4 c = albedo;
|
|
fixed3 normal = UnpackNormal(tex2D(_NormalTex, IN.uv.xy));
|
|
fixed2 metalnessTexed = tex2D(_MetalnessTex, IN.uv.xy).ra * _Metalness;
|
|
metalnessTexed.g *= _Smoothness;
|
|
fixed metallic = metalnessTexed.r;
|
|
|
|
//边缘光
|
|
half3 worldPos = half3(IN.tSpace0.w, IN.tSpace1.w, IN.tSpace2.w);
|
|
fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPos));
|
|
|
|
PBROutput o = (PBROutput)0;
|
|
o.Albedo = albedo.rgb * _Color.rgb;
|
|
o.Normal = normal;
|
|
o.Metallic = metallic;
|
|
o.Smoothness = metalnessTexed.g;
|
|
o.Emission = 0;
|
|
|
|
fixed3 worldN;
|
|
worldN.x = dot(IN.tSpace0.xyz, o.Normal);
|
|
worldN.y = dot(IN.tSpace1.xyz, o.Normal);
|
|
worldN.z = dot(IN.tSpace2.xyz, o.Normal);
|
|
worldN = normalize(worldN);
|
|
o.Normal = worldN;
|
|
|
|
UnityGI gi;
|
|
gi.indirect.diffuse = ShadeSHPerPixel(o.Normal, IN.sh, worldPos);
|
|
gi.indirect.specular = 0;
|
|
gi.light.color = _LightColor0.rgb;
|
|
gi.light.dir = normalize(UnityWorldSpaceLightDir(worldPos));
|
|
|
|
c.rgb = BRDF_PBS(o, worldViewDir, gi);
|
|
c.rgb += o.Emission;
|
|
c.a *= _Color.a;
|
|
return c;
|
|
}
|
|
ENDCG
|
|
}
|
|
}
|
|
} |