If I use the Grass Tool to apply grass through the landscape material by applying a Grass Type, do I have a way to NOT align the grass mesh to Normal? I love the Landscape material grass tool, but I have no way not to align it to normal. So grass on sloped hills is not growing up, but growing in an angle that looks not quite right…
I keept the grass short so I have never noticed this so far, however it does make perfect sense.
I would suggest just changing the grass material to offset the blades vertically based on an input from the instance.
you should be able to use the Object Rotation for this.
The math should be as straightforward as counter rotating on the vertex normal by the same amount of rotation? Something to that effect.
Doing it this way should be better if you can keep the mesh base alignment (ei: use the vertex paint for the wind as a filter for the shift).
this way the mesh can be tilted to follow the landscape, but grow vertically from where each blade is placed…
There is a checkbox to ‘align to surface’ and it will do what you want, make the grass point straight up(?). However, I run into the same problem that as the mesh models are not single blades of grass but a bunch, some part of is always free-floating off the surface.
I had to do what MostHost LA suggested where I perform a bending of the mesh along a z-fade (up) so that the top is always aligned with world-up (0,0,1). Seems a reasonable cost and it’s a nifty little function you can apply to many things that grow-towards-the-light, or things like flames, bubbles, or if you invert it, falling leaves, etc.
I had some code to show but decided not to post it as I’m not personally ok with the results.
The basics can be as simple as using a 0,0,X vector into World displacement, where x is how tall the grass needs to be in the Z axis. (Fed into the vertex paint, or you just move the mesh up).
for me this doesn’t look too good since some of my grass blades are bent.
This lead to messing around with cross/dot of object rotation and different axis plugged into rotate about axis, but I can - not sure why - only get it to work correctly on one of the inclines…
the other side keeps on bending incorrectly on me.
I don’t like it, but in the end, given that you add in the wind later (literally use add node) this works well enough unless the angles are really extreme.
Does this help?
Thank you everyone.
Grass doesn’t have to grow straight up to grow to the light. Is it an artistic / design choice? Not that it cannot grow straight up on a hill, either.
My example uses 0,0,1 however I’m personally using a MPC light vector - at least until the light vector from the athmosphere is made to work in the vertex shader.
looks promising. Need to try it out on my grass… its not all at the same pivot so it may not work for me.
Ha, well that pointed me in the correct direction in the end:
Basically I need to compress my grass mesh, then my current code will work correctly anyway…
The vertex color with blend is a bit of a nasty piece of work, but it is doable.
Triple post… because it literally took me a few hours to figure out the best possible solution to vertex coloring the mesh correctly
Basically this modified python script sourced from here: https://blender.stackexchange.com/qu…-vertex-colors
Takes into account only the Z value of the vertex, and packs it in a Normalized 0/1 range inside the Y - which is the G channel.
You may notice the 1- which is obviously used to invert the result.
Simply adjust “max = -0.3521/min = 16.1744” to your tallest and lowest value, and each vertex will be correctly packed with the world Z, making it possible to then use the base script to “grow” meshes vertically
import bpy from mathutils import Color, Vector my_object = bpy.context.active_object.data vert_list = my_object.vertices color_map_collection = my_object.vertex_colors if len(color_map_collection) == 0: color_map_collection.new() color_map = color_map_collection'Col'] i = 0 max = -0.3521 min = 16.1744 for poly in my_object.polygons: for idx in poly.loop_indices: loop = my_object.loops[idx] v = loop.vertex_index VertexPaint=1-((vert_list[v].co.z - min) / (max - min)) x =0 y =VertexPaint z =0 t =0 final = (x,y,z,t) color_map.data*.color = final i += 1 # set to vertex paint mode to see the result bpy.ops.object.mode_set(mode='VERTEX_PAINT')
Spectacular results compared to the distortion I had before.
After roaming the world for an hour or so today I decided things looked way too uniform. And that makes perfect sense because the random mesh scaling is now completely worthless in regards to height.
Therefore, here’s the fix for that.