最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

編寫 Unity Shader 的時候,語義 POSITION 和 SV_POSITION 的區(qū)別?

2023-05-30 14:55 作者:游戲開發(fā)RAIN  | 我要投稿

在編寫 Unity Shader 的時候,經(jīng)常會遇到語義 POSITION 和 SV_POSITION,它們都是表示頂點(diǎn)位置的語義。但是,它們之間有著一些微妙的區(qū)別。本文將詳細(xì)介紹這兩個語義的區(qū)別,并給出相應(yīng)的示例。

一、POSITION

首先,我們來看一下 POSITION。在 Unity Shader 中,POSITION 表示的是頂點(diǎn)在模型空間中的位置。也就是說,這個語義表示的是從模型空間到世界空間的變換后的頂點(diǎn)位置。在頂點(diǎn)著色器中,我們可以使用 float4 類型的 POSITION 變量來表示頂點(diǎn)的位置:

void vert(inout appdata_full v, out Input o) { ? ?// 計算頂點(diǎn)在模型空間中的位置 ? ?float4 pos = mul(unity_ObjectToWorld, v.vertex); ? ? ? ?// 將頂點(diǎn)位置賦值給 POSITION ? ?o.vertex = pos; ? ?o.uv = TRANSFORM_TEX(v.uv, _MainTex); }


在上面的代碼中,我們首先使用 unity_ObjectToWorld 矩陣將頂點(diǎn)從模型空間轉(zhuǎn)換到世界空間,然后將變換后的頂點(diǎn)位置賦值給了 POSITION。這個 POSITION 變量將會被傳遞到像素著色器中,用來計算最終的顏色。

二、SV_POSITION

接下來,我們來看一下 SV_POSITION。在 Unity Shader 中,SV_POSITION 表示的是頂點(diǎn)在屏幕空間中的位置。也就是說,這個語義表示的是從世界空間到屏幕空間的變換后的頂點(diǎn)位置。在頂點(diǎn)著色器中,我們可以使用 float4 類型的 SV_POSITION 變量來表示頂點(diǎn)在屏幕空間中的位置:

void vert(inout appdata_full v, out Input o) { ? ?// 計算頂點(diǎn)在模型空間中的位置 ? ?float4 pos = mul(unity_ObjectToWorld, v.vertex); ? ? ? ?// 計算頂點(diǎn)在屏幕空間中的位置 ? ?o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); ? ? ? ?// 將頂點(diǎn)位置賦值給 SV_POSITION ? ?o.vertex = ComputeGrabScreenPos(o.vertex); ? ?o.uv = TRANSFORM_TEX(v.uv, _MainTex); }


在上面的代碼中,我們首先使用 unity_ObjectToWorld 矩陣將頂點(diǎn)從模型空間轉(zhuǎn)換到世界空間,然后使用 UNITY_MATRIX_MVP 矩陣將頂點(diǎn)從世界空間轉(zhuǎn)換到屏幕空間。最后,我們將變換后的頂點(diǎn)位置賦值給了 SV_POSITION。這個 SV_POSITION 變量將會被傳遞到像素著色器中,用來計算最終的顏色。

三、POSITION 和 SV_POSITION 的區(qū)別

從上面的示例中,我們可以看出 POSITION 和 SV_POSITION 的區(qū)別。具體來說,它們的區(qū)別如下:

  1. POSITION 表示的是頂點(diǎn)在模型空間中的位置,而 SV_POSITION 表示的是頂點(diǎn)在屏幕空間中的位置。

  2. POSITION 變量在頂點(diǎn)著色器中使用,用來計算最終的顏色,而 SV_POSITION 變量在像素著色器中使用,用來計算最終的顏色。

  3. POSITION 變量的值是從模型空間到世界空間的變換后的頂點(diǎn)位置,而 SV_POSITION 變量的值是從世界空間到屏幕空間的變換后的頂點(diǎn)位置。

四、示例

下面我們來看一個示例,來更好地理解 POSITION 和 SV_POSITION 的區(qū)別。假設(shè)我們有一個簡單的立方體模型,我們需要將其繪制到屏幕上,并且在每個面上顯示不同的顏色。我們可以使用以下的 Shader:

Shader "Custom/ColorCube" { ? ?Properties { ? ? ? ?_MainTex ("Texture", 2D) = "white" {} ? ?} ? ?SubShader { ? ? ? ?Tags { "RenderType"="Opaque" } ? ? ? ?CGPROGRAM ? ? ? ?#pragma surface surf Standard ? ? ? ?struct Input { ? ? ? ? ? ?float2 uv_MainTex; ? ? ? ? ? ?float4 worldPos; ? ? ? ?}; ? ? ? ?sampler2D _MainTex; ? ? ? ?void surf (Input IN, inout SurfaceOutputStandard o) { ? ? ? ? ? ?// 計算頂點(diǎn)在模型空間中的位置 ? ? ? ? ? ?float4 pos = IN.worldPos; ? ? ? ? ? ?// 將頂點(diǎn)位置賦值給 POSITION ? ? ? ? ? ?o.Normal = pos.xyz; ? ? ? ? ? ?o.Albedo = pos.xyz; ? ? ? ? ? ?o.Alpha = 1.0; ? ? ? ?} ? ? ? ?ENDCG ? ?} ? ?FallBack "Diffuse" }


在上面的代碼中,我們使用了 worldPos 變量來傳遞頂點(diǎn)在世界空間中的位置。在 surf 函數(shù)中,我們將 worldPos 賦值給了 POSITION,這樣就可以在像素著色器中使用這個變量了。

接下來,我們需要修改一下頂點(diǎn)著色器,來計算頂點(diǎn)在屏幕空間中的位置,并將其賦值給 SV_POSITION 變量。修改后的代碼如下:


void vert (inout appdata_full v) { ? ?// 計算頂點(diǎn)在模型空間中的位置 ? ?float4 pos = v.vertex; ? ?// 將頂點(diǎn)位置賦值給 POSITION ? ?v.normal.xyz = pos.xyz; ? ?v.tangent.xyz = pos.xyz; ? ?v.texcoord.xy = TRANSFORM_TEX(v.texcoord, _MainTex); ? ?// 計算頂點(diǎn)在屏幕空間中的位置 ? ?v.vertex = mul(UNITY_MATRIX_MVP, v.vertex); ? ?// 將頂點(diǎn)位置賦值給 SV_POSITION ? ?ComputeGrabScreenPos(v.vertex); }


在上面的代碼中,我們首先計算了頂點(diǎn)在模型空間中的位置,然后將其賦值給了 normal 和 tangent 變量。這里使用 normal 和 tangent 變量來傳遞頂點(diǎn)的位置是因為 Surface Shader 中沒有 POSITION 變量。接著,我們使用 UNITY_MATRIX_MVP 矩陣將頂點(diǎn)從世界空間轉(zhuǎn)換到屏幕空間,并將變換后的頂點(diǎn)位置賦值給了 SV_POSITION 變量。

最后,我們需要在像素著色器中使用 SV_POSITION 變量來計算最終的顏色。修改后的代碼如下:


void surf (Input IN, inout SurfaceOutputStandard o) { ? ?// 計算世界空間中的頂點(diǎn)位置 ? ?float3 worldPos = mul(unity_ObjectToWorld, IN.worldPos).xyz; ? ?// 計算頂點(diǎn)在屏幕空間中的位置 ? ?float4 screenPos = ComputeGrabScreenPos(IN.worldPos); ? ?// 根據(jù)屏幕空間中的位置來計算顏色 ? ?if (screenPos.x < 0.5) { ? ? ? ?o.Albedo = float3(1, 0, 0); ? ?} else if (screenPos.x < 1.0) { ? ? ? ?o.Albedo = float3(0, 1, 0); ? ?} else { ? ? ? ?o.Albedo = float3(0, 0, 1); ? ?} ? ?o.Normal = worldPos; ? ?o.Alpha = 1.0; }


在上面的代碼中,我們首先使用 unity_ObjectToWorld 矩陣將頂點(diǎn)從模型空間轉(zhuǎn)換到世界空間,然后計算頂點(diǎn)在屏幕空間中的位置,并根據(jù)屏幕空間中的位置來計算顏色。這里我們將 x 坐標(biāo)小于 0.5 的面設(shè)置為紅色,將 x 坐標(biāo)在 0.5 到 1.0 之間的面設(shè)置為綠色,將 x 坐標(biāo)大于 1.0 的面設(shè)置為藍(lán)色。

五、總結(jié)

在編寫 Unity Shader 的時候,POSITION 和 SV_POSITION 都是表示頂點(diǎn)位置的語義。它們之間的區(qū)別在于,POSITION 表示的是頂點(diǎn)在模型空間中的位置,而 SV_POSITION 表示的是頂點(diǎn)在屏幕空間中的位置。在頂點(diǎn)著色器中,我們可以使用 POSITION 變量來表示頂點(diǎn)的位置,在像素著色器中,我們可以使用 SV_POSITION 變量來表示頂點(diǎn)的位置。在實(shí)際應(yīng)用中,我們需要根據(jù)具體的需求來選擇使用哪個語義。


編寫 Unity Shader 的時候,語義 POSITION 和 SV_POSITION 的區(qū)別?的評論 (共 條)

分享到微博請遵守國家法律
连州市| 延边| 白朗县| 枣庄市| 易门县| 阳山县| 刚察县| 当阳市| 方城县| 平山县| 高平市| 区。| 泗水县| 梁平县| 成都市| 拉萨市| 汉沽区| 藁城市| 历史| 新津县| 清远市| 泗阳县| 南江县| 泰来县| 拜城县| 杨浦区| 罗源县| 临沭县| 保山市| 固镇县| 彩票| 河北省| 汉寿县| 嘉鱼县| 佛坪县| 清镇市| 玉溪市| 尤溪县| 永泰县| 新沂市| 抚宁县|