Problem accessing arrays

Hello people,

I have a bit of an issue which I can’t seem to wrap my head around.

The basic Idea of what I want to achieve is that when an object hits a wall, a certain radius of that collision point would become visible (just as a basic thing) and I got this working just fine. The problem however is that this object bounces off and can hit objects multiple times, which we limited to 4.

I initially just wanted to pass the 4 different collision points as an array, but Unity doesn’t allow passing arrays. So I thought of something else which I am trying to get to work now, but a problem arises. Let me explain when I am trying to do:

I created a struct that holds a collisionpoint and exposure radius (float3 and float respectively) and I create 4 of these structs as an array. Because we keep track of how many bounces the object has made, I wanted to use that as an index to fill the structs with their relevant data. I am however not allowed to use this uniform as an index. Here’s the shader so things might get more clear:

Shader "SonarBall/HitExposure" 
{
	Properties 
	{
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_CollisionPoint ("Point of Collision", Vector) = (0, 0, 0)
		_ExposureRadius ("Radius of Exposure", Float) = 3
		_CollisionIndex ("Hit Amount", Float) = 0
	}
	SubShader 
	{
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		#pragma surface surf Lambert
		#pragma target 3.0

		sampler2D _MainTex;
		float3 _CollisionPoint;
		float _ExposureRadius;
		float _CollisionIndex;

		struct Exposure
		{
			float3 CollisionPoint;
			float ExposureRadius;
		};

		Exposure _Exposures[4];

		struct Input 
		{
			float2 uv_MainTex;
			float3 worldPos;
		};

		void surf (Input IN, inout SurfaceOutput o) 
		{
			int index = _CollisionIndex;
			_Exposures[index].CollisionPoint = _CollisionPoint;
			_Exposures[index].ExposureRadius = _ExposureRadius;

			float4 color = float4(0, 0, 0, 1);

			for(int i = 0; i < 4; i++)
			{
				float3 ColPoint = _Exposures[i].CollisionPoint;
				float Expose = _Exposures[i].ExposureRadius;

				float dist = distance(IN.worldPos, ColPoint);

				if(dist < Expose)
				{
					color = tex2D (_MainTex, IN.uv_MainTex);
				}
			}

			o.Albedo = color.rgb;
			o.Alpha = color.a;
		}
		ENDCG
	} 
	FallBack "Diffuse"
}

So my question is, is there any efficient way of doing this? I tried to assign the values manually, but I still want to use the index to check which “bounce” has occurred, as later on, this will have an impact on the visuals.

Any suggestions of a better way of achieving this effect is also welcome :slight_smile:

I’m not quite sure what you’re trying to do there… When you need to render four of these collisions, then you can’t pass just one. This way, even if it worked, you would get just one collision out of it, as whatever you set inside a shader is not persistent between calls.

I would do something along these lines (untested):

Shader "SonarBall/HitExposure" 
{
    Properties 
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _Collision1 ("Collision 1", Vector) = (0, 0, 0, 0);
        _Collision2 ("Collision 2", Vector) = (0, 0, 0, 0);
        _Collision3 ("Collision 3", Vector) = (0, 0, 0, 0);
        _Collision4 ("Collision 4", Vector) = (0, 0, 0, 0);
    }
    SubShader 
    {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        CGPROGRAM
        #pragma surface surf Lambert

        sampler2D _MainTex;
        float4 _Collision1;
        float4 _Collision2;
        float4 _Collision3;
        float4 _Collision4;
        
        #define Collision(i) _Collision##i

        struct Input 
        {
            float2 uv_MainTex;
            float3 worldPos;
        };

        void surf (Input IN, inout SurfaceOutput o) 
        {   
            float4 color = float4(0, 0, 0, 1);

            for(int i = 0; i < 4; i++)
            {   
                float4 col = Collision(i);
                float3 ColPoint = col.xyz;
                float Expose = col.w;
                
                float dist = distance(IN.worldPos, ColPoint);
                if(dist < Expose)
                {
                    color = tex2D (_MainTex, IN.uv_MainTex);
                }
            }
            
            o.Albedo = color.rgb;
            o.Alpha = color.a;
        }
        ENDCG
    } 
    FallBack "Diffuse"
}

Yeah that was the initial way I wanted to implement it and the way I showed wasn’t a correct way anyway.

I initially just wanted to pass an array of collision points to use, but alas, I can’t pass arrays. So I guess this is the only way I can make it work :slight_smile:

Thanks anyway :slight_smile: