- Home /
Send large array of world positions to Shader (or any other way of sending a large ammount of Vector3s to shader)
Hi! I have a large array of points/positions in world space (large as in it might scale up to a million in "depth") I need a way to transfer this data in some way to the shader for processing..
The basic idea is to let the shader messure the distance between the vertex and the provided world positions in the array and depending on the length of the distance color the material/shader.
So basically..
if(distance(v.vertex.xyz, largeArray[i].xyz) < 1.0f) { //Do stuff for coloring }
The issue is that I cant use the "normal" arrays for this.. since they have a max-depth of somewhere around 1100 (if Im not misstaken).. so I need an alternative way to do this.. any ideas?.. Also.. Im up for any other sulotions as well since I do realize that iterating over all the points might sort of kill the GPU.. so if you have any other suggestions then please feel free to share them.. I was sort of thinking if I could use a 3DTexture in someway maybe.. but couldn't really get my head around it..
Br, Inx
Did you look into compute shaders yet?
https://docs.unity3d.com/560/Documentation/$$anonymous$$anual/ComputeShaders.html
I would use a regular 2DTexture to provide this data.
Let the RGB vaule of the first pixel in the texture [0,0] define the x,y,z coordinates, of the first point you wish to check, Let the RGB vaule of the second pixel in the texture [1,0] define the x,y,z coordinates, of the second point you wish to check, etc...
Of course, these colors will all be normalized values (0.0 to 1.0), so you will probably need some multiplier value, from the material, to convert(scale) to world-space.
The edge size of this texture will need to be: the sqrt of the # of points to check.
I suspect there is plenty of stuff out there on how to create and assign this texture to the material, and how to access it inside the shader.
Alas, no idea's to help performance of that.
edit: not familiar with compute-shaders myself, that may very well be the better way to go.
Hi! Just wanted to ask if you came up with a solution, I'm having the EXACT same question for a while now :)
Hi! Just wanted to ask if you came up with a solution, I'm having the EXACT same question for a while now :)
Answer by termway · May 04, 2017 at 04:18 PM
You should look at Compute Buffer and/or Compute Shaders.
The simplest way would be to use structured buffered but it's only DirectX11. Something like this :
CGPROGRAM
#pragma target 5.0
#pragma vertex vert
#pragma fragment frag
uniform StructuredBuffer<float3> positions;
uniform StructuredBuffer<float3> colors;
struct VertexColor
{
float4 position : POSITION;
float4 color: COLOR;
};
VertexColor vert(uint id : SV_VertexID)
{
VertexColor output;
output.position = mul(UNITY_MATRIX_MVP, float4(positions[id], 1));
output.color = float4(colors[id], 1);
return output;
}
In scripts :
ComputeBuffer positionsBuffer = new ComputeBuffer(points[m].Size, sizeof(float) * 3, ComputeBufferType.Default);
ComputeBuffer colorsBuffer = new ComputeBuffer(points[m].Size, sizeof(float) * 3, ComputeBufferType.Default);
//...
positionsBuffer.SetData(...);
colorsBuffer.SetData(...);
//
material.SetBuffer("positions", positionsBuffer);
material.SetBuffer("colors", colorsBuffer);