[程式] Unity3D 客製shader接收array的問題已刪文
大大們好 我是Unity新手
最近依樣畫葫蘆做了個挺細緻的草地Shader 角色進入後草會被踐踏
但僅適用一個物件 我想要的效果是能被array中所有物件同時踐踏
例如 主角, 敵人, NPC 同時在草原走動 各自踐踏草皮
google了一下 基本上應該能把原本輸入單一目標參數的地方改成輸入array, for loop來
輕鬆解
可是我改完後只有array中最後一個物件對草有互動
(例如 array有5個物件: 玩家、npc1, npc2, npc3, npc4,
設定完後卻只有最後一個npc成功踐踏草皮)
---
要互動的遊戲物件上的script:
[SerializeField]
GameObject[] objects;
Vector4[] positions = new Vector4[100];
void Update()
{
for (int i = 0; i < objects.Length; i++)
{
positions = objects.transform.position;
}
Shader.SetGlobalFloat("_PositionArray", objects.Length);
Shader.SetGlobalVectorArray("_PositionMoving", positions);
}
---
Shader本身script太長了 我就po關鍵接收array參數的部分
由剛剛遊戲物件上script得來的array大小及位置參數:
uniform float _PositionArray;
uniform float3 _PositionMoving[100];
for loop部分:
基本上只是在原版shader裡加了for(){}這個函式
其中sphereDisp這個參數會影響後續掰彎草莖的地方
我的理解是array中每個物件產生的sphereDisp不同
因而達成後續同時在不同地方掰彎草地的效果
float3 sphereDisp;
for (int i = 0; i < _PositionArray; i++) {
float3 dis = distance(_PositionMoving, worldPos);
float3 radius = 1 - saturate(dis/ _Radius);
sphereDisp = worldPos - _PositionMoving;
sphereDisp *= radius;
sphereDisp = clamp(sphereDisp.xyz * _Strength, -0.8, 0.8);
}
而這裡面的worldPos我是照抄預設定義 大致如下:
但我懷疑這會不會是問題所在 我完全看不懂IN[0]哪來的
但直覺認為有0的話是不是代表只有1個預設input
而因為我是要讓它接收複數型式的array資料 會不會因此造成執行時只有一個物件成功踐
踏草皮
v2g vert(Attributes v)
{
float3 v0 = v.positionOS.xyz;
v2g OUT;
OUT.pos = v.positionOS;
OUT.norm = v.normal;
OUT.uv = v.texcoord;
OUT.color = v.color;
return OUT;
}
struct g2f
{
float4 pos : SV_POSITION;
float3 norm : NORMAL;
float2 uv : TEXCOORD0;
float3 diffuseColor : COLOR;
float3 worldPos : TEXCOORD3;
float3 shadows : TEXCOORD4;
float fogFactor : TEXCOORD5;
};
[maxvertexcount(48)]
void geom(point v2g IN[1], inout TriangleStream<g2f> triStream)
{
上略
float3 worldPos = TransformObjectToWorld(IN[0].pos);
下略
}
我還很菜 都是邊做邊學 大部分碰到執行錯誤就看編碼器的解釋
但像這種能順利執行 但效果不是我要的(只接受array最後一個物件給的值)
就真沒頭緒0rz
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.35.113.159 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/GameDesign/M.1615477726.A.6F5.html
GameDesign 近期熱門文章
PTT遊戲區 即時熱門文章