[英]How to render the normal map in Unity and Three.js with shader respectively?
我想在Three.js和Unity中渲染法線貼圖,但是我發現最終輸出是不同的。
Unity中使用的着色器如下:
Shader "Unlit/normal"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal:NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.color.xyz = mul(_Object2World, v.normal)*0.5+0.5 ;
o.color.w = 1.0f;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return i.color; //output normal
}
ENDCG
}
}
}
在three.js中,我使用MeshNormalMaterial渲染法線貼圖,但是它與Unity中的渲染不同。
我認為問題在於您正在使用unity_ObjectToWorld矩陣來變換法線,該矩陣還包括比例尺。 考慮到Unity版本看起來暗了多少,這可能導致法線縮放或剪切。 我的建議是改為使用UnityCG.cginc中包含的內置函數:
o.color.rgb = UnityObjectToWorldNormal(v.normal);
理想情況下,也應該在片段函數中對法線進行規范化,因為硬件插值器無法保證您的值保持規范化。 另外,您的着色器中還包含很多不必要的東西-您可以刪除以下幾行:
#pragma multi_compile_fog
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
sampler2D _MainTex;
float4 _MainTex_ST;
編輯:還請注意,MeshNormalMaterial似乎在視圖空間而非世界空間中渲染法線。 這是將世界法線轉換為視圖空間的方式:
float3 viewNormal = normalize(mul((float3x3)UNITY_MATRIX_V, worldNormal));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.