话不多说,直接上代码,具体区别我后边会补充上,
暂时委屈各位,先锻炼下自己的“找不同”的能力,哈哈:
Built-CG写法:
Shader "Unity Shaders Book/Chapter 7/Normal Map In World Space" {
Properties {
_Color("Color", Color) = (1, 1, 1, 1)
_Specular("Specular", Color) = (1, 1, 1, 1)
_MainTex("Main Tex", 2D) = "white"{}
_BumpMap("Bump Map", 2D) = "white"{}
_Gloss("Gloss", Range(10, 256)) = 20
_BumpScale("BumpScale", Range(-2, 2)) = 0
}
SubShader {
Pass {
Tags {
"LightMode"="ForwardBase"
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
fixed4 _Color;
fixed4 _Specular;
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _BumpMap;
float4 _BumpMap_ST;
float _Gloss;
float _BumpScale;
struct a2v {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
float4 TtoW0 : TEXCOORD1;
float4 TtoW1 : TEXCOORD2;
float4 TtoW2 : TEXCOORD3;
};
v2f vert(a2v data) {
v2f v;
v.pos = UnityObjectToClipPos(data.vertex);
v.uv.xy = data.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
v.uv.zw = data.texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw;
float4 worldPos = mul(unity_ObjectToWorld, data.vertex);
float3 worldNormal = UnityObjectToWorldNormal(data.normal);
float3 worldTangent = UnityObjectToWorldDir(data.tangent.xyz);
float3 worldBinormal = cross(worldNormal, worldTangent) * data.tangent.w;
// worldTangent、worldBinormal、worldNormal为世界坐标系下的表示
// 按列摆放组成的矩阵即为 切线空间->世界空间 的矩阵
v.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);
v.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);
v.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);
return v;
}
fixed4 frag(v2f v) : SV_Target {
float3 worldPos = float3(v.TtoW0.w, v.TtoW1.w, v.TtoW2.w);
fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));
fixed3 bump = UnpackNormal(tex2D(_BumpMap, v.uv.zw));
bump.xy *= _BumpScale;
bump.z = sqrt(1 - saturate(dot(bump.xy, bump.xy)));
bump = normalize(half3(dot(v.TtoW0.xyz, bump), dot(v.TtoW1.xyz, bump), dot(v.TtoW2.xyz, bump)));
fixed3 albedo = tex2D(_MainTex, v.uv.xy).rgb * _Color.rgb;
// 环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
// 漫反射
fixed3 diffuse = _LightColor0.rgb * albedo * saturate(dot(bump, lightDir));
// 高光
fixed3 halfDir = normalize(lightDir + viewDir);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(halfDir, bump)), _Gloss);
return fixed4(ambient + diffuse + specular, 1);
}
ENDCG
}
}
FallBack "Specular"
}
URP+HLSL写法:
Shader "Unity Shaders Book/Chapter 7/Normal Map In World Space" {
Properties {
_Color("Color", Color) = (1, 1, 1, 1)
_Specular("Specular", Color) = (1, 1, 1, 1)
_MainTex("Main Tex", 2D) = "white"{}
_BumpMap("Bump Map", 2D) = "white"{}
_Gloss("Gloss", Range(10, 256)) = 20
_BumpScale("BumpScale", Range(-2, 2)) = 0
}
SubShader {
Pass {
Tags {
"RenderPipeline"="UniversalPipeline"
}
Tags {
"LightMode"="UniversalForward"
}
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
half4 _Color;
half4 _Specular;
float4 _MainTex_ST;
float4 _BumpMap_ST;
float _Gloss;
float _BumpScale;
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
TEXTURE2D(_BumpMap);
SAMPLER(sampler_BumpMap);
struct a2v {
float4 vertex : POSITION;
half3 normal : NORMAL;
float4 tangent : TANGENT;
float4 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
float4 TtoW0 : TEXCOORD1;
float4 TtoW1 : TEXCOORD2;
float4 TtoW2 : TEXCOORD3;
};
v2f vert(a2v data) {
v2f v;
v.pos = TransformObjectToHClip(data.vertex.xyz);
v.uv.xy = data.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
v.uv.zw = data.texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw;
float3 worldPos = mul(UNITY_MATRIX_M, data.vertex).xyz;
float3 worldNormal = TransformObjectToWorldNormal(data.normal);
float3 worldTangent = TransformObjectToWorldDir(data.tangent.xyz);
float3 worldBinormal = cross(worldNormal, worldTangent) * data.tangent.w;
// worldTangent、worldBinormal、worldNormal为世界坐标系下的表示
// 按列摆放组成的矩阵即为 切线空间->世界空间 的矩阵
v.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);
v.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);
v.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);
return v;
}
half4 frag(v2f v) : SV_Target {
float3 worldPos = float3(v.TtoW0.w, v.TtoW1.w, v.TtoW2.w);
half3 lightDir = normalize(_MainLightPosition.xyz);
half3 viewDir = normalize(_WorldSpaceCameraPos.xyz - worldPos);
half3 bump = UnpackNormal(SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, v.uv.zw));
bump.xy *= _BumpScale;
bump.z = sqrt(1 - saturate(dot(bump.xy, bump.xy)));
bump = normalize(half3(dot(v.TtoW0.xyz, bump), dot(v.TtoW1.xyz, bump), dot(v.TtoW2.xyz, bump)));
half3 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, v.uv.xy).rgb * _Color.rgb;
// 环境光
half3 ambient = half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) * albedo;
// 漫反射
half3 diffuse = _MainLightColor.rgb * albedo * saturate(dot(bump, lightDir));
// 高光
half3 halfDir = normalize(lightDir + viewDir);
half3 specular = _MainLightColor.rgb * _Specular.rgb * pow(saturate(dot(halfDir, bump)), _Gloss);
return half4(ambient + diffuse + specular, 1);
}
ENDHLSL
}
}
FallBack "Universal Render Pipeline/Simple Lit"
}