Particle shader - how to get normals to orient particles?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Macryc

Hi.

I’m working with 3d particle shaders. I have a shader that places particles using a heightmap image. I’m using this shader to create particle grass.
I also have a normal map to go with this heightmap and I was wondering if I can use that normal map to somehow get the individual particles to point in the direction of the terrain normal.
Is this possible in particle shaders? Presumably, TRANSFORM should be able to do this but I’ve been racking my brains on how to set this up and so far I’ve been unsuccessful.
Any tips highly appreciated.

it is possible, but it is a bit of a mathematic nightmare. You need to build transformation matrix to rotate chosen axis of your mesh towards the NORMAL. That requires to simulate other orthogonal axes of NORMAL using cross().
Good luck understanding this :
https://forum.godotengine.org/117809/construct-rotation-matrix-knowing-vector-align-matrix-vector

If I get back to my project whereI simplified it and understood it, I will be able to post proper answer :slight_smile:

Inces | 2022-06-13 18:45

:bust_in_silhouette: Reply From: Regulus

In the vertex() function of your particle shader:


First, I will set a temporary x-basis vector.
I’m just setting this to vec3(1,0,0) here,
BUT if your grass particles have rotation,
then you will have to set it to vec3(cos(angle), 0, sin(angle)).

vec3 temp_xbasis=vec3(1,0,0);

I will set the TRANSFORM of the x basis later, as it
relys on the other vectors being calculated first
in order to be perpendicular.

y-basis vector (set to normal)

TRANSFORM[1][0]=normal.x;
TRANSFORM[1][1]=normal.y;
TRANSFORM[1][2]=normal.z;

z-basis vector.

vec3 zbasis=cross(temp_xbasis,normal);
TRANSFORM[2][0]=zbasis.x;
TRANSFORM[2][1]=zbasis.y;
TRANSFORM[2][2]=zbasis.z;

finnaly setting the x-basis vector

vec3 xbasis=cross(zbasis,normal);
TRANSFORM[0][0]=xbasis.x;
TRANSFORM[0][1]=xbasis.y;
TRANSFORM[0][2]=xbasis.z;

Thank you to Inces’ comment, it reminded me of cross products.

1 Like