<aside> <img src="/icons/exclamation-mark_gray.svg" alt="/icons/exclamation-mark_gray.svg" width="40px" /> Unity使用的紋理空間與OpenGL一樣都是以「左下角」為原點。

</aside>

Unity Shader

Properties {
	_MainTex ("Main Tex", 2D) = "white" {} // 可用"black"
}

sampler2D _MainTex;
float4 _MainTex_ST; // xy: Scale(Tiling) & zw: Translation(Offset)

因為2D屬性還有Tiling和Offset的設置,所以uv還需要根據Tiling和Offset做修改

uv = i.uv * _MainTex_ST.xy + _MainTex_ST.zw;
uv = TRANSFORM_TEX (i.uv, _MainTex); // 等價上面的代碼

TRANSFORM_TEX是一個宏,等價於上一行代碼。

fixed3 albedo = Tex2D (_MainTex, uv).rgb;
fixed4 packedNormal = tex2D (_BumpMap, uv);
fixed3 tangentNormal;

// 如果Texture沒有被標記為Normal Map
tangentNormal.xy = (packedNormal.xy * 2 - 1) * _BumpScale;  // 映射回[-1, 1]範圍
tangentNormal.z = sqrt (1.0 - saturate (dot (tangentNormal.xy, tangentNormal.xy))); // 算出z軸

// 如果Texture被標記為Normal Map
tangentNormal = UnpackNormal (packedNormal);

tangentNormal.xy *= _BumpScale;
tangentNormal.z = sqrt (1.0 - saturate (dot (tangentNormal.xy, tangentNormal.xy)));

Texture設置成Normal Map時,Unity會根據不同平台對紋理進行壓縮。而UnpackNormal函數會根據不同的格式重新解壓紋。