Hello Monkeys,
im currently working on adding grass to my voxelgame.
I decided to go with a geometry shader approach and to put a long story short, while meshing a chunk i also create a point mesh that contains one point per visible top-face of vegetation spawning blocks (currently only for grass blocks but i put the blocktype in a vertex attribute so in the shader i could spawn different vegetation based on blocktype)
in the shader i then spawn several triangle-strip grass-blades per point and offset them using a noise-texture so they spread over the 1x1 sized top-face of the block.
that all works fine as long as i’m facing negative z. As soon as i rotate the cam the grassblades get thinner until they disappear. so i obviously want to do some billboarding in that i rotate the grassblades, around the y axis only, to always be facing the cameras position, but beeing the shadernoob that i am, i cannot seem to get it working
here is the code for the rotation:
//msPosCenter is the origin of the grassblade, it already contains the offset caused by the noisetexture to spread over the whole face, in modelSpace (its the point i want to rotate around basically)
//msPosOffset is the grass-blade-vertexes offset relative to the msPosCenter, in modelSpace (so over the 7 calls nedded to form a full grassblade, msPosCenter is the same for all calls, only msPosOffset varies
vec3 faceCamera(vec3 msPosCenter, vec3 msPosOffset) {
//return (g_WorldMatrix * vec4(msPosCenter+msPosOffset, 1.0)).xyz;
//prepare some variables
//ms modelspace
vec4 msPos = vec4(msPosCenter, 1.0);
vec4 msOffPos = vec4(msPosOffset, 1.0);
vec3 msNorm = vec3(0.0, 0.0, 1.0);
//ws worldspace
vec3 wsPos = (g_WorldMatrix * msPos).xyz;
vec3 wsOffPos = (g_WorldMatrix * msOffPos).xyz;
vec3 wsNorm =(g_WorldMatrix * vec4(msNorm, 1.0)).xyz;
//first calculate direction to camera (in worldspace)
wsNorm.y = 0.0;
wsNorm = normalize(wsNorm);
vec3 deltaCam =g_CameraPosition-wsPos;
deltaCam.y = 0.0;
deltaCam = normalize(deltaCam);
//calc angle between normal and view
float dot = dot(wsNorm, deltaCam);
float angle = acos(dot);
//now rotate the offset
mat2 rot = mat2(vec2(cos(angle), sin(angle)), vec2(-sin(angle), cos(angle)));
vec2 wsOffPosFlat = wsOffPos.xz;
vec2 wsOffPosRot = rot * wsOffPosFlat;
//and return the offset added to the basePosition
return wsPos.xyz + vec3(wsOffPosRot.x, wsOffPos.y, wsOffPosRot.y);
}
EDIT: the ‘vec3 msPosOffset’ parameter does only offset in x and y directions, thus the line ‘vec3 msNorm = vec3(0.0, 0.0, 1.0);’
im aware of the fact that i pass in positions in modelspace and return a position in worldspace, but im taking care of that and if i uncomment the first line, and comment out all other lines instead, their position is correct, only they are not rotated ofc
i could also use the same rotation matrix for all vertices of a grass-blade but i can do such optimization later, i want it to work first
So thanks a lot in advance already, have a nice day and many greetings from the shire,
samwise