国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Unity地面交互效果——3、曲面細分基礎知識

這篇具有很好參考價值的文章主要介紹了Unity地面交互效果——3、曲面細分基礎知識。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

回到目錄
??大家好,我是阿趙。
??之前介紹了使用動態(tài)法線貼圖混合的方式模擬軌跡的凹凸感,這次來講一下更真實的凹凸感制作。不過在說這個內(nèi)容之前,這一篇先要介紹一下曲面細分著色器(Tessellation Shader)的用法。

一、為什么要做曲面細分

??之前通過法線貼圖模擬了凹凸的感覺:
Unity地面交互效果——3、曲面細分基礎知識,Unity引擎Shader效果,unity,游戲引擎,Tessellation,Shader,地面交互

??法線貼圖不會真的產(chǎn)生凹凸,它只是改變了這個平面上面的法線方向。所以,只有通過光照模型,通過法線方向和燈光方向進行點乘,才會計算出不同的光照角度,讓我們產(chǎn)生一定的凹凸感覺。
??但如果想做到這樣的效果,法線貼圖是不行的:
Unity地面交互效果——3、曲面細分基礎知識,Unity引擎Shader效果,unity,游戲引擎,Tessellation,Shader,地面交互

??這種效果,球是真的陷進去地面了。很明顯,這些都是需要偏移頂點讓網(wǎng)格產(chǎn)生真實的變形,才能做到。
??不過這里有一個問題,如果地面的網(wǎng)格面數(shù)并不是很高,那么就算我們有能力去偏移頂點,也產(chǎn)生不了這樣好的效果。
??比如一般的地面網(wǎng)格的面數(shù)都很低,只有這樣的水平:
Unity地面交互效果——3、曲面細分基礎知識,Unity引擎Shader效果,unity,游戲引擎,Tessellation,Shader,地面交互

??這個時候,球所在的地方,根本就沒有頂點,所以也偏移不了。就算再稍微多一點面,這樣的地面網(wǎng)格面數(shù)算比較高了,仍然產(chǎn)生不了很好的凹凸效果:
Unity地面交互效果——3、曲面細分基礎知識,Unity引擎Shader效果,unity,游戲引擎,Tessellation,Shader,地面交互

??所以這里有一個很嚴重的問題,我們難道需要用幾十萬甚至幾百萬面,去做一個地面的模型,才能產(chǎn)生真實的凹凸感嗎?
??這是不可能的,實際的情況是:
Unity地面交互效果——3、曲面細分基礎知識,Unity引擎Shader效果,unity,游戲引擎,Tessellation,Shader,地面交互

??在需要到很精確的頂點控制的一個小局部,才需要把面數(shù)變高,其他的地方,面數(shù)很是很低的。具體可以看看這個視頻:

Unity引擎動態(tài)曲面細分

??而這里用到的局部增加面數(shù)的技術,就是曲面細分(Tessellation)了。

二、曲面細分的過程

??在Unity里面寫頂點片段著色器的Shader,我們一般只會注意到需要些Vertex頂點程序,和fragment片段程序,因為在大多數(shù)情況下,其他的渲染管線流程都不是我們可以控制的,而我們能控制頂點程序改變模型的形狀,控制片段程序來改變模型的顏色。
??但在頂點程序和片段程序中間,其實還有一個曲面細分(tessellate)的過程,這個過程有2個程序是我們可以控制的
1、hullProgram
??這個程序會接受每個多邊形各個頂點的信息,記錄下來,然后通過指定一個Patch Constant Function,去設置細分的數(shù)量,這個過程是針對多邊形的每一條邊,還有多邊形的內(nèi)部,分別設置拆分的數(shù)量的。
2、domainProgram
??在前面的hullProgram里面,其實只是設置了頂點信息和拆分數(shù)量,并沒有真正的生成新的網(wǎng)格。而在這個domainProgram里面,拆分后的頂點信息已經(jīng)產(chǎn)生了,所以可以對拆分后的頂線進行操作,可以計算他們的位置、法線、uv等。
??為了避免難以理解,也不說太多,只要知道,需要做曲面細分的時候,需要添加2個程序過程,一個過程設置了拆分的數(shù)量和其他參數(shù),另外一個過程就得到了頂點,可以進行實際操作,這樣就行了。

