Quick Clay Render

40 votes
Version: 
1.1
Date Updated: 
11/13/2009

Clay Render

 

One click will render your scene as a 'clay' style image, leaving the scene, materials and all your render settings exactly as they are. Code has been updated to create the floor plane at the lowest vertex in the scene, and to make it easier to customise (different renderers, alter the material colour, environment background and light type).

Additional Info: 

When modelling, I often find myself using quick 'clay' renders to get an idea of what my models look like when lit, as it really brings out the edging and detail. But this involved saving my scene, creating a ground plane, positioning it, assigning a clay material to everything, creating the light, rendering it, then reloading the scene because I'd lost all my materials. So I figured I'd give creating a script a go.

It's not perfect, as it's the first proper script I've made, but it does the job. It will find the lowest vertex in the scene, create the ground plane beneath that, sort out the lights and materials, set the renderer to the DSR, do the render, then cleans up after itself (deletes the created nodes, restores all materials, puts the renderer back to whatever you were using).

Only downside - The actual render speed of using skylights isnt great, but that can't be helped, I just love how they look :)

And yes, this has just been written in the past hour because I got fed up of going through the process I described above. Any suggestions on how to improve it are welcome, but go easy on me, I haven't done this before!

Figure I may as well just post the code, it isn't that long:

macroScript ClayRender category: "LiamDavis"
(
-- Variables to change basic settings
rendererToUse = Default_Scanline_Renderer()
clayColour = [255,255,255]
renderBackground = [255,255,255]

clay = standardMaterial diffuse:clayColour shaderType:1
sun = Skylight castShadows: true enabled: true

in coordsys world
min_v = 99999999999
mat_array = #()
m = 1

-- define the clay material

-- Finds the lowest vertex in the scene
for obj in objects do
(
if superclassof obj == geometryClass then
(
-- Take a snapshot of the current objects mesh
checkMesh = snapshotAsMesh obj
-- Find out how many verticies it has for the coming 'for' loop and test each verticies z position to find the lowest
num_verts = checkMesh.numverts
for v=1 to num_verts do
(
vert = getVert checkMesh v
if min_v > vert.z then
(
min_v = vert.z
)
)
delete checkMesh
)
)

-- Create the floorplane at the lowest point
floorplane = plane lengthsegs:1 widthsegs:1 length:10000 width:10000 pos:[0,0,min_v]

-- Store objects current material in an array then assign the Clay material
for obj in objects do
(
append mat_array obj.material
obj.material = clay
)

-- makes sure it renders using the DSR, but leaves it as whatever the user had it as
backgroundSetBackTo = backgroundColor
backgroundColor = renderBackground
rendererSetBackTo = renderers.current
renderers.current = rendererToUse
max quick render -- render the current viewport
renderers.current = rendererSetBackTo
backgroundColor = backgroundSetBackTo

-- delete the added nodes or repeated use would multiply them
delete floorplane
delete sun

-- restore original materials to scene objects
for obj in objects do
(
obj.material = mat_array[m]
m = m+1
)
)

Video URL: 

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Anubis's picture

Hi Liam, about '$' sign, yes

Hi Liam, about '$' sign, yes its a short for selection.
And to exclude the hidden objects:

geo = for g in geometry where not g.isHidden collect g
sha = for s in shapes where not s.isHidden collect s

my recent MAXScripts RSS (archive here)

Liam.Davis's picture

Hey Anubis, you seem to be

Hey Anubis, you seem to be quite good at this stuff, quick question; I had modified my much longer version of the code to exclude hidden objects from the z finding (to ignore reference planes Ive got going on at the mo), by simply checking each objects .isHidden value in the loop, and if it wasnt there it didnt get checked.

Can you think of a way to replicate this in the shorter version? The only way I can see if to add in a loop that checks, but then loops are my answer to everything when clearly there are sometimes much more efficient ways.

Cheers for any suggestions (or from anyone else from that matter).

Liam.Davis's picture

Wow, that's way more

Wow, that's way more succient! I didn't know you could do the undo stuff like that, saves storing ll the things you might change and resetting them like the renderer and materials. Also thats a much better way of aligning the floorplane - so the & acts as a wildcard for everything selected in this case, right?

I'll have to bear those techniquies in mind for the future, cheers fella!

Anubis's picture

Not bed for the first

Not bed for the first script! Here is my idea to optimize the code to works faster:

with undo on
(
	geo = for g in geometry collect g -- collect geometry
	sha = for s in shapes collect s -- shapes as well
	join geo sha -- join shapes
	clay = standardMaterial diffuse:white shaderType:1
	geo.material = clay -- assign mtl at Once (without loop)
	sun = Skylight castShadows: true enabled: true
	floorplane = plane lengthsegs:1 widthsegs:1 length:10000 width:10000
	select geo
	floorplane.pos.z = $.min.z -- easy Z align
	floorplane.material = clay -- assign mtl to the plane
	useEnvironmentmap = off -- turn off env.map
	backgroundColor = white
	renderers.current = Default_Scanline_Renderer()
	max quick render
)
max undo

my recent MAXScripts RSS (archive here)

fajar's picture

oh and light type....

oh and light type....

fajar's picture

Ok got it !!

Ok got it !!

Liam.Davis's picture

Could probably be quite

Could probably be quite easily adapted to make it work with Vray, but I dont have it so Im unable to do it myself. Theres a few lines where it checks what the current renderer is, stores it, switches it to the DSR for the render, then changes the renderer back to whatever was being used. Quite often you're using the DSR anyway, but I put it in just in case it annoyed anyone using any other renderer, wanted the 'leave the place as I found it' if you will! Lemme find it...

currentRender = renderers.current
renderers.current = Default_Scanline_Renderer()
max quick render
renderers.current = currentRender

If you replaced the part that calls the DSR to call VRay, then I don't see why it wouldn't work. Oh, and you'd need to change the material from...

clay = standardMaterial diffuse:[255,255,255] shaderType:1

...to a Vray type material.

fajar's picture

is this support V-Ray cause

is this support V-Ray cause I use V-Ray alot.....?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.