Hi, I’m working on a grass shader that will bend the grass on interaction.
(to simulate the character trampling the grass)
It works fine with single inputs. However, when I try to pass an array of objects into the shader, ONLY the last object on the array list will bend grasses.
(For example, on a size 5 array, only the 5th object interacts with the grass in runtime)
Here’s the code I attached to the interactor:
[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);
}
The shader code is rather long and here are parts I edited to try to make it take multiple inputs:
uniform float _PositionArray;
uniform float3 _PositionMoving[100];
float3 sphereDisp;
for (int i = 0; i < _PositionArray; i++) {
float3 dis = distance(_PositionMoving, worldPos); // distance for radius
float3 radius = 1 - saturate(dis/ _Radius); // in world radius based on objects interaction radius
sphereDisp = worldPos - _PositionMoving; // position comparison
sphereDisp *= radius; // position multiplied by radius for falloff
sphereDisp = clamp(sphereDisp.xyz * _Strength, -0.8, 0.8);
}
The “sphereDisp” float variable is later used to bend the grass. The For Loop is supposed to pass each object in the array to create a sphereDisp that bends the grass, at least that’s how I understand it.
I’m new to Unity, and suspect there also might be something wrong with the “worldPos”, but can’t tell.
The excerpt looks something like this in the script:
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 triStream)
{float3 worldPos = TransformObjectToWorld(IN[0].pos);
I don’t understand the whole “IN[0].pos” thing, whether it will count multiple inputs or just one.
To sum up, my shader only responds to the last object in the array I pass into.
I want it to respond to all the objects in the array simultaneously.
(Just like in a game, where grasses are trampled by multiple objects such as the player, enemies, npcs…)