三、曲面細分在Unity引擎的實現(xiàn)

1、Surface類型著色器

??Surface類型的Shader提供了很多Unity封裝好的方法,也包括提供了對應曲面細分著色器的方法。
使用很簡單:
1.#include “Tessellation.cginc”
2.指定曲面細分的方法:tessellate:tessFunction
3.指定target 4.6

Unity地面交互效果——3、曲面細分基礎知識,Unity引擎Shader效果,unity,游戲引擎,Tessellation,Shader,地面交互

看到這里有target 4.6的聲明了,沒錯Unity官方的說明也是這樣的:

When you use tessellation, the shader is automatically compiled into
the Shader Model 4.6 target, which prevents support for running on
older graphics targets.

??這里著重說一下曲面細分方法。
??由于Surface的曲面細分方法是Unity封裝好的,所以我們不需要走正常的渲染流程,不需要指定hullProgram、Patch Constant Function和domainProgram,只需要指定一個tessellate處理方法。這個方法實際是返回一個曲面細分的值,來決定某個面具體要細分成多少個網(wǎng)格。
而在Unity提供的方法里面,對于怎樣細分曲面,提供了3種選擇:

1.Fixed固定數(shù)量細分

??這種方式細分,在tessFunction里面直接返回一個數(shù)值,然后全部面就按照統(tǒng)一的數(shù)值去細分。
Unity地面交互效果——3、曲面細分基礎知識,Unity引擎Shader效果,unity,游戲引擎,Tessellation,Shader,地面交互

unity官方文檔里面的例子是這樣

Shader "Tessellation Sample" {
        Properties {
            _Tess ("Tessellation", Range(1,32)) = 4
            _MainTex ("Base (RGB)", 2D) = "white" {}
            _DispTex ("Disp Texture", 2D) = "gray" {}
            _NormalMap ("Normalmap", 2D) = "bump" {}
            _Displacement ("Displacement", Range(0, 1.0)) = 0.3
            _Color ("Color", color) = (1,1,1,0)
            _SpecColor ("Spec color", color) = (0.5,0.5,0.5,0.5)
        }
        SubShader {
            Tags { "RenderType"="Opaque" }
            LOD 300
            
            CGPROGRAM
            #pragma surface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessFixed nolightmap
            #pragma target 4.6

            struct appdata {
                float4 vertex : POSITION;
                float4 tangent : TANGENT;
                float3 normal : NORMAL;
                float2 texcoord : TEXCOORD0;
            };

            float _Tess;

            float4 tessFixed()
            {
                return _Tess;
            }

            sampler2D _DispTex;
            float _Displacement;

            void disp (inout appdata v)
            {
                float d = tex2Dlod(_DispTex, float4(v.texcoord.xy,0,0)).r * _Displacement;
                v.vertex.xyz += v.normal * d;
            }

            struct Input {
                float2 uv_MainTex;
            };

            sampler2D _MainTex;
            sampler2D _NormalMap;
            fixed4 _Color;

            void surf (Input IN, inout SurfaceOutput o) {
                half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
                o.Albedo = c.rgb;
                o.Specular = 0.2;
                o.Gloss = 1.0;
                o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));
            }
            ENDCG
        }
        FallBack "Diffuse"
    }

其中曲面細分方法是直接返回了一個指定的值

float4 tessFixed()
{
    return _Tess;
}

2.根據(jù)距離細分

??這里的距離,指的是和攝像機的距離。根據(jù)離攝像機不同的距離,設置一個范圍來細分
Unity地面交互效果——3、曲面細分基礎知識,Unity引擎Shader效果,unity,游戲引擎,Tessellation,Shader,地面交互

