<form id="dlljd"></form>
        <address id="dlljd"><address id="dlljd"><listing id="dlljd"></listing></address></address>

        <em id="dlljd"><form id="dlljd"></form></em>

          <address id="dlljd"></address>
            <noframes id="dlljd">

              聯系我們 - 廣告服務 - 聯系電話:
              您的當前位置: > 關注 > > 正文

              世界報道:世界空間中的著色器 從對象空間到世界空間的轉換

              來源:CSDN 時間:2023-02-02 09:45:36

              在《在著色器中調試》章節中提到,頂點輸入參數使用語義詞 POSITION 指定對象的坐標,即本地對象(模型)的網格空間坐標,對象空間(對象的坐標系統)是特定于每個游戲對象的,然而,所有的游戲對象會被轉換到一個共同的坐標系中(世界空間)。

              如果一個對象被直接放入世界空間中,游戲對象會通過轉換組件直接將對象的坐標轉成世界坐標。你可以在 Scene 視圖或者 Hierarchy 視圖中選中一個對象,然后在 Inspector 視圖中查看 Transform 組件。在 Transform 組件中包括 Position、Rotation 和 Scale 屬性,這個組件用來指定從本地坐標到世界坐標的頂點轉換(如果一個游戲對象擁有父級對象,那么轉換組件只轉換父級對象的坐標)。在《Vertex Transformations》章節中,我們將討論頂點的轉換、旋轉、縮放以及 4 x 4 矩陣組合變換的細節。

              回到我們的例子中:從對象空間到世界空間的轉換是通過 4 x 4 矩陣來轉換的,也叫“模型矩陣”,這個矩陣在 Unity 中通過 uniform 參數 _Object2World 已經聲明了:


              (資料圖)

              Shader "Custom/World Space"

              { SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag //uniform flaot4*4 Object3World //automatic definition of a Unity-specific uniform parameter 自動定義統一值是unity的一個特性 struct vertexOutput  { float4 pos: SV_POSITION; float4 position_in_world_space : TEXCOORD0; }; vertexOutput vert(float4 vertex:POSITION)  { vertexOutput output; output.pos = mul(UNITY_MATRIX_MVP,vertex); output.position_in_world_space = mul(_Object2World,vertex);//物體坐標轉化為世界坐標 return output; } float4 frag(vertexOutput input) :COLOR { float dist = distance(input.position_in_world_space,float4(0.0,0.0,0.0,1.0));  //計算片段位置與原點距離(第四個坐標永遠是1) if (dist < 5.0) { return float4(0.0, 1.0, 0.0, 1.0);   //接近 } else return float4(0.3,0.3,0.3,1.0);//遠離原點 } ENDCG } }

              }

              更多的 Unity Uniforms

              在 Unity 中,定義了幾個和 _Object2World 一樣的 float4x4  矩陣,下面是在系列教程中使用的 uniforms 簡短列表:

              uniform float4 _Time, _SinTime, _CosTime; // time valuesuniform float4 _ProjectionParams;// x = 1 or -1 (-1 if projection is flipped)// y = near plane; z = far plane; w = 1/far planeuniform float4 _ScreenParams; // x = width; y = height; z = 1 + 1/width; w = 1 + 1/heightuniform float4 unity_Scale; // w = 1/scale; see _World2Objectuniform float3 _WorldSpaceCameraPos;uniform float4x4 _Object2World; // model matrixuniform float4x4 _World2Object; // inverse model matrix // (all but the bottom-right element have to be scaled // with unity_Scale.w if scaling is important) uniform float4 _LightPositionRange; // xyz = pos, w = 1/rangeuniform float4 _WorldSpaceLightPos0; // position or direction of light sourceuniform float4x4 UNITY_MATRIX_MVP; // model view projection matrix uniform float4x4 UNITY_MATRIX_MV; // model view matrixuniform float4x4 UNITY_MATRIX_V; // view matrixuniform float4x4 UNITY_MATRIX_P; // projection matrixuniform float4x4 UNITY_MATRIX_VP; // view projection matrixuniform float4x4 UNITY_MATRIX_T_MV; // transpose of model view matrixuniform float4x4 UNITY_MATRIX_IT_MV; // transpose of the inverse model view matrixuniform float4x4 UNITY_MATRIX_TEXTURE0; // texture matrixuniform float4x4 UNITY_MATRIX_TEXTURE1; // texture matrixuniform float4x4 UNITY_MATRIX_TEXTURE2; // texture matrixuniform float4x4 UNITY_MATRIX_TEXTURE3; // texture matrixuniform float4 UNITY_LIGHTMODEL_AMBIENT; // ambient color

              用戶指定 Uniforms:著色器屬性

              還有一個更重要的 uniform  參數:用戶自定義的 uniforms。實際上,這是 Unity 的屬性,你可以認為他們是著色器的用戶自定義 uniform 參數。通常一個著色器不帶參數只能由編寫的程序員在一些特定的程序中使用,但是如果一個著色器擁有參數并且還帶有描述性的說明,那么這個著色器就可以被其他人使用,另外,如果你打算出售你的著色器,為著色器的提供參數會大大增加它的價值。

              因為在 Unity 的 ShaderLab  中使用《description of shader properties 》非常不錯,通過下面的例子我們來了解如何使用著色器屬性,首先,我們聲明一個屬性,然后我們再定義一個與屬性名稱相同、類型相同的 uniforms 。

              Shader "Cg shading in world space" {   Properties    {      _Point ("a point in world space", Vector) = (0., 0., 0., 1.0)      _DistanceNear ("threshold distance", Float) = 5.0      _ColorNear ("color near to point", Color) = (0.0, 1.0, 0.0, 1.0)      _ColorFar ("color far from point", Color) = (0.3, 0.3, 0.3, 1.0)   }    SubShader    {      Pass       {         CGPROGRAM          #pragma vertex vert           #pragma fragment frag           #include "UnityCG.cginc"          // defines _Object2World and _World2Object         // uniforms corresponding to properties         uniform float4 _Point;         uniform float _DistanceNear;         uniform float4 _ColorNear;         uniform float4 _ColorFar;          struct vertexInput          {            float4 vertex : POSITION;         };         struct vertexOutput          {            float4 pos : SV_POSITION;            float4 position_in_world_space : TEXCOORD0;         };          vertexOutput vert(vertexInput input)          {            vertexOutput output;              output.pos =  mul(UNITY_MATRIX_MVP, input.vertex);            output.position_in_world_space = mul(_Object2World, input.vertex);            return output;         }          float4 frag(vertexOutput input) : COLOR          {            float dist = distance(input.position_in_world_space, _Point);            // computes the distance between the fragment position             // and the position _Point.            if (dist < _DistanceNear)            {               return _ColorNear;             }            else            {               return _ColorFar;             }         }         ENDCG        }   }}

              使用 sharedMaterial 我們可以改變所有使用了這個材質的對象的參數,如果你只希望改變一個并使用了這個材質的對象的參數,那么你應該使用 material 。假如你設置 _Point 屬性為另一個對象的位置信息,這樣你只需要在 Unity 中移動這個對象就可以查看效果了,你可以復制/粘貼 下面的代碼到一個 C# 腳本中:

              using UnityEngine;using System.Collections;[ExecuteInEditMode]public class NewBehaviourScript : MonoBehaviour {public GameObject other;void Update(){if(other != null){GetComponent().sharedMaterial.SetVector("_Point", other.transform.position);}}}

              然后我們只需要移動另一個對象(Sphere)就可以看到(Cube)顏色的變化,當小球離原點近時,如圖:

              當小球離原點遠時,如圖:

              責任編輯:

              標簽:

              相關推薦:

              精彩放送:

              新聞聚焦
              Top 中文字幕在线观看亚洲日韩