When I was making trees in 3dsmax, I encountered a problem about vertex normals. In order to get better light and shadow effect, I needed to adjust the vertex normals of leaves. I found some scripts online that can pass vertex normals, most of them are spherical normals:VertexNormal
although some light and shadow problems have been solved. But the final volume is not ideal. I tried to do a script myself, by getting the normal orientation of the face and then do a certain flip, but the effect is very unsatisfactory.
I found in Horizon's documentation that their approach to leaf normals looks like a normal transferred from some wrap shape.
Is there a way to generate such an inclusion model in 3dsmax and pass normal information through it to the original model?
I have a simple question... How long does it take an artist to make an average foliage geometry, including mapping and material?
An artist spends at least an hour creating a tree..... there is nothing wrong with spending another 5 minutes to create a few spheres around the “clouds of foliage”.
So, the topic of “automatic” creation is solved and closed, I guess. Now we can focus on “normal things”.
Now another question: Do we need to modify vertex normals? I expect that you will use a normal map anyway. Wouldn't it be easier to create the right texture?
I did a quick geometry around the leaves. It took about 5 minutes.
After that, all is simple:
src=$leaf2
trg = $normals
rm = RayMeshGridIntersect ()
rm.Initialize 100 --init. the voxel grid size to 100x100x100
rm.addNode trg
rm.buildGrid()
for v=1 to src.numverts collect
(
f = rm.ClosestFace (getvert src v)
n = getfacenormal trg f
setnormal src v n
)
update src
need a better approximation? go ahead, make a closer target mesh, and tesselate it enough...
Can the algorithm be improved, and the result as well? Yes, it can... but first, we need to discuss what's wrong with it.
I found a script in blender that came close to the expected result. It used voxels to generate the inclusion model, then passed vertex normals, and got a nice AO, but it didn't quite work as well as the Horizon document. The inclusion completely filled all the leaf clusters, resulting in a lot of vertex normals facing down. The inclusions in Horizon are more like the outer outline based on the overall leaf.
Unfortunately blender is not part of my workflow and I can't find anything like it in 3dsmax.
Hi, Denis. Script executes without errors, but gives strange results.
Am I using it wrong?
Lowest max I can save to is 2021 so sending FBX instead.
It was my mistake. I used the wrong interface and didn't double-check. It should be (MeshProjIntersect)
(
mi = MeshProjIntersect()
mi.SetNode target_node
mi.Build()
target_mesh = snapshotasmesh target_node
cc = for v=1 to source_mesh_node.numverts collect
(
pos = getvert source_mesh_node v
if (mi.ClosestFace pos doubleSided:true) do
(
face = mi.GetHitFace()
norm = getfacenormal target_mesh face
setnormal source_mesh_node v norm
)
)
)
Thank you for updated version. "isset" was giving me error
-- Type error: Call needs function or class, got: undefined
Not sure this is the right way, but removing it seems to work. Ended up with:
(
source_mesh_node = $leaf2
target_node = $normals
mi = MeshProjIntersect()
mi.SetNode target_node
mi.Build()
target_mesh = snapshotasmesh target_node
cc = for v=1 to source_mesh_node.numverts collect
(
pos = getvert source_mesh_node v
mi.ClosestFace pos doubleSided:true
if (face = mi.GetHitFace()) do
(
norm = getfacenormal target_mesh face
setnormal source_mesh_node v norm
)
)
update source_mesh_node
)
This gives expected result with just a couple of artifacts.
@dmitriy.shpilevoy wrote:Thank you for updated version. "isset" was giving me error
-- Type error: Call needs function or class, got: undefined
isset is my function 😁 It means not 0, not false, not undefined, and if count is defined, it's not zero.
I fixed the code
Can't find what you're looking for? Ask the community or share your knowledge.