unity官方文檔里面的例子是這樣:

   Shader "Tessellation Sample" {
        Properties {
            _Tess ("Tessellation", Range(1,32)) = 4
            _MainTex ("Base (RGB)", 2D) = "white" {}
            _DispTex ("Disp Texture", 2D) = "gray" {}
            _NormalMap ("Normalmap", 2D) = "bump" {}
            _Displacement ("Displacement", Range(0, 1.0)) = 0.3
            _Color ("Color", color) = (1,1,1,0)
            _SpecColor ("Spec color", color) = (0.5,0.5,0.5,0.5)
        }
        SubShader {
            Tags { "RenderType"="Opaque" }
            LOD 300
            
            CGPROGRAM
            #pragma surface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessDistance nolightmap
            #pragma target 4.6
            #include "Tessellation.cginc"

            struct appdata {
                float4 vertex : POSITION;
                float4 tangent : TANGENT;
                float3 normal : NORMAL;
                float2 texcoord : TEXCOORD0;
            };

            float _Tess;

            float4 tessDistance (appdata v0, appdata v1, appdata v2) {
                float minDist = 10.0;
                float maxDist = 25.0;
                return UnityDistanceBasedTess(v0.vertex, v1.vertex, v2.vertex, minDist, maxDist, _Tess);
            }

            sampler2D _DispTex;
            float _Displacement;

            void disp (inout appdata v)
            {
                float d = tex2Dlod(_DispTex, float4(v.texcoord.xy,0,0)).r * _Displacement;
                v.vertex.xyz += v.normal * d;
            }

            struct Input {
                float2 uv_MainTex;
            };

            sampler2D _MainTex;
            sampler2D _NormalMap;
            fixed4 _Color;

            void surf (Input IN, inout SurfaceOutput o) {
                half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
                o.Albedo = c.rgb;
                o.Specular = 0.2;
                o.Gloss = 1.0;
                o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));
            }
            ENDCG
        }
        FallBack "Diffuse"
    }

其中曲面細分方法是傳入了最小距離、最大距離和一個控制值

float4 tessDistance (appdata v0, appdata v1, appdata v2) {
	 float minDist = 10.0;
	float maxDist = 25.0;
	return UnityDistanceBasedTess(v0.vertex, v1.vertex, v2.vertex, minDist, maxDist, _Tess);
}

UnityDistanceBasedTess就是Unity提供的根據(jù)距離計算細分值的方法。

3.根據(jù)邊的長度細分

??這個根據(jù)邊的長度,指的是多邊形的邊,在屏幕里面渲染的大小。
Unity地面交互效果——3、曲面細分基礎知識,Unity引擎Shader效果,unity,游戲引擎,Tessellation,Shader,地面交互

??所以從左圖可以看出,越近屏幕的邊,渲染的長度越大,所以細分得越多,而離屏幕越遠的邊,渲染的長度越小,細分得也越少。
??從右圖可以看出,同一個模型,如果通過縮放把邊拉長,它的細分程度也會隨著模型拉長而變大,最后保持著一個比較固定的細分密度。
unity官方文檔里面的例子是這樣的:

    Shader "Tessellation Sample" {
        Properties {
            _EdgeLength ("Edge length", Range(2,50)) = 15
            _MainTex ("Base (RGB)", 2D) = "white" {}
            _DispTex ("Disp Texture", 2D) = "gray" {}
            _NormalMap ("Normalmap", 2D) = "bump" {}
            _Displacement ("Displacement", Range(0, 1.0)) = 0.3
            _Color ("Color", color) = (1,1,1,0)
            _SpecColor ("Spec color", color) = (0.5,0.5,0.5,0.5)
        }
        SubShader {
            Tags { "RenderType"="Opaque" }
            LOD 300
            
            CGPROGRAM
            #pragma surface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessEdge nolightmap
            #pragma target 4.6
            #include "Tessellation.cginc"

            struct appdata {
                float4 vertex : POSITION;
                float4 tangent : TANGENT;
                float3 normal : NORMAL;
                float2 texcoord : TEXCOORD0;
            };

            float _EdgeLength;

            float4 tessEdge (appdata v0, appdata v1, appdata v2)
            {
                return UnityEdgeLengthBasedTess (v0.vertex, v1.vertex, v2.vertex, _EdgeLength);
            }

            sampler2D _DispTex;
            float _Displacement;

            void disp (inout appdata v)
            {
                float d = tex2Dlod(_DispTex, float4(v.texcoord.xy,0,0)).r * _Displacement;
                v.vertex.xyz += v.normal * d;
            }

            struct Input {
                float2 uv_MainTex;
            };

            sampler2D _MainTex;
            sampler2D _NormalMap;
            fixed4 _Color;

            void surf (Input IN, inout SurfaceOutput o) {
                half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
                o.Albedo = c.rgb;
                o.Specular = 0.2;
                o.Gloss = 1.0;
                o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));
            }
            ENDCG
        }
        FallBack "Diffuse"
}

其中曲面細分程序傳入一個指定的值,需要注意的是,這個值越小,細分得越多

float4 tessEdge (appdata v0, appdata v1, appdata v2)
{
	return UnityEdgeLengthBasedTess (v0.vertex, v1.vertex, v2.vertex, _EdgeLength);
}

UnityEdgeLengthBasedTess 是Unity提供的根據(jù)邊長細分的方法

2、頂點片段程序?qū)崿F(xiàn)曲面細分

??如果不使用Surface類型的Shader,而用傳統(tǒng)的頂點片段程序著色器,實現(xiàn)曲面細分就只有一種方式,就是正常的添加hullProgram、Patch Constant Function和domainProgram,然后逐條邊和多邊形內(nèi)部指定細分的數(shù)量。我這里提供一個最簡單的Shader來說明一下寫法:

Shader "azhao/TessVF"
{
    Properties
    {
		_MainTex("Texture", 2D) = "white" {}
		_Color("Color", Color) = (1,1,1,1)
		_EditFactor("edgeFactor", Float) = 15
		_InsideFactor("insideFactor",FLoat)  =15

    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
			//在正常的vertex和fragment之間還需要hull和domain,所以在這里加上聲明
			#pragma hull hullProgram
			#pragma domain domainProgram
            #pragma fragment frag


            #include "UnityCG.cginc"
			sampler2D _MainTex;
			float4 _MainTex_ST;
			fixed4 _Color;
			uniform float _EditFactor;
			uniform float _InsideFactor;
			struct a2v
			{
				float4 pos	: POSITION;
				float2 uv  : TEXCOORD0;
			};

			struct v2t
			{
				float4 worldPos	: TEXCOORD0;
				float2 uv  : TEXCOORD1;
			};
			struct t2f
			{
				float4 clipPos:SV_POSITION;
				float2 uv: TEXCOORD0;
				float4 worldPos:TEXCOORD1;
				
			};

			struct TessOut
			{
				float2 uv  : TEXCOORD0;
				float4 worldPos	: TEXCOORD1;
				
			};
			struct TessParam
			{
				float EdgeTess[3]	: SV_TessFactor;//各邊細分數(shù)
				float InsideTess : SV_InsideTessFactor;//內(nèi)部點細分數(shù)
			};

			v2t vert(a2v i)
			{
				v2t o;
				o.worldPos = mul(unity_ObjectToWorld,i.pos);
				o.uv = i.uv;
				return o;
			}
			//在hullProgram之前必須設置這些參數(shù),不然會報錯
			[domain("tri")]//圖元類型,可選類型有 "tri", "quad", "isoline"
			[partitioning("integer")]//曲面細分的過渡方式是整數(shù)還是小數(shù)
			[outputtopology("triangle_cw")]//三角面正方向是順時針還是逆時針
			[outputcontrolpoints(3)]//輸出的控制點數(shù)
			[patchconstantfunc("ConstantHS")]//對應之前的細分因子配置階段的方法名
			[maxtessfactor(64.0)]//最大可能的細分段數(shù)

			//vert頂點程序之后調(diào)用,計算細分前的三角形頂點信息
			TessOut hullProgram(InputPatch<v2t, 3> i, uint idx : SV_OutputControlPointID)
			{
				TessOut o;
				o.worldPos = i[idx].worldPos;
				o.uv = i[idx].uv;
				return o;
			}

			//指定每個邊的細分段數(shù)和內(nèi)部細分段數(shù)
			TessParam ConstantHS(InputPatch<v2t, 3> i, uint id : SV_PrimitiveID)
			{
				TessParam o;
				o.EdgeTess[0] = _EditFactor;
				o.EdgeTess[1] = _EditFactor;
				o.EdgeTess[2] = _EditFactor;
				o.InsideTess = _InsideFactor;
				return o;
			}

			//在domainProgram前必須設置domain參數(shù),不然會報錯
			[domain("tri")]
			//細分之后,把信息傳到frag片段程序
			t2f domainProgram(TessParam tessParam, float3 bary : SV_DomainLocation, const OutputPatch<TessOut, 3> i)
			{
				t2f o;				
				//線性轉(zhuǎn)換

				float2 uv = i[0].uv * bary.x + i[1].uv * bary.y + i[2].uv * bary.z;
				o.uv = uv;
				float4 worldPos = i[0].worldPos * bary.x + i[1].worldPos * bary.y + i[2].worldPos * bary.z;
				o.worldPos = worldPos;
				o.clipPos = UnityWorldToClipPos(worldPos);
				return o;
			}
            fixed4 frag (t2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv)*_Color;

				return col;
            }
            ENDCG
        }
    }
}

