Community
3ds Max Programming
Welcome to Autodesk’s 3ds Max Forums. Share your knowledge, ask questions, and explore popular 3ds Max SDK, Maxscript and Python topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Foliage vertex normals editing in 3ds Max

11 REPLIES 11
Reply
Message 1 of 12
haoze0221
789 Views, 11 Replies

Foliage vertex normals editing in 3ds Max

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.
1.jpg2.jpg3.jpg
Is there a way to generate such an inclusion model in 3dsmax and pass normal information through it to the original model?

Tags (1)
Labels (2)
11 REPLIES 11
Message 2 of 12

I have a simple question... How long does it take an artist to make an average foliage geometry, including mapping and material?

Message 3 of 12

Hi Denis, I'm also confused that artists always want to automate repetitive operations that don't take much time to make themselvesi
Message 4 of 12

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?

Message 5 of 12

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.

Message 6 of 12

denisTMaxDoctor_0-1723974082384.png

Not bad! 😊

 

Message 7 of 12

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.

Message 8 of 12

denisTMaxDoctor_2-1724006862164.png

 

I don't know. Mine looks good to me.

Message 9 of 12

Hi, Denis. Script executes without errors, but gives strange results.

dmitriyshpilevoy_0-1724055843549.png

Am I using it wrong?

 

Lowest max I can save to is 2021 so sending FBX instead.

Message 10 of 12

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 
		)
	)
)

 

 

 

 

 

Message 11 of 12

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.

Message 12 of 12


@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.

Post to forums  

Autodesk Design & Make Report