#Custom Node
1 messages ยท Page 1 of 1 (latest)
Well, in your custom node hlsl you'll need to make a loop ๐
void CalculatingColHeight(float UVx, out float UVy )
{
for (int i = 0; i < positionArrays.Length; i++)
{
if(UVx < positionArrays[i].x)
{
UVy = positionArrays[i].y;
return;
}
}
}```
Something like this I guess ?
Note that you could achieve the same result without custom nodes and loops if you simply decide to use a texture instead of the vector2 array
I'm considering it to be honest but I am currently exploring my options ^^
Oh wait, I've maybe mis-interpretted your example : are the "columns" always evenly spaced like in your example, or can they vary in width ?
Also I don't know how generating a 1600pixel texture everyframe will impact performance (I don't knox anything about that though)
Within a same object the column will always be the same width ๐
And evenly distributed ?
Yep
In that case, the texture method would probably be better
And you don't need to generate the texture every frame, you generate it once, and only update when needed.
So I create the texture with my y value (using alpha or red values), I pass it with the increment to my shader and I make the shader read the this value to converting back to a float ? (if I understand correctly)
Let me build an example very quickly
It's a constant movement for waves in a pixel art 2D water so it would be every frame :/
The idea is to create a body of water where I can control waves patterns while retaining a pixel art look ๐ I have tried different options in the past but always encountered problems.
Example if the values are in a texture :
Okay I understood correctly at least ๐
Now, indeed if you want to change a single pixel of the texture, it all needs to be uploaded to the GPU with "Apply()".
So depend how many values in the vector array you are changing per frame.
If it's only a single one, vector arrays might be more performant.
If it's the whole array, I think it would have comparable perfs as the texture.
You can achieve a similar effect with the custom HLSL in a simple way :
float2 array[];
void WaveMask_float( float2 uv, out float )
{
int index = floor( uv.x * arraySize );
return step( uv.y, array[index] );
}
Well technically as you said the distribution will be uniform depending on the spacing parameter so I only need a float array. But every float would change per frame yeah
Well, so a texture is easier to handle I guess (and can more easilly be resized) ๐
So let's imagine I have my code. On FUpdate I do the calculations to determine the position of each pixel. Once the calculations are over I create a new texture depending on the array (with red values for exemple). I just need to get this texture to the shader or do I need something else ? (Sorry I'm a bit novicde in computer graphics ^^")
In Start, you create the texture with the required size, and assign it to the material.
On Update, you :
- calculate your pixels positions in a c# color array (yep, no choice, it needs to be of the Color type)
- set the value in the R field for each of them
- Once all the values are calculated (after the for loop
- call texture.SetPixels( ... ) with the color array
- call texture.Apply() to send the data to the GPU.
No need to create a texture every frame, and no need to re-apply it to the material.
{
int size;
Texture2D texture;
float[] pixelPos;
Color[] colorsAray;
SpriteRenderer spriteRenderer;
// Start is called before the first frame update
void Start()
{
size = (int)transform.localScale.x * 16;
colorsAray = new Color[size];
pixelPos = new float[size];
texture = new Texture2D(size, 1, TextureFormat.ARGB32, false);
//set up Material Property Blmock and assign texture to material
}
void FixedUpdate()
{
//Do some shit to calculate pixels positions in pixelPos
for (int i = 0; i < size; i++)
{
colorsAray[i] = new Color(pixelPos[i],0,0);
}
texture.SetPixels(colorsAray);
texture.Apply();
}
}```
Something like this ?
Something like this. Could be a bit better optimisation wise, but should work
What would you improve ?
- Use https://docs.unity3d.com/ScriptReference/TextureFormat.RFloat.html if you only need a single channel
- No need for the pixelPos array, as the data is already in colorsArray
- less sure :
colorsAray[i] = new Color(pixelPos[i],0,0);: maybe just modify the r/x value instead of creating a new color object.
I see ! The pixelPos array will also be used to trigger particles and displacement during collisions so this is fine ๐
Hey ! Thanks a lot for your help, my system is working as intended thanks to your advices ^^
@bright olive