需要注意的地方是:
1.聲明處理程序:

#pragma hull hullProgram
#pragma domain domainProgram

2.在hullProgram之前必須設置這些參數(shù),不然會報錯

[domain("tri")]//圖元類型,可選類型有 "tri", "quad", "isoline"
[partitioning("integer")]//曲面細分的過渡方式是整數(shù)還是小數(shù)
[outputtopology("triangle_cw")]//三角面正方向是順時針還是逆時針
[outputcontrolpoints(3)]//輸出的控制點數(shù)
[patchconstantfunc("ConstantHS")]//對應之前的細分因子配置階段的方法名
[maxtessfactor(64.0)]//最大可能的細分段數(shù)

3.domainProgram前必須設置domain參數(shù),不然會報錯

[domain("tri")]

四、根據(jù)范圍做局部曲面細分

??已經(jīng)介紹完怎樣使用曲面細分了,接下來就是要實現(xiàn)文章一開始說的,根據(jù)指定的中心點和范圍,做局部的曲面細分。

1、在頂點片段著色器實現(xiàn)局部細分

??由于使用頂點片段著色器做曲面細分,是可以直接設置每個多邊形的邊和內(nèi)部的細分數(shù)量,所以要實現(xiàn)局部細分也就非常簡單了,思路是:
1.獲得中心點坐標和范圍半徑
2.在著色器取得當前頂點的世界坐標,然后判斷是否在中心點的半徑范圍內(nèi)
3.用一個smoothStep做一個邊緣范圍過渡,作為細分強度
4.根據(jù)計算出的細分強度,設置最終的細分值。

寫成代碼大概就是這樣:

Shader "azhao/GroundTessVF"
{
    Properties
    {
		_MainTex("Texture", 2D) = "white" {}
		_Color("Color", Color) = (1,1,1,1)
		_centerPos("CenterPos", Vector) = (0,0,0,0)
		_minVal("minVal", Float) = 0
		_maxVal("maxVal", Float) = 10
		_factor("factor", Float) = 15
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
			//在正常的vertex和fragment之間還需要hull和domain,所以在這里加上聲明
			#pragma hull hullProgram
			#pragma domain domainProgram
            #pragma fragment frag


            #include "UnityCG.cginc"
			sampler2D _MainTex;
			float4 _MainTex_ST;
			fixed4 _Color;
			uniform float _minVal;
			uniform float _maxVal;
			uniform float3 _centerPos;
			uniform float _factor;
			struct a2v
			{
				float4 pos	: POSITION;
				float2 uv  : TEXCOORD0;
			};

			struct v2t
			{
				float4 worldPos	: TEXCOORD0;
				float2 uv  : TEXCOORD1;
			};
			struct t2f
			{
				float4 clipPos	       : SV_POSITION;
				float2 uv     : TEXCOORD0;
				float4 worldPos            : TEXCOORD1;
				
			};

			struct TessOut
			{
				float2 uv  : TEXCOORD0;
				float4 worldPos	: TEXCOORD1;
				
			};
			struct TessParam
			{
				float EdgeTess[3]	: SV_TessFactor;//各邊細分數(shù)
				float InsideTess : SV_InsideTessFactor;//內(nèi)部點細分數(shù)
			};

			
			v2t vert(a2v i)
			{
				v2t o;
				o.worldPos = mul(unity_ObjectToWorld,i.pos);
				o.uv = i.uv;
				return o;
			}
			//在hullProgram之前必須設置這些參數(shù),不然會報錯
			[domain("tri")]//圖元類型,可選類型有 "tri", "quad", "isoline"
			[partitioning("integer")]//曲面細分的過渡方式是整數(shù)還是小數(shù)
			[outputtopology("triangle_cw")]//三角面正方向是順時針還是逆時針
			[outputcontrolpoints(3)]//輸出的控制點數(shù)
			[patchconstantfunc("ConstantHS")]//對應之前的細分因子配置階段的方法名
			[maxtessfactor(64.0)]//最大可能的細分段數(shù)

			//vert頂點程序之后調(diào)用,計算細分前的三角形頂點信息
			TessOut hullProgram(InputPatch<v2t, 3> i, uint idx : SV_OutputControlPointID)
			{
				TessOut o;
				o.worldPos = i[idx].worldPos;
				o.uv = i[idx].uv;
				return o;
			}

			//指定每個邊的細分段數(shù)和內(nèi)部細分段數(shù)
			TessParam ConstantHS(InputPatch<v2t, 3> i, uint id : SV_PrimitiveID)
			{
				TessParam o;
				float4 worldPos = (i[0].worldPos + i[1].worldPos + i[2].worldPos) / 3;
				float smoothstepResult = smoothstep(_minVal, _maxVal, distance(worldPos.xz, _centerPos.xz));
				float fac = max((1.0 - smoothstepResult)*_factor, 1);
				//由于我這里是根據(jù)指定的中心點和半徑范圍來動態(tài)算細分段數(shù),所以才有這個計算,不然可以直接指定變量來設置。
				o.EdgeTess[0] = fac;
				o.EdgeTess[1] = fac;
				o.EdgeTess[2] = fac;
				o.InsideTess = fac;
				return o;
			}

			//在domainProgram前必須設置domain參數(shù),不然會報錯
			[domain("tri")]
			//細分之后,把信息傳到frag片段程序
			t2f domainProgram(TessParam tessParam, float3 bary : SV_DomainLocation, const OutputPatch<TessOut, 3> i)
			{
				t2f o;				
				//線性轉(zhuǎn)換
				o.worldPos = i[0].worldPos * bary.x + i[1].worldPos * bary.y + i[2].worldPos * bary.z;
				o.clipPos = UnityWorldToClipPos(o.worldPos);
				float2 uv = i[0].uv * bary.x + i[1].uv * bary.y + i[2].uv * bary.z;
				o.uv = uv;
				return o;
			}
            fixed4 frag (t2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv)*_Color;
                return col;
            }
            ENDCG
        }
    }
}

??使用的時候,在C#端中心點改變的時候,傳入centerPos,通過調(diào)整_maxVal和_minVal,可以控制半徑和邊緣強度漸變的效果

2、在Surface著色器實現(xiàn)局部細分

??在Surface著色器里面實現(xiàn)曲面細分,需要寫的代碼很少,我們就使用上面介紹的Fixed類型然后同樣的通過傳入中心點,還有_maxVal和_minVal,來確定需要細分的范圍,實現(xiàn)思路和上面的頂點片段著色器是一樣的。
代碼會是這樣的:

Shader "azhao/FootStepMeshSurface"
{
    Properties
    {
		_MainTex("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
		_centerPos("centerPos", Vector) = (0,0,0,0)
		_minVal("minVal", Float) = 0
		_maxVal("maxVal", Float) = 10
		_factor("factor", Float) = 15
		_footstepRect("footstepRect",Vector) = (0,0,0,0)
		_footstepTex("footstepTex",2D) = "gray"{}
		_height("height" ,Float) = 0.3
		_Glossiness("Glossiness",Float) = 0
		_Metallic("Metallic",Float) = 0

    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
		#include "Tessellation.cginc"
        #pragma surface surf Standard fullforwardshadows vertex:vertexDataFunc tessellate:tessFunction 
        #pragma target 4.6


        struct Input
        {
            float2 uv_texcoord;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
		uniform sampler2D _mainTex;
		SamplerState sampler_mainTex;
		uniform float4 _mainTex_ST;
		uniform float _minVal;
		uniform float _maxVal;
		uniform float3 _centerPos;
		uniform float _factor;
		float4 _footstepRect;
		sampler2D _footstepTex;
		float _height;
        UNITY_INSTANCING_BUFFER_START(Props)
        UNITY_INSTANCING_BUFFER_END(Props)

		float RemapUV(float min, float max, float val)
		{
			return (val - min) / (max - min);
		}
		//這里處理細分相關邏輯
		float4 tessFunction(appdata_full v0, appdata_full v1, appdata_full v2)
		{
			float3 worldPos = mul(unity_ObjectToWorld, (v0.vertex + v1.vertex + v2.vertex) / 3);
			float smoothstepResult = smoothstep(_minVal, _maxVal, distance(worldPos.xz, _centerPos.xz));
			float fac = max((1.0 - smoothstepResult)*_factor, 0.1);
			return fac;
		}

		void vertexDataFunc(inout appdata_full v)
		{

		}

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c =  _Color;
			float2 uv_mainTex = IN.uv_texcoord * _mainTex_ST.xy + _mainTex_ST.zw;
			float4 mainTex = tex2D(_mainTex, uv_mainTex);
            o.Albedo = mainTex.rgb*c.rgb;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

3、選擇哪種方式的Shader實現(xiàn)會比較好?

??這個問題是沒有直接答案的,需要根據(jù)自己的實際情況來選擇。
??頂點片段著色器的優(yōu)點是可控性強,自己可以隨意的定義各種光照模型、修改細節(jié)的效果,缺點是寫法麻煩。
??Surface著色器的優(yōu)點是寫法簡單,缺點是可控性比較弱一點。
??我個人是習慣用頂點片段著色器的,因為我比較的喜歡自己控制各個環(huán)節(jié)的細節(jié)。所以在接下來的例子里面,我還是會用頂點片段著色器的寫法來繼續(xù)做這個地面交互效果的demo。不過其實如果頂點片段著色器上知道了怎樣實現(xiàn),在Surface著色器上面實現(xiàn)的過程就更簡單了。文章來源地址http://www.zghlxwxcb.cn/news/detail-743994.html

到了這里,關于Unity地面交互效果——3、曲面細分基礎知識的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • Unity制作下雨中的地面效果

    Unity制作下雨中的地面效果

    Unity引擎制作下雨效果 ??大家好,我是阿趙。 ??之前介紹了Unity引擎里面通過UV偏移做序列幀動畫的做法,這里再介紹一個進階的用法,模擬地面下雨的雨點效果。 ??最基本的原理,還是基于這個序列幀動畫的做法。不過這里做一點改變。我不再用網(wǎng)格的UV作為計算的

    2024年02月10日
    瀏覽(20)
  • 3D Surface Subdivision Methods 3D 曲面細分方法

    3D Surface Subdivision Methods 3D 曲面細分方法

    原文地址: https://doc.cgal.org/latest/Subdivision_method_3/index.html#Chapter_3D_Surface_Subdivision_Methods 細分方法遞歸地細化控制網(wǎng)格并生成逼近極限表面的點。 該包由四種流行的細分方法及其細化主機組成。 支持的細分方法包括 Catmull-Clark、Loop、Doo-Sabin 和 √3 細分。 它們各自的細化宿主是

    2024年01月19日
    瀏覽(22)
  • OpenGL超級寶典第八章學習筆記:基元處理之曲面細分

    OpenGL超級寶典第八章學習筆記:基元處理之曲面細分

    前言 本篇在講什么 OpenGL藍寶書第八章學習筆記之曲面細分 本篇適合什么 適合 初學OpenGL 的小白 本篇需要什么 對 C++ 語法有簡單認知 對 OpenGL 有簡單認知 最好是有 OpenGL超級寶典 藍寶書 依賴 Visual Studio 編輯器 本篇的特色 具有全流程的 圖文教學 重實踐,輕理論,快速上手

    2024年02月07日
    瀏覽(23)
  • 計算機圖形學與opengl C++版 學習筆記 第12章 曲面細分

    計算機圖形學與opengl C++版 學習筆記 第12章 曲面細分

    術語Tessellation(鑲嵌)是指一大類設計活動,通常是指在平坦的表面上,用各種幾何形狀的瓷磚相鄰排列以形成圖案。它的目的可以是藝術性的或?qū)嵱眯缘?,很多例子可以追溯到幾千年前[TS16]。 在3D圖形學中,Tessellation指的是有點不同的東西(曲面細分),但顯然是由它的經(jīng)

    2024年02月08日
    瀏覽(34)
  • 【游戲開發(fā)小技】Unity中實現(xiàn)Dota里的角色技能地面貼花效果(URP ShaderGraph Decal)(1)

    【游戲開發(fā)小技】Unity中實現(xiàn)Dota里的角色技能地面貼花效果(URP ShaderGraph Decal)(1)

    [Toggle(_SupportOrthographicCamera)] _SupportOrthographicCamera(“_SupportOrthographicCamera (default = off)”, Float) = 0 } SubShader { // 關于tags的內(nèi)容可以查閱官網(wǎng)手冊:https://docs.unity3d.com/Manual/SL-SubShaderTags.html // 為了避免渲染順序問題, Queue必須 = 2501, 它位于透明隊列中 // 在透明隊列中,Unity總是從后

    2024年04月16日
    瀏覽(22)
  • UI及交互設計知識整理(超詳細 基礎篇)

    UI及交互設計知識整理(超詳細 基礎篇)

    首先,解決一個問題 UI 是 User Interface 的縮寫,即界面設計。 其中 Interface 中的 inter 又有“ 在一起,交互 ”之義,所以UI設計中也包括了交互設計。 用更通俗易懂的話來說就是 符合用戶需求的界面設計 。 然后開始我們的 設計基礎知識介紹 這是包括項目經(jīng)理、ui設計師、交

    2023年04月25日
    瀏覽(12)
  • 全面了解Java連接MySQL的基礎知識,快速實現(xiàn)數(shù)據(jù)交互

    全面了解Java連接MySQL的基礎知識,快速實現(xiàn)數(shù)據(jù)交互

    當今互聯(lián)網(wǎng)時代,大量的應用程序都需要使用MySQL數(shù)據(jù)庫來存儲和處理數(shù)據(jù)。Java作為一種廣泛使用的編程語言之一,在開發(fā)Web應用程序時經(jīng)常需要連接MySQL數(shù)據(jù)庫進行數(shù)據(jù)操作。 因此,了解如何使用Java連接MySQL數(shù)據(jù)庫是非常重要的。在本文中,我們將介紹Java JDBC API以及如何使

    2024年02月06日
    瀏覽(18)
  • Unity通過深度圖做有交互效果的水泡沫

    Unity通過深度圖做有交互效果的水泡沫

    通過深度圖做交互水泡沫 大家好,我是阿趙。 這里做一個有交互效果的水面,物體浸入水面時,會根據(jù)物體的形狀,有一圈水泡沫的效果,并且水泡沫的形狀會跟隨這物體變化。由于想做得稍微完整一點,又不想其他效果太強泡沫的風頭,所以簡單加了一個水面紋理流動的

    2024年02月12日
    瀏覽(19)
  • pygame偽3d地面 移動效果

    pygame偽3d地面 移動效果

    2024年02月13日
    瀏覽(44)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包