For those of you interested in creating “3D” 3D images using 3Delight, here’s a quick little starter for you. You can render from multiple cameras at the same time in the same render pass and save LOADS of rendering time while doing it.

This post will assume that you have created a stereo camera rig in Maya.

Under your 3Delight Render Pass, change the rendering camera to be the center camera, which should be something like stereoCameraCenterShape.

Now, this next step will be dependent on what kind of AOVs and displays you want to render to. In my example, I’m rendering “rgba” as well as “AO” with an alpha channel and exclusivity. In Pre World MEL under the MEL section of the render pass, tweak and add this:
RiDisplay -n "+/path/to/image/rgba_#4f.right.tif" -t "tiff" -m "rgba" -p "camera" "string" "stereoCameraRightShape";
RiDisplay -n "+/path/to/image/rgba_#4f.left.tif" -t "tiff" -m "rgba" -p "camera" "string" "stereoCameraLeftShape";
RiDisplay -n "+/path/to/image/AO_#4f.right.tif" -t "tiff" -m "color aov_AO,alpha" -p "camera" "string" "stereoCameraRightShape" -p "exclusive" "int" "1" -p "exclusive" "int" "1";
RiDisplay -n "+/path/to/image/AO_#4f.left.tif" -t "tiff" -m "color aov_AO,alpha" -p "camera" "string" "stereoCameraLeftShape" -p "exclusive" "int" "1" -p "exclusive" "int" "1";

When you render, this will render .tif files for the left and right cameras for those two AOVs. You can and should tweak this to fit what you need. Then, you can combine the two 3D images in a compositing program to create a 3D stereoscopic image.

For more information on what options you can tweak (such as pixel filters, associating alpha, etc) consult the 3Delight Studio Pro and 3Delight for Maya User Manuals. The general format for adding parameters to the Display portion of the RIB is:
-p "PARAMETER" "TYPE" "VALUE"

 

Sometimes you need to store something for later while using Python. For large cases, you might even need a database. In this example, I’ll show you how to pickle a Python object and store it into a MySQL database.

Pickling in Python is a way of storing sometimes complex data structures into a binary representation that can be unpickled later to get back the same data structure. For instance, a list of nested lists will pickle and unpickle into the same list of nested lists.

In this example, I’m assuming there is a MySQL server at ‘localhost’, with the user ‘pickle’ / password ‘cucumber’ granted rights on the database ‘lists’. In that database is a table called ‘pickleTest’ with the following columns:

ID: a standard auto-incrementing ID int field
Name: a character field for a name
List: a binary BLOB field for storing pickled things

See the commented script which you can run yourself for an example of how to use the pickle module along with a MySQL database to store mass amounts of Python structures that you can retrieve later and unpickle back into the original structure.

It goes over connecting to the database, pickling a semi-complex list, storing the list, retrieving the results, and then unpickling back into the original list.

import cPickle
import MySQLdb

## Create a semi-complex list to pickle
listToPickle = [(10, 10), (20, 10.0), (1.0, 2.0)]

## Pickle the list into a string
pickledList = cPickle.dumps(listToPickle)

## Connect to the database as localhost, user pickle,
## password cucumber, database lists
connection = MySQLdb.connect('localhost','pickle','cucumber','lists')

## Create a cursor for interacting
cursor = connection.cursor()

## Add the information to the database table pickleTest
cursor.execute("""INSERT INTO pickleTest VALUES (NULL, 'testCard', %s)""", (pickledList, ))

## Select what we just added
cursor.execute("""SELECT features FROM pickleTest WHERE card = 'testCard'""")

## Dump the results to a string
rows = cursor.fetchall()

## Get the results
for each in rows:
	## The result is also in a tuple
	for pickledStoredList in each:
		## Unpickle the stored string
		unpickledList = cPickle.loads(pickledStoredList)
		print unpickledList

 

There is a new script in the code section. It is another python for Maya script. This script makes it possible (and super easy) to export your Maya scene to After Effects to add in some composite elements matched to the 3D scene. It bakes out the cameras and objects of your choice, placing locator nulls for each object. Also, it will scale the entire scene up by an amount that you choose to make it much easier to edit in After Effects, because After Effects reads in every unit in Maya as one pixel.

 

I’m sure you’ve had this, multiple render layers, different shaders on each. Eventually, it will break. Especially if you’re assigning materials on a per-face basis.

It’s better to not do that. But, whenever you have a scene that breaks and your renders are unpredictable, you can use this to fix it.

fixRenderLayerOutAdjustmentErrors;

Run that MEL command. That should fix some of the errors. Sometimes, it will revert whenever you save and close the file, but you can run it again whenever you open the scene again.

 

NOTE: This has since been moved to:

http://blog.cameronleger.com/code/ptc_uber_light_shader/

I’ve compiled the shader as a light shader now.

You can’t have multiple atmosphere shaders on top of the same object, so that was limiting. With both ways, you can render out multiple effects at one time. The difference being that with the atmosphere shader, you have one shader with many effects and a pass for each effect, and with the light shader you have lots of light shaders you can link to objects however you want. The key downside for the light shader is that using custom AOVs won’t work unless you hardcode those AOVs into the surface shader. So, for every surface shader in your scene, you have to add in the code to allow them to pass along the custom AOVs. Whereas with the atmosphere shader, you don’t have to.

So for now, in this light shader, custom AOVs and passes are disabled. You can make a render pass for each light and render them out separately, but you lose the ability to render them all at once and save time.

Here are the several key differences in this shader vs. the atmosphere version.

• There is no baking function for the light shader. You can either use my ptc_uber or your own shader to bake
• AOVs are disabled. I’ve taken all the AOV sections out, because in 9.0.1, which I’m using, I don’t have an easy way to make them work. Besides going in to each shader and adding the custom AOVs, if anyone has a better idea, please let me know. If you want to add them back in, compare this shader to my ptc_uber to see what all goes where.
• Gamma correction is gone, but each section has an intensity multiplier so you can control the effect.
• No AO section under GI. I haven’t tested using multiple options at the same time, but there’s no use for that because you can very easily add another light with another instance of this shader for the added effects. That is also the reason for taking out AO under GI. If you want both, use two lights, one for AO, one for GI. Simple enough.

UPDATE:10/19/2010
It now works correctly with 3Delight materials. Still having trouble with mia materials.
Added SSS to PTC usage section.

UPDATE:11/2/2010
Added AOV support for the newest 3Delight versions.
Fixed numerous bugs.

UPDATE:11/9/2010
Added directional occlusion, a tweak on occlusion that makes it kind of like a soft directional light
Fixed some hints on the Max Variation parameter
IBL may not have been working before
Samplebase isn’t a PTC option, oops

UPDATE:11/22/2010
Added the ability to rebake and reuse PTC data to save rendertime when multiple renders are needed

##    Main
#pragma annotation "grouping" "MAIN/composite;"
#pragma annotation composite "gadgettype=checkbox:0:1=custom value;label=Composite;hint=Add the effect on top of RGBA, otherwise just in the AOV;"
#pragma annotation "grouping" "MAIN/AO;"
#pragma annotation AO "gadgettype=checkbox:0:1=custom value;label=Ambient Occlusion;"
#pragma annotation "grouping" "MAIN/DO;"
#pragma annotation DO "gadgettype=checkbox:0:1=custom value;label=Directional Occlusion;"
#pragma annotation "grouping" "MAIN/RO;"
#pragma annotation RO "gadgettype=checkbox:0:1=custom value;label=Reflection Occlusion;"
#pragma annotation "grouping" "MAIN/GRefl;"
#pragma annotation GRefl "gadgettype=checkbox:0:1=custom value;label=Glossy Reflections;"
#pragma annotation "grouping" "MAIN/GRefr;"
#pragma annotation GRefr "gadgettype=checkbox:0:1=custom value;label=Glossy Refractions;"
#pragma annotation "grouping" "MAIN/IBL;"
#pragma annotation IBL "gadgettype=checkbox:0:1=custom value;label=Image Based Lighting;"
#pragma annotation "grouping" "MAIN/GI;"
#pragma annotation GI "gadgettype=checkbox:0:1=custom value;label=Color Bleeding (GI);"
#pragma annotation "grouping" "MAIN/SSS;"
#pragma annotation SSS "gadgettype=checkbox:0:1=custom value;label=Subsurface Scattering;"
#pragma annotation "grouping" "MAIN/filename;"
#pragma annotation "grouping" "MAIN/rebake;"
#pragma annotation rebake "gadgettype=checkbox:0:1=custom value;label=Rebake PTC Map;"
#pragma annotation "grouping" "MAIN/reuse;"
#pragma annotation reuse "gadgettype=checkbox:0:1=custom value;label=Reuse PTC Map;"
#pragma annotation filename "gadgettype=inputfile;label=PTC File;hint=A previously rendered .ptc file. A .ptc with color and direct lighting baked in is needed for GI and can be used by all, but only point values are needed for AO."
#pragma annotation "grouping" "MAIN/coordsyst;"
#pragma annotation coordsyst "gadgettype=inputfile;label=Coordinate System;hint=Default 'world'. The coordinate system used by the point cloud."
#pragma annotation "grouping" "MAIN/envmap;"
#pragma annotation envmap "gadgettype=inputfile;label=ENV File;hint=A .tdl environment map made from 3Delight's tdlmake. If this is loaded it, it will be used for whatever you have actived and gets used if a ray doesn't hit an object.."
#pragma annotation "grouping" "MAIN/envspace;"
#pragma annotation envspace "gadgettype=inputfile;label=Coordinate System;hint=Default 'world'. The coordinate system used by the environment map."
##    AO
#pragma annotation "grouping" "AO/AO_int;"
#pragma annotation AO_int "gadgettype=floadfield;label=Intensity;hint=Multiplied by the AO effect. Default is 1."
#pragma annotation "grouping" "AO/AO_hitsides;"
#pragma annotation AO_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "AO/AO_maxdist;"
#pragma annotation AO_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e2. Change this based on the scale of your scene."
#pragma annotation "grouping" "AO/AO_falloff;"
#pragma annotation AO_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "AO/AO_falloffmode;"
#pragma annotation AO_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "AO/AO_coneangle;"
#pragma annotation AO_coneangle "gadgettype=floatslider;min=0;max=360;label=Cone Angle;hint=Solid angle considered per point. Default is a hemishpere (180 degrees)."
#pragma annotation "grouping" "AO/AO_bias;"
#pragma annotation AO_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface to prevent self-occlusion on curved surfaces. Usually 0.0 - 0.01. Lower values will get rid of white lines in corners."
#pragma annotation "grouping" "AO/AO_clamp;"
#pragma annotation AO_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Reducing over-occlusion. Doubles render time but much better results."
#pragma annotation "grouping" "AO/AO_maxsolidangle;"
#pragma annotation AO_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Good values between 0.03 and 0.2 Higher values are faster."
#pragma annotation "grouping" "AO/AO_maxvariation;"
#pragma annotation AO_maxvariation "gadgettype=floatfield;label=Max Variation;hint=Interpolates low variations. Values around 30 are up to twice as fast to render but look almost the same."
##    DO
#pragma annotation "grouping" "DO/DO_int;"
#pragma annotation DO_int "gadgettype=floadfield;label=Intensity;hint=Multiplied by the DO effect. Default is 1."
#pragma annotation "grouping" "DO/DO_hitsides;"
#pragma annotation DO_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "DO/DO_dir;"
#pragma annotation DO_dir "label=Direction;hint=Direction of occlusion in world space, coming from the point at XYZ."
#pragma annotation "grouping" "DO/DO_maxdist;"
#pragma annotation DO_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e2. Change this based on the scale of your scene."
#pragma annotation "grouping" "DO/DO_falloff;"
#pragma annotation DO_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "DO/DO_falloffmode;"
#pragma annotation DO_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "DO/DO_coneangle;"
#pragma annotation DO_coneangle "gadgettype=floatslider;min=0;max=360;label=Cone Angle;hint=Solid angle considered per point. Default is a hemishpere (180 degrees)."
#pragma annotation "grouping" "DO/DO_bias;"
#pragma annotation DO_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface to prevent self-occlusion on curved surfaces. Usually 0.0 - 0.01. Lower values will get rid of white lines in corners."
#pragma annotation "grouping" "DO/DO_clamp;"
#pragma annotation DO_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Reducing over-occlusion. Doubles render time but much better results."
#pragma annotation "grouping" "DO/DO_maxsolidangle;"
#pragma annotation DO_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Good values between 0.03 and 0.2 Higher values are faster."
#pragma annotation "grouping" "DO/DO_maxvariation;"
#pragma annotation DO_maxvariation "gadgettype=floatfield;label=Max Variation;hint=Interpolates low variations. Values around 30 are up to twice as fast to render but look almost the same."
##    RO
#pragma annotation "grouping" "RO/RO_int;"
#pragma annotation RO_int "gadgettype=floadfield;label=Intensity;hint=Multiplied by the RO effect. Default is 1."
#pragma annotation "grouping" "RO/RO_hitsides;"
#pragma annotation RO_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "RO/RO_maxdist;"
#pragma annotation RO_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e15. Change this based on the scale of your scene."
#pragma annotation "grouping" "RO/RO_falloff;"
#pragma annotation RO_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "RO/RO_falloffmode;"
#pragma annotation RO_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "RO/RO_coneangle;"
#pragma annotation RO_coneangle "gadgettype=floatfield;label=Cone Angle;hint=Value in radians of the cone angle. Smaller values are better for Reflection Occlusion. Default .2"
#pragma annotation "grouping" "RO/RO_bias;"
#pragma annotation RO_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface to prevent self-occlusion on curved surfaces. Usually 0.0 - 0.01. Lower values will get rid of white lines in corners."
#pragma annotation "grouping" "RO/RO_clamp;"
#pragma annotation RO_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Reducing over-occlusion. Doubles render time but much better results."
#pragma annotation "grouping" "RO/RO_maxsolidangle;"
#pragma annotation RO_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Should use very low values for Reflection Occlusion. Default .005."
##    GRefl
#pragma annotation "grouping" "GRefl/GRefl_int;"
#pragma annotation GRefl_int "gadgettype=floadfield;label=Intensity;hint=Multiplied by the GRefl effect. Default is 1."
#pragma annotation "grouping" "GRefl/GRefl_hitsides;"
#pragma annotation GRefl_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "GRefl/GRefl_maxdist;"
#pragma annotation GRefl_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e15. Change this based on the scale of your scene."
#pragma annotation "grouping" "GRefl/GRefl_falloff;"
#pragma annotation GRefl_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "GRefl/GRefl_falloffmode;"
#pragma annotation GRefl_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "GRefl/GRefl_coneangle;"
#pragma annotation GRefl_coneangle "gadgettype=floatfield;label=Cone Angle;hint=Value in radians of the cone angle. Smaller values are preferred. The larger the value the blurrier the reflections. Default 30"
#pragma annotation "grouping" "GRefl/GRefl_bias;"
#pragma annotation GRefl_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface to prevent self-occlusion on curved surfaces. Usually 0.0 - 0.01. Lower values will get rid of white lines in corners."
#pragma annotation "grouping" "GRefl/GRefl_clamp;"
#pragma annotation GRefl_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Reducing over-occlusion. Doubles render time but much better results."
#pragma annotation "grouping" "GRefl/GRefl_sort;"
#pragma annotation GRefl_sort "gadgettype=checkbox:0:1=custom value;label=Sorting;hint=Clamping must be on for this to have an effect. The color bleed is sorted by distance and gives more correct colors and shadows."
#pragma annotation "grouping" "GRefl/GRefl_maxsolidangle;"
#pragma annotation GRefl_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Should use very low values. Default .005."
##    GRefr
#pragma annotation "grouping" "GRefr/GRefr_readme;"
#pragma annotation GRefr_readme "gadgettype=floatfield;label=README;hint=For this to work properly, THE OBJECT WITH THIS EFFECT ON IT SHOULD NOT BE IN THE POINT CLOUD."
#pragma annotation "grouping" "GRefr/GRefr_int;"
#pragma annotation GRefr_int "gadgettype=floatfield;label=Intensity;hint=Intensity of the effect;"
#pragma annotation "grouping" "GRefr/GRefr_ior;"
#pragma annotation GRefr_ior "gadgettype=floatfield;label=IOR;hint=Index of Refraction;"
#pragma annotation "grouping" "GRefr/GRefr_hitsides;"
#pragma annotation GRefr_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "GRefr/GRefr_maxdist;"
#pragma annotation GRefr_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e15. Change this based on the scale of your scene."
#pragma annotation "grouping" "GRefr/GRefr_falloff;"
#pragma annotation GRefr_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "GRefr/GRefr_falloffmode;"
#pragma annotation GRefr_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "GRefr/GRefr_coneangle;"
#pragma annotation GRefr_coneangle "gadgettype=floatfield;label=Cone Angle;hint=Value in radians of the cone angle. Smaller values are preferred. The larger the value the blurrier the refractions. Default 30"
#pragma annotation "grouping" "GRefr/GRefr_bias;"
#pragma annotation GRefr_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface to prevent self-occlusion on curved surfaces. Usually 0.0 - 0.01. Lower values will get rid of white lines in corners."
#pragma annotation "grouping" "GRefr/GRefr_clamp;"
#pragma annotation GRefr_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Reducing over-occlusion. Doubles render time but much better results."
#pragma annotation "grouping" "GRefr/GRefr_sort;"
#pragma annotation GRefr_sort "gadgettype=checkbox:0:1=custom value;label=Sorting;hint=Clamping must be on for this to have an effect. The color bleed is sorted by distance and gives more correct colors and shadows."
#pragma annotation "grouping" "GRefr/GRefr_maxsolidangle;"
#pragma annotation GRefr_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Should use very low values. Default .005."
##    IBL
#pragma annotation "grouping" "IBL/IBL_int;"
#pragma annotation IBL_int "gadgettype=floadfield;label=Intensity;hint=Multiplied by the IBL effect. Default is 1."
#pragma annotation "grouping" "IBL/IBL_hitsides;"
#pragma annotation IBL_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "IBL/IBL_maxdist;"
#pragma annotation IBL_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e15. Change this based on the scale of your scene."
#pragma annotation "grouping" "IBL/IBL_falloff;"
#pragma annotation IBL_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "IBL/IBL_falloffmode;"
#pragma annotation IBL_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "IBL/IBL_coneangle;"
#pragma annotation IBL_coneangle "gadgettype=floatslider;min=0;max=360;label=Cone Angle;hint=Solid angle considered per point. Default is a hemishpere (180 degrees)."
#pragma annotation "grouping" "IBL/IBL_bias;"
#pragma annotation IBL_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface. Usually 0.0 - 0.01. Go as low as you can go without artifacts."
#pragma annotation "grouping" "IBL/IBL_clamp;"
#pragma annotation IBL_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Doubles render time but much better results."
#pragma annotation "grouping" "IBL/IBL_maxsolidangle;"
#pragma annotation IBL_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Good values between 0.03 and 0.1 Higher values are faster."
#pragma annotation "grouping" "IBL/IBL_maxvariation;"
#pragma annotation IBL_maxvariation "gadgettype=floatfield;label=Max Variation;hint=Interpolates low variations. Values around 30 are up to twice as fast to render but look almost the same."
##    GI
#pragma annotation "grouping" "GI/GI_int;"
#pragma annotation GI_int "gadgettype=floatfield;label=Intensity;hint=Multiplied by the GI result. Default is 1."
#pragma annotation "grouping" "GI/GI_hitsides;"
#pragma annotation GI_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "GI/GI_maxdist;"
#pragma annotation GI_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e15. Change this based on the scale of your scene."
#pragma annotation "grouping" "GI/GI_falloff;"
#pragma annotation GI_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "GI/GI_falloffmode;"
#pragma annotation GI_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "GI/GI_coneangle;"
#pragma annotation GI_coneangle "gadgettype=floatslider;min=0;max=360;label=Cone Angle;hint=Solid angle considered per point. Default is a hemishpere (180 degrees)."
#pragma annotation "grouping" "GI/GI_bias;"
#pragma annotation GI_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface. Usually 0.0 - 0.01. Go as low as you can go without artifacts."
#pragma annotation "grouping" "GI/GI_clamp;"
#pragma annotation GI_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Doubles render time but much better results."
#pragma annotation "grouping" "GI/GI_sort;"
#pragma annotation GI_sort "gadgettype=checkbox:0:1=custom value;label=Sorting;hint=Clamping must be on for this to have an effect. The color bleed is sorted by distance and gives more correct colors and shadows."
#pragma annotation "grouping" "GI/GI_maxsolidangle;"
#pragma annotation GI_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Good values between 30 and 0.1 Higher values are faster."
##    SSS
#pragma annotation "grouping" "SSS/SSS_ior;"
#pragma annotation SSS_ior "gadgettype=floatfield;label=IOR;hint=Index of Refraction. Looks-wise, lower values are more contrasty and higher values produce a more even look with more scattering."
#pragma annotation "grouping" "SSS/SSS_scale;"
#pragma annotation SSS_scale "gadgettype=floatfield;label=Scale;hint=The scale the SSS is computed at, default 1 at millimeters. Higher values produce more scattering and make it look waxier."


#pragma annotation "grouping" "SSS/SSS_type;"
#pragma annotation SSS_type "gadgettype=optionmenu:apple:chicken1:chicken2:cream:ketchup:marble:potato:skimmilk:skin1:skin2:spectralon:wholemilk:custom;label=Preset;hint=Presets. If you choose custom, you can input values in the CUSTOM section. Default CUSTOM values are for skin2"
#pragma annotation "grouping" "SSS/CUSTOM/SSS_abs;"
#pragma annotation SSS_abs "gadgettype=colorslider;label=Absorption;hint=Absorption Coefficient."
#pragma annotation "grouping" "SSS/CUSTOM/SSS_sct;"
#pragma annotation SSS_sct "gadgettype=colorslider;label=Scattering;hint=Scattering Coefficient."
#pragma annotation "grouping" "SSS/SSS_smooth;"
#pragma annotation SSS_smooth "gadgettype=floatfield;label=Smoothing;hint=How much to smooth, from 0 being not and 1 being fully smoothed."
#pragma annotation "grouping" "SSS/SSS_weight;"
#pragma annotation SSS_weight "gadgettype=floatfield;label=Diffuse Weight;hint=How much of the diffuse is considered. 1 is purely diffuse, 0 is purely SSS"
## REBAKING
#pragma annotation "grouping" "REUSING/rebaked_file;"
#pragma annotation rebaked_file "gadgettype=inputfile;label=PTC Filename;hint=Where the .ptc file gets baked to."
#pragma annotation "grouping" "REUSING/rebaked_coordsyst;"
#pragma annotation rebaked_coordsyst "gadgettype=inputfile;label=Coordinate system;hint=Which coordsystem to bake to. Default world."

light
    cl_ptc_light_uber (
                string filename = "<project>/3delight/ptc/<scene>.#.ptc";
                string envmap = "";
                string coordsyst = "world";
                string envspace = "world";
                string AO_hitsides = "both";
                float composite = 0,
                AO_maxdist = 1e2,
                AO_int = .5,
                AO_coneangle = 180, 
                AO_falloff = 1, 
                AO_falloffmode = 1,
                AO_bias = 0.01,
                AO_clamp = 1, 
                AO_maxsolidangle = 0.05,
                AO_maxvariation = 0,
                AO = 0;
                string DO_hitsides = "both";
                float DO_maxdist = 1e2,
                DO_int = .5,
                DO_coneangle = 180, 
                DO_falloff = 1, 
                DO_falloffmode = 1,
                DO_bias = 0.01,
                DO_clamp = 1, 
                DO_maxsolidangle = 0.05,
                DO_maxvariation = 0,
                DO = 0;
                normal DO_dir = normal "world" (0,1,-2);
                string RO_hitsides = "both";
                float RO_maxdist = 1e15, 
                RO_int = 1,
                RO_falloff = 1, 
                RO_falloffmode = 1,
                RO_bias = 0.01,
                RO_clamp = 1, 
                RO_maxsolidangle = 0.05,
                RO_coneangle = 30,
                RO = 0;
                string GRefl_hitsides = "both";
                float GRefl_maxdist = 1e15,
                GRefl_int = 1, 
                GRefl_falloff = 1, 
                GRefl_falloffmode = 1,
                GRefl_bias = 0.01,
                GRefl_clamp = 1,
                GRefl_sort = 1, 
                GRefl_maxsolidangle = 0.05,
                GRefl_coneangle = 30,
                GRefl = 0;
                string GRefr_hitsides = "both";
                float GRefr_maxdist = 1e15,
                GRefr_readme = 0,
                GRefr_int = .3,
                GRefr_ior = 1.1,
                GRefr_falloff = 1, 
                GRefr_falloffmode = 1,
                GRefr_bias = 0.01,
                GRefr_clamp = 1,
                GRefr_sort = 1, 
                GRefr_maxsolidangle = 0.05,
                GRefr_coneangle = 0.1,
                GRefr = 0;
                string IBL_hitsides = "both";
                float IBL_maxdist = 1e15,
                IBL_int = 1, 
                IBL_coneangle = 180,
                IBL_falloff = 1, 
                IBL_falloffmode = 1,
                IBL_bias = 0.01,
                IBL_clamp = 1,
                IBL_maxsolidangle = 0.05, 
                IBL_maxvariation = 0,
                IBL = 0;
                string GI_hitsides = "both";
                float GI_maxdist = 1e15,
                GI_falloff = 1,
                GI_falloffmode = 1,
                GI_bias = 0.045,
                GI_clamp = 1,
                GI_sort = 1,
                GI_coneangle = 180,
                GI_maxsolidangle = .2,
                GI_int = 1,
                GI = 0;
                string SSS_type = "skin1";
                color SSS_sct = color(1.09, 1.59, 1.79), 
		SSS_abs = color(0.013, 0.070, 0.145);
                float SSS_ior = 1.3,
                SSS_scale = 1,
                SSS_smooth = 0,
                SSS_weight = .4,
		SSS = 0;
		float reuse = 0,
		rebake = 0;
		string rebaked_file = "<project>/3delight/ptc/<scene>.#.rebake.ptc",
                rebaked_coordsyst = "world";
                output varying color GI_Cl = 0;
                output varying color GRefl_Cl = 0;
                output varying color GRefr_Cl = 0;
                output varying color RO_Cl = 0;
                output varying color IBL_Cl = 0;
                output varying color AO_Cl = 1;
                output varying color DO_Cl = 1;
                output varying color SSS_Cl = 1;
                output varying color aov_envcolor = 1) 
    {
    normal shading_normal = normalize(Ns);
      
      if(AO == 1) {
		if (reuse != 1) {
        AO_Cl = AO_int*(1-occlusion( // performs occlusion with parameters from GUI, inverse AO and multiply by our intensity
                Ps, shading_normal, 0,
                "pointbased", 1,
                "filename", filename,
                "coordsystem", coordsyst,
                "coneangle", radians(AO_coneangle),
                "hitsides", AO_hitsides,
                "maxdist", AO_maxdist,
                "falloff", AO_falloff,
                "falloffmode", AO_falloffmode,
                "bias", AO_bias,
                "clamp", AO_clamp,
                "maxsolidangle", AO_maxsolidangle,
                "maxvariation", AO_maxvariation));
                
		} else {
		texture3d(rebaked_file, Ps, shading_normal,
		"occlusion", AO_Cl,
		"coordsystem", rebaked_coordsyst);
		}
		outputchannel("aov_AO", AO_Cl);
        if(composite == 1) {
            Cl = AO_Cl;
        } else {
			Cl = Cl;
		}
        Ol = Ol;
		if(rebake == 1) {
			bake3d(rebaked_file, "", Ps, shading_normal, 
			"occlusion", AO_Cl,
			"coordsystem", rebaked_coordsyst,
			"interpolate", 1);
		}
      }
    
    if(DO == 1) {
		if (reuse != 1) {
        DO_Cl = DO_int*(1-occlusion( // performs occlusion with parameters from GUI, inverse AO and multiply by our intensity
                Ps, DO_dir, 0,
                "pointbased", 1,
                "filename", filename,
                "coordsystem", coordsyst,
                "coneangle", radians(DO_coneangle),
                "hitsides", DO_hitsides,
                "maxdist", DO_maxdist,
                "falloff", DO_falloff,
                "falloffmode", DO_falloffmode,
                "bias", DO_bias,
                "clamp", DO_clamp,
                "maxsolidangle", DO_maxsolidangle,
                "maxvariation", DO_maxvariation));
                
		} else {
		texture3d(rebaked_file, Ps, DO_dir,
		"occlusion", DO_Cl,
		"coordsystem", rebaked_coordsyst);
		}
		outputchannel("aov_DO", DO_Cl);
        if(composite == 1) {
            Cl = DO_Cl;
        } else {
			Cl = Cl;
		};
        Ol = Ol;
		if(rebake == 1) {
			bake3d(rebaked_file, "", Ps, DO_dir, 
			"occlusion", DO_Cl,
			"coordsystem", rebaked_coordsyst,
			"interpolate", 1);
		}
      }
      
      if(RO == 1) {
           vector RO_refl = reflect(I, shading_normal); // Uses the reflected vector to compute occlusion, thus reflection occlusion
       if (reuse != 1) {
		RO_Cl = RO_int*(1-occlusion(Ps, RO_refl, 0,  
                "pointbased", 1, 
                "filename", filename,
                "coordsystem", coordsyst,
                "hitsides", RO_hitsides,
                   "clamp", RO_clamp,
                "maxdist", RO_maxdist, 
                "falloff", RO_falloff,
                "falloffmode", RO_falloffmode,
                "coneangle", radians(RO_coneangle),
                "maxsolidangle", RO_maxsolidangle,
                "bias", RO_bias));
            
		} else {
		texture3d(rebaked_file, Ps, RO_refl,
		"occlusion", RO_Cl,
		"coordsystem", rebaked_coordsyst);
		}
		outputchannel("aov_RO", RO_Cl);
        if(composite == 1) {
            Cl = RO_Cl;
        } else {
			Cl = Cl;
		}
        Ol = Ol;
		if(rebake == 1) {
			bake3d(rebaked_file, "", Ps, RO_refl, 
			"occlusion", RO_Cl,
			"coordsystem", rebaked_coordsyst,
			"interpolate", 1);
		}
      }
    
      if(GRefl == 1) {
          vector GRefl_refl = reflect(I, shading_normal); // Again, using a reflection vector for computation 
		if (reuse != 1) {
        GRefl_Cl = GRefl_int*indirectdiffuse(Ps, GRefl_refl, 0, 
                "pointbased", 1, 
                "filename", filename,
                "coordsystem", coordsyst,
                "hitsides", GRefl_hitsides, 
                "clamp", GRefl_clamp,
                "sortbleeding", GRefl_sort,
                "maxdist", GRefl_maxdist, 
                "falloff", GRefl_falloff,
                "falloffmode", GRefl_falloffmode,
                "coneangle", radians(GRefl_coneangle),
                "bias", GRefl_bias,
                "maxsolidangle", GRefl_maxsolidangle);

		} else {
		texture3d(rebaked_file, Ps, GRefl_refl,
		"reflection", GRefl_Cl,
		"coordsystem", rebaked_coordsyst);
		}
        outputchannel("aov_GRefl", GRefl_Cl);
         if(composite == 1) {
            Cl = GRefl_Cl;
        } else {
			Cl = Cl;
		}
          Ol = Ol;
		if(rebake == 1) {
			bake3d(rebaked_file, "", Ps, GRefl_refl, 
			"reflection", GRefl_Cl,
			"coordsystem", rebaked_coordsyst,
			"interpolate", 1);
		}
      }
    
      if(GRefr == 1) {
		if (reuse != 1) {
        extern point Ps;
        extern normal N;
        extern vector I;
        // normalizing
        vector IN = normalize(I);
        // stores reflection and refraction vectors
        vector reflDir, refrDir;
        float eta = (IN.shading_normal < 0) ? 1/GRefr_ior : GRefr_ior;
        float kr, kt;
        // computes fresnel effect
        fresnel(IN, shading_normal, eta, kr, kt, reflDir, refrDir);
        kt = 1 - kr; 
        
        vector RF = normalize(refrDir);
        GRefr_Cl = kt*GRefr_int*indirectdiffuse(Ps, RF, 0, //glossy refractions
                "filename", filename, 
                "pointbased", 1,
                "hitsides", GRefr_hitsides, 
                "coneangle", radians(GRefr_coneangle),
                   "clamp", GRefr_clamp,
                 "coordsystem", coordsyst,
                  "sortbleeding", GRefr_sort,
                 "maxdist", GRefr_maxdist, 
                "falloff", GRefr_falloff,
                  "falloffmode", GRefr_falloffmode,
                "bias", GRefr_bias,
                   "maxsolidangle", GRefr_maxsolidangle);

		} else {
		texture3d(rebaked_file, Ps,  shading_normal,
		"refraction", GRefr_Cl,
		"coordsystem", rebaked_coordsyst);
		}
		outputchannel("aov_GRefr", GRefr_Cl);
        if(composite == 1) {
            Cl = GRefr_Cl;
        } else {
			Cl = Cl;
		}
        Ol = Ol;
		if(rebake == 1) {
			bake3d(rebaked_file, "", Ps, shading_normal, 
			"refraction", GRefr_Cl,
			"coordsystem", rebaked_coordsyst,
			"interpolate", 1);
		}
      }
      
      if(IBL == 1) {
		if (reuse != 1) {
        color IBL_envcol = 0;
        vector IBL_envdir = 0;
        IBL_Cl = IBL_int*occlusion( // performs occlusion from HDRI with parameters from GUI 
                Ps, shading_normal, 0, 
                "pointbased", 1, 
                "filename", filename,
                "coordsystem", coordsyst,
                "hitsides", IBL_hitsides,
                "maxdist", IBL_maxdist, 
                "coneangle", radians(IBL_coneangle),
                "falloff", IBL_falloff,
                "falloffmode", IBL_falloffmode,
                "bias", IBL_bias,
                "clamp", IBL_clamp,
                "maxsolidangle", IBL_maxsolidangle,
                "maxvariation", IBL_maxvariation,
                "environmentmap", envmap,
                "environmentcolor", IBL_envcol,
                "environmentdir", IBL_envdir,
                "environmentcolor", aov_envcolor);

		} else {
		texture3d(rebaked_file, Ps, shading_normal,
		"ibl", IBL_Cl,
		"coordsystem", rebaked_coordsyst);
		}
		outputchannel("aov_IBL", IBL_Cl);
        if(composite == 1) {
            Cl = IBL_Cl;
        } else {
			Cl = Cl;
		}
        Ol = Ol;
		if(rebake == 1) {
			bake3d(rebaked_file, "", Ps,  shading_normal, 
			"ibl", IBL_Cl,
			"coordsystem", rebaked_coordsyst,
			"interpolate", 1);
		}
      }
      
      if(GI == 1) {
		if (reuse != 1) {
        GI_Cl = GI_int*indirectdiffuse(Ps,  // performs color bleeding with parameters from GUI
                shading_normal, 0, 
                "pointbased", 1, 
                "filename", filename,
                "hitsides", GI_hitsides, 
                "coneangle", radians(GI_coneangle),
                "clamp", GI_clamp,
                "coordsystem", coordsyst,
                "sortbleeding", GI_sort,
                "maxdist", GI_maxdist, 
                "falloff", GI_falloff,
                "falloffmode", GI_falloffmode,
                "bias", GI_bias,
                "maxsolidangle", GI_maxsolidangle,
                "environmentmap", envmap,
                "environmentspace", envspace);
                
		} else {
		texture3d(rebaked_file, Ps, shading_normal,
		"indirectdiffuse", GI_Cl,
		"coordsystem", rebaked_coordsyst);
		}
        outputchannel("aov_GI", GI_Cl);
        if(composite == 1) {
            Cl = GI_Cl;
        } else {
			Cl = Cl;
		}
		
		
		Ol = Ol;
		if(rebake == 1) {
			bake3d(rebaked_file, "", Ps,  shading_normal, 
			"indirectdiffuse", GI_Cl,
			"coordsystem", rebaked_coordsyst,
			"interpolate", 1);
		}

        }
        
        if(SSS == 1) {
color SSS_scatter, SSS_absorption;
if (SSS_type == "custom") {
	SSS_scatter = SSS_sct;
	SSS_absorption = SSS_abs;
} else if (SSS_type == "apple") {
	SSS_scatter = color(2.29, 2.39, 1.97);
	SSS_absorption = color(0.003, 0.0034, 0.046);
} else if (SSS_type == "chicken1") {
	SSS_scatter = color(0.15, 0.21, 0.38);
	SSS_absorption = color(0.015, 0.077, 0.19);
} else if (SSS_type == "chicken2") {
	SSS_scatter = color(0.19, 0.25, 0.32);
	SSS_absorption = color(0.018, 0.088, 0.20);
} else if (SSS_type == "cream") {
	SSS_scatter = color(7.38, 5.47, 3.15);
	SSS_absorption = color(0.0002, 0.0028, 0.0163);
} else if (SSS_type == "ketchup") {
	SSS_scatter = color(0.18, 0.07, 0.03);
	SSS_absorption = color(0.061, 0.97, 1.45);
} else if (SSS_type == "marble") {
	SSS_scatter = color(2.19, 2.62, 3.00);
	SSS_absorption = color(0.0021, 0.0041, 0.0071);
} else if (SSS_type == "potato") {
	SSS_scatter = color(0.68, 0.70, 0.55);
	SSS_absorption = color(0.0024, 0.009, 0.12);
} else if (SSS_type == "skimmilk") {
	SSS_scatter = color(0.70, 1.22, 1.9);
	SSS_absorption = color(0.0014, 0.0025, 0.0142);
} else if (SSS_type == "skin1") {
	SSS_scatter = color(0.74, 0.88, 1.01);
	SSS_absorption = color(0.032, 0.17, 0.48);
} else if (SSS_type == "skin2") {
	SSS_scatter = color(1.09, 1.59, 1.79);
	SSS_absorption = color(0.013, 0.07, 0.145);
} else if (SSS_type == "spectralon") {
	SSS_scatter = color(11.6, 20.4, 14.9);
	SSS_absorption = color(0, 0, 0);
} else if (SSS_type == "wholemilk") {
	SSS_scatter = color(2.55, 3.21, 3.77);
	SSS_absorption = color(0.0011, 0.0024, 0.014);
}
		if (reuse != 1) {
        float SSS_mult = SSS_weight;
        SSS_mult = (SSS_mult - 1)*(-1); // SSS_weight should be 0 for SSS and 1 for diffuse.
	SSS_Cl = subsurface( // performs subsurface with ptc 
                Ps, shading_normal,
                "coordsystem", coordsyst,
                "filename", filename,
                "scale", SSS_scale,
                "smooth", SSS_smooth,
		"scattering", SSS_scatter,
		"absorption", SSS_absorption,
                "ior", SSS_ior) * SSS_mult; // Multiply by the SSS_mult to control SSS intensity

		} else {
		texture3d(rebaked_file, Ps, shading_normal,
		"subsurface", SSS_Cl,
		"coordsystem", rebaked_coordsyst);
		}
        outputchannel("aov_SSS", SSS_Cl);
        if(composite == 1) {
            Cl = SSS_Cl;
        } else {
			Cl = Cl;
		}
        Ol = Ol;
		if(rebake == 1) {
			bake3d(rebaked_file, "", Ps,  shading_normal, 
			"subsurface", SSS_Cl,
			"coordsystem", rebaked_coordsyst,
			"interpolate", 1);
		}
      }
        
    }
 

NOTE: This has since been moved to:

http://blog.cameronleger.com/code/ptc_uber_shader/

NOTE: I’ve shrunk the code box for the two scripts. Instead of copying them, when you hover your mouse over them you should get a little box at the top right with icons. The far left icon will open the script itself in a new window. Use that to copy the script.

This is a shader I’ve been working on for a week or so at work. I’ve tested it in a few scenes and so far it’s all working correctly. This is a .sl shader for use with 3Delight, a RenderMan compliant renderer. Although, with some tweaking, it can work with any RenderMan compliant renderer. It’s been tested using 3Delight 9.0.69

What it is, is a shader which can do really anything you want it to with a point cloud (now referred to as PTC).

It’s an atmosphere shader that you can set as an override to encompass everything, or set on a per object basis.

Functionality:
• Baking PTC, whether just the points or points with shading information as well
• Ambient Occlusion
• Reflection Occlusion
• Glossy reflections
• Glossy refractions
• Image based lighting
• Global Illumination / Color Bleeding
• SSS
• Directional Occlusion

I have pragma annotations for just about everything. So, everything is grouped into categories. In each category of functionality, you have the values at your control for the effect. The values are given “nice” names and have tooltip descriptions of what the value does, and in some cases, the best and/or default value.

The shader includes AOVs for each pass. Each pass will render out the normal image with the effect you’ve chosen on top of it. You can also use AOVs to render out the image before the effects and the bare effect for compositing. The specific AOVs are documented inside of the shader, but I’ll also list them here.

1) aov_GI - The diffuse lighting and color bleeding from the GI pass
2) aov_AO - The occlusion part of either the OC pass or the occlusion from the GI pass
3) aov_RO - The reflection occlusion
4) aov_GRefl - The blurred reflections
5) aov_GRefr - The blurred refractions
6) aov_envcolor - The environment color from the GI pass if you're using it for lighting from a texture
7) aov_IBL - The lighting from the image in the IBL pass
8) aov_pre - The scene before the effects

PTC based effects are a two passed approach. First, you bake out the PTC, then you use the PTC. When baking, you need the two following attributes under PreWorldMEL:

RiAttribute -n "cull" -p "hidden" "integer" "0" -p "backfacing" "integer" "0";
RiAttribute -n "dice" -p "rasterorient" "integer" "0";

Also, under Advanced in the Render Pass settings of all the passes utilizing this shader, you must turn the AOVs to ALL AOVs and enable Standard Atmosphere Shader.

At work and at home, I make extensive use of Maya Projects. So in each project I have to make a template for the PTC_Baking pass. I recommend you make a template for it as well, so you don’t have to keep typing in the PreWorldMEL. Since I have to do this on a per project basis, I’ve made a quick MEL script that creates a 3Delight Render Pass for PTC_Baking. You can do this easily by saving a template of your pass, and then finding that .ma template pass, opening it, and copying the contents of that file into a shelf button. Or, you could use this MEL script and save it as a shelf button.

Note: That was created using Maya 8.5, you might want to try what I said earlier to make your own shelf button if that doesn’t work for you. Also, you have to set the camera to bake from and the render set override yourself.

Because of the way the script works and the AOVs, each image you render contains a normal render and the effect. So, by rendering AO, you’re also rendering the image to composite AO on top of with it. This makes the rendertime hit seem MUCH less. Also, if you’re using GI and plan to use AO as well, it’s best to turn on the AO for GI. They’ll both be calulated at the same time and it will save a lot of rendertime. For instance:

Rendertimes
Normal: 120 seconds
Baking: 160 seconds
AO: 180 seconds
GI: 192 seconds
GI & AO: 247 seconds

The baking pass also included the normal image, so really it was +40 seconds.
The AO also included the normal image, so AO added 60 seconds. GI added 72 seconds.
Rendering those separately would give you two sets of normal images and GI and AO, at 372 seconds.
Rendering them together also gives you the normal image, thus adding 127 seconds on top of the normal render, saving you much more time.

I’ve tested this on Maya 8.5 and 2010, Mac and Windows.

Future ideas for added functionality:
• Subsurface Scattering
• Converting to a light shader so we can also use atmosphere effects
• Figuring out how to get it to work with area lights

Finally, here’s the script.

UPDATE:10/19/2010
Added SSS to the PTC usage section
Glossy Reflections now composite on top, so you can control the reflectivity amount.
Should now work with all 3Delight materials AND mia materials.

UPDATE:11/2/2010
SSS fixed for the newest version
Numerous bug fixes

UPDATE:11/9/2010
Added directional occlusion, a tweak on occlusion that makes it kind of like a soft directional light
Fixed some hints on the Max Variation parameter
IBL may not have been working before
Samplebase isn’t a PTC option, oops

UPDATE:11/22/2010
Added the ability to rebake and reuse PTC data to save rendertime when multiple renders are needed

##    Main
#pragma annotation "grouping" "MAIN/composite;"
#pragma annotation composite "gadgettype=checkbox:0:1=custom value;label=Composite;hint=Add the effect on top of RGBA, otherwise just in the AOV;"
#pragma annotation "grouping" "MAIN/AO;"
#pragma annotation AO "gadgettype=checkbox:0:1=custom value;label=Ambient Occlusion;"
#pragma annotation "grouping" "MAIN/DO;"
#pragma annotation DO "gadgettype=checkbox:0:1=custom value;label=Directional Occlusion;"
#pragma annotation "grouping" "MAIN/RO;"
#pragma annotation RO "gadgettype=checkbox:0:1=custom value;label=Reflection Occlusion;"
#pragma annotation "grouping" "MAIN/GRefl;"
#pragma annotation GRefl "gadgettype=checkbox:0:1=custom value;label=Glossy Reflections;"
#pragma annotation "grouping" "MAIN/GRefr;"
#pragma annotation GRefr "gadgettype=checkbox:0:1=custom value;label=Glossy Refractions;"
#pragma annotation "grouping" "MAIN/IBL;"
#pragma annotation IBL "gadgettype=checkbox:0:1=custom value;label=Image Based Lighting;"
#pragma annotation "grouping" "MAIN/GI;"
#pragma annotation GI "gadgettype=checkbox:0:1=custom value;label=Color Bleeding (GI);"
#pragma annotation "grouping" "MAIN/SSS;"
#pragma annotation SSS "gadgettype=checkbox:0:1=custom value;label=Subsurface Scattering;"
#pragma annotation "grouping" "MAIN/bake;"
#pragma annotation bake "gadgettype=checkbox:0:1=custom value;label=Bake PTC Map;"
#pragma annotation "grouping" "MAIN/filename;"
#pragma annotation filename "gadgettype=inputfile;label=PTC Files;hint=A previously rendered .ptc file. A .ptc with color and direct lighting baked in is needed for GI and can be used by all, but only point values are needed for AO. Also, if you have multiple PTC files, separate them with a ;"
#pragma annotation "grouping" "MAIN/rebake;"
#pragma annotation rebake "gadgettype=checkbox:0:1=custom value;label=Rebake PTC Map;"
#pragma annotation "grouping" "MAIN/reuse;"
#pragma annotation reuse "gadgettype=checkbox:0:1=custom value;label=Reuse PTC Map;"
#pragma annotation "grouping" "MAIN/coordsyst;"
#pragma annotation coordsyst "gadgettype=inputfile;label=Coordinate System;hint=Default 'world'. The coordinate system used by the point cloud."
#pragma annotation "grouping" "MAIN/envmap;"
#pragma annotation envmap "gadgettype=inputfile;label=ENV File;hint=A .tdl environment map made from 3Delight's tdlmake. If this is loaded it, it will be used for whatever you have actived and gets used if a ray doesn't hit an object.."
#pragma annotation "grouping" "MAIN/envspace;"
#pragma annotation envspace "gadgettype=inputfile;label=Coordinate System;hint=Default 'world'. The coordinate system used by the environment map."
##    AO
#pragma annotation "grouping" "AO/AO_tex;"
#pragma annotation AO_tex "gadgettype=inputfile;label=Alpha;hint=A .tdl image for controlling the AO effect, black for none and white for full."
#pragma annotation "grouping" "AO/AO_hitsides;"
#pragma annotation AO_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "AO/AO_maxdist;"
#pragma annotation AO_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e2. Change this based on the scale of your scene."
#pragma annotation "grouping" "AO/AO_falloff;"
#pragma annotation AO_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "AO/AO_falloffmode;"
#pragma annotation AO_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "AO/AO_coneangle;"
#pragma annotation AO_coneangle "gadgettype=floatslider;min=0;max=360;label=Cone Angle;hint=Solid angle considered per point. Default is a hemishpere (180 degrees)."
#pragma annotation "grouping" "AO/AO_bias;"
#pragma annotation AO_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface to prevent self-occlusion on curved surfaces. Usually 0.0 - 0.01. Lower values will get rid of white lines in corners."
#pragma annotation "grouping" "AO/AO_clamp;"
#pragma annotation AO_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Reducing over-occlusion. Doubles render time but much better results."
#pragma annotation "grouping" "AO/AO_maxsolidangle;"
#pragma annotation AO_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Good values between 0.03 and 0.2 Higher values are faster."
#pragma annotation "grouping" "AO/AO_maxvariation;"
#pragma annotation AO_maxvariation "gadgettype=floatfield;label=Max Variation;hint=Interpolates low variations. Values around 30 are up to twice as fast to render but look almost the same."
##    DO
#pragma annotation "grouping" "DO/DO_tex;"
#pragma annotation DO_tex "gadgettype=inputfile;label=Alpha;hint=A .tdl image for controlling the DO effect, black for none and white for full."
#pragma annotation "grouping" "DO/DO_hitsides;"
#pragma annotation DO_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "DO/DO_dir;"
#pragma annotation DO_dir "label=Direction;hint=Direction of occlusion in world space, coming from the point at XYZ."
#pragma annotation "grouping" "DO/DO_maxdist;"
#pragma annotation DO_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e2. Change this based on the scale of your scene."
#pragma annotation "grouping" "DO/DO_falloff;"
#pragma annotation DO_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "DO/DO_falloffmode;"
#pragma annotation DO_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "DO/DO_coneangle;"
#pragma annotation DO_coneangle "gadgettype=floatslider;min=0;max=360;label=Cone Angle;hint=Solid angle considered per point. Default is a hemishpere (180 degrees)."
#pragma annotation "grouping" "DO/DO_bias;"
#pragma annotation DO_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface to prevent self-occlusion on curved surfaces. Usually 0.0 - 0.01. Lower values will get rid of white lines in corners."
#pragma annotation "grouping" "DO/DO_clamp;"
#pragma annotation DO_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Reducing over-occlusion. Doubles render time but much better results."
#pragma annotation "grouping" "DO/DO_maxsolidangle;"
#pragma annotation DO_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Good values between 0.03 and 0.2 Higher values are faster."
#pragma annotation "grouping" "DO/DO_maxvariation;"
#pragma annotation DO_maxvariation "gadgettype=floatfield;label=Max Variation;hint=Interpolates low variations. Values around 30 are up to twice as fast to render but look almost the same."
##    RO
#pragma annotation "grouping" "RO/RO_tex;"
#pragma annotation RO_tex "gadgettype=inputfile;label=Alpha;hint=A .tdl image for controlling the RO effect, black for none and white for full."
#pragma annotation "grouping" "RO/RO_hitsides;"
#pragma annotation RO_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "RO/RO_maxdist;"
#pragma annotation RO_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e15. Change this based on the scale of your scene."
#pragma annotation "grouping" "RO/RO_falloff;"
#pragma annotation RO_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "RO/RO_falloffmode;"
#pragma annotation RO_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "RO/RO_coneangle;"
#pragma annotation RO_coneangle "gadgettype=floatfield;label=Cone Angle;hint=Value in radians of the cone angle. Smaller values are better for Reflection Occlusion. Default 30"
#pragma annotation "grouping" "RO/RO_bias;"
#pragma annotation RO_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface to prevent self-occlusion on curved surfaces. Usually 0.0 - 0.01. Lower values will get rid of white lines in corners."
#pragma annotation "grouping" "RO/RO_clamp;"
#pragma annotation RO_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Reducing over-occlusion. Doubles render time but much better results."
#pragma annotation "grouping" "RO/RO_maxsolidangle;"
#pragma annotation RO_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Should use very low values for Reflection Occlusion. Default .005."
##    GRefl
#pragma annotation "grouping" "GRefl/GRefl_tex;"
#pragma annotation GRefl_tex "gadgettype=inputfile;label=Alpha;hint=A .tdl image for controlling the glossy reflection effect, black for none and white for full."
#pragma annotation "grouping" "GRefl/GRefl_amnt;"
#pragma annotation GRefl_amnt "gadgettype=floatslider;min=0;max=1;label=Amount;hint=How reflective the surface is."
#pragma annotation "grouping" "GRefl/GRefl_hitsides;"
#pragma annotation GRefl_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "GRefl/GRefl_maxdist;"
#pragma annotation GRefl_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e15. Change this based on the scale of your scene."
#pragma annotation "grouping" "GRefl/GRefl_falloff;"
#pragma annotation GRefl_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "GRefl/GRefl_falloffmode;"
#pragma annotation GRefl_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "GRefl/GRefl_coneangle;"
#pragma annotation GRefl_coneangle "gadgettype=floatfield;label=Cone Angle;hint=Value of the cone angle. Smaller values are preferred. The larger the value the blurrier the reflections. Default 30"
#pragma annotation "grouping" "GRefl/GRefl_bias;"
#pragma annotation GRefl_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface to prevent self-occlusion on curved surfaces. Usually 0.0 - 0.01. Lower values will get rid of white lines in corners."
#pragma annotation "grouping" "GRefl/GRefl_clamp;"
#pragma annotation GRefl_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Reducing over-occlusion. Doubles render time but much better results."
#pragma annotation "grouping" "GRefl/GRefl_sort;"
#pragma annotation GRefl_sort "gadgettype=checkbox:0:1=custom value;label=Sorting;hint=Clamping must be on for this to have an effect. The color bleed is sorted by distance and gives more correct colors and shadows."
#pragma annotation "grouping" "GRefl/GRefl_maxsolidangle;"
#pragma annotation GRefl_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Should use very low values. Default .005."
##    GRefr
#pragma annotation "grouping" "GRefr/GRefr_tex;"
#pragma annotation GRefr_tex "gadgettype=inputfile;label=Alpha;hint=A .tdl image for controlling the glossy refraction effect, black for none and white for full."
#pragma annotation "grouping" "GRefr/GRefr_readme;"
#pragma annotation GRefr_readme "gadgettype=floatfield;label=README;hint=For this to work properly, THE OBJECT WITH THIS EFFECT ON IT SHOULD NOT BE IN THE POINT CLOUD."
#pragma annotation "grouping" "GRefr/GRefr_int;"
#pragma annotation GRefr_int "gadgettype=floatfield;label=Intensity;hint=Intensity of the effect;"
#pragma annotation "grouping" "GRefr/GRefr_ior;"
#pragma annotation GRefr_ior "gadgettype=floatfield;label=IOR;hint=Index of Refraction;"
#pragma annotation "grouping" "GRefr/GRefr_hitsides;"
#pragma annotation GRefr_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "GRefr/GRefr_maxdist;"
#pragma annotation GRefr_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e15. Change this based on the scale of your scene."
#pragma annotation "grouping" "GRefr/GRefr_falloff;"
#pragma annotation GRefr_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "GRefr/GRefr_falloffmode;"
#pragma annotation GRefr_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "GRefr/GRefr_coneangle;"
#pragma annotation GRefr_coneangle "gadgettype=floatfield;label=Cone Angle;hint=Value of the cone angle. Smaller values are preferred. The larger the value the blurrier the refractions. Default 30"
#pragma annotation "grouping" "GRefr/GRefr_bias;"
#pragma annotation GRefr_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface to prevent self-occlusion on curved surfaces. Usually 0.0 - 0.01. Lower values will get rid of white lines in corners."
#pragma annotation "grouping" "GRefr/GRefr_clamp;"
#pragma annotation GRefr_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Reducing over-occlusion. Doubles render time but much better results."
#pragma annotation "grouping" "GRefr/GRefr_sort;"
#pragma annotation GRefr_sort "gadgettype=checkbox:0:1=custom value;label=Sorting;hint=Clamping must be on for this to have an effect. The color bleed is sorted by distance and gives more correct colors and shadows."
#pragma annotation "grouping" "GRefr/GRefr_maxsolidangle;"
#pragma annotation GRefr_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Should use very low values. Default .005."
##    IBL
#pragma annotation "grouping" "IBL/IBL_tex;"
#pragma annotation IBL_tex "gadgettype=inputfile;label=Alpha;hint=A .tdl image for controlling the IBL effect, black for none and white for full."
#pragma annotation "grouping" "IBL/IBL_int;"
#pragma annotation IBL_int "gadgettype=floatfield;label=Intensity;hint=Use this to brighten or darken the result as needed."
#pragma annotation "grouping" "IBL/IBL_hitsides;"
#pragma annotation IBL_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "IBL/IBL_maxdist;"
#pragma annotation IBL_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e15. Change this based on the scale of your scene."
#pragma annotation "grouping" "IBL/IBL_falloff;"
#pragma annotation IBL_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "IBL/IBL_falloffmode;"
#pragma annotation IBL_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "IBL/IBL_coneangle;"
#pragma annotation IBL_coneangle "gadgettype=floatslider;min=0;max=360;label=Cone Angle;hint=Solid angle considered per point. Default is a hemishpere (180 degrees)."
#pragma annotation "grouping" "IBL/IBL_bias;"
#pragma annotation IBL_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface. Usually 0.0 - 0.01. Go as low as you can go without artifacts."
#pragma annotation "grouping" "IBL/IBL_clamp;"
#pragma annotation IBL_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Doubles render time but much better results."
#pragma annotation "grouping" "IBL/IBL_maxsolidangle;"
#pragma annotation IBL_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Good values between 0.03 and 0.1 Higher values are faster."
#pragma annotation "grouping" "IBL/IBL_maxvariation;"
#pragma annotation IBL_maxvariation "gadgettype=floatfield;label=Max Variation;hint=Interpolates low variations. Values around 30 are up to twice as fast to render but look almost the same."
##    GI
#pragma annotation "grouping" "GI/GI_tex;"
#pragma annotation GI_tex "gadgettype=inputfile;label=Alpha;hint=A .tdl image for controlling the global illumination effect, black for none and white for full."
#pragma annotation "grouping" "GI/GI_intensity;"
#pragma annotation GI_intensity "gadgettype=floatfield;label=Intensity;hint=Multiplied by the GI result. Default is 1."
#pragma annotation "grouping" "GI/GI_hitsides;"
#pragma annotation GI_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "GI/GI_maxdist;"
#pragma annotation GI_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e15. Change this based on the scale of your scene."
#pragma annotation "grouping" "GI/GI_falloff;"
#pragma annotation GI_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "GI/GI_falloffmode;"
#pragma annotation GI_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "GI/GI_coneangle;"
#pragma annotation GI_coneangle "gadgettype=floatslider;min=0;max=360;label=Cone Angle;hint=Solid angle considered per point. Default is a hemishpere (180 degrees)."
#pragma annotation "grouping" "GI/GI_bias;"
#pragma annotation GI_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface. Usually 0.0 - 0.01. Go as low as you can go without artifacts."
#pragma annotation "grouping" "GI/GI_clamp;"
#pragma annotation GI_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Doubles render time but much better results."
#pragma annotation "grouping" "GI/GI_sort;"
#pragma annotation GI_sort "gadgettype=checkbox:0:1=custom value;label=Sorting;hint=Clamping must be on for this to have an effect. The color bleed is sorted by distance and gives more correct colors and shadows."
#pragma annotation "grouping" "GI/GI_maxsolidangle;"
#pragma annotation GI_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Good values between 0.03 and 0.1 Higher values are faster."
## GI AO
#pragma annotation "grouping" "GI/AO/GI_AO_tex;"
#pragma annotation GI_AO_tex "gadgettype=inputfile;label=Alpha;hint=A .tdl image for controlling the AO effect, black for none and white for full."
#pragma annotation "grouping" "GI/AO/GI_AO;"
#pragma annotation GI_AO "gadgettype=checkbox:0:1=custom value;label=Ambient Occlusion w/ GI;"
#pragma annotation "grouping" "GI/AO/GI_AO_hitsides;"
#pragma annotation GI_AO_hitsides "gadgettype=optionmenu:front:back:both;label=Hitsides;hint=Which side of point sample is used."
#pragma annotation "grouping" "GI/AO/GI_AO_maxdist;"
#pragma annotation GI_AO_maxdist "gadgettype=floatfield;label=Max Distance;hint=Only consider intersections inside this distance. Default 1e2. Change this based on the scale of your scene."
#pragma annotation "grouping" "GI/AO/GI_AO_falloff;"
#pragma annotation GI_AO_falloff "gadgettype=floatfield;label=Falloff;hint=Shapes the curve of falloff. Set to 1 for linear falloff."
#pragma annotation "grouping" "GI/AO/GI_AO_falloffmode;"
#pragma annotation GI_AO_falloffmode "gadgettype=floatslider;min=0;max=1;label=Falloff Mode;hint=0 is exponential. 1 is polynomial."
#pragma annotation "grouping" "GI/AO/GI_AO_coneangle;"
#pragma annotation GI_AO_coneangle "gadgettype=floatslider;min=0;max=360;label=Cone Angle;hint=Solid angle considered per point. Default is a hemishpere (180 degrees)."
#pragma annotation "grouping" "GI/AO/GI_AO_bias;"
#pragma annotation GI_AO_bias "gadgettype=floatfield;label=Bias;hint=Offsets points above surface. Usually 0.0 - 0.01. Go as low as you can go without artifacts."
#pragma annotation "grouping" "GI/AO/GI_AO_clamp;"
#pragma annotation GI_AO_clamp "gadgettype=checkbox:0:1=custom value;label=Clamping;hint=Doubles render time but much better results."
#pragma annotation "grouping" "GI/AO/GI_AO_maxsolidangle;"
#pragma annotation GI_AO_maxsolidangle "gadgettype=floatfield;label=Max Solid Angle;hint=Time vs Quality. Good values between 0.03 and 0.1 Higher values are faster."
#pragma annotation "grouping" "GI/AO/GI_AO_maxvariation;"
#pragma annotation GI_AO_maxvariation "gadgettype=floatfield;label=Max Variation;hint=Interpolates low variations. Values around 30 are up to twice as fast to render but look almost the same."
##    SSS
#pragma annotation "grouping" "SSS/SSS_ior;"
#pragma annotation SSS_ior "gadgettype=floatfield;label=IOR;hint=Index of Refraction. Looks-wise, lower values are more contrasty and higher values produce a more even look with more scattering."
#pragma annotation "grouping" "SSS/SSS_scale;"
#pragma annotation SSS_scale "gadgettype=floatfield;label=Scale;hint=The scale the SSS is computed at, default 1 at millimeters. Higher values produce more scattering and make it look waxier."
#pragma annotation "grouping" "SSS/SSS_type;"
#pragma annotation SSS_type "gadgettype=optionmenu:apple:chicken1:chicken2:cream:ketchup:marble:potato:skimmilk:skin1:skin2:spectralon:wholemilk:custom;label=Preset;hint=Presets. If you choose custom, you can input values in the CUSTOM section. Default CUSTOM values are for skin2"
#pragma annotation "grouping" "SSS/CUSTOM/SSS_abs;"
#pragma annotation SSS_abs "gadgettype=colorslider;label=Absorption;hint=Absorption Coefficient."
#pragma annotation "grouping" "SSS/CUSTOM/SSS_sct;"
#pragma annotation SSS_sct "gadgettype=colorslider;label=Scattering;hint=Scattering Coefficient."
#pragma annotation "grouping" "SSS/SSS_smooth;"
#pragma annotation SSS_smooth "gadgettype=floatfield;label=Smoothing;hint=How much to smooth, from 0 being not and 1 being fully smoothed."
#pragma annotation "grouping" "SSS/SSS_weight;"
#pragma annotation SSS_weight "gadgettype=floatfield;label=Diffuse Weight;hint=How much of the diffuse is considered. 1 is purely diffuse, 0 is purely SSS"
## BAKING
#pragma annotation "grouping" "BAKING/readme;"
#pragma annotation readme "gadgettype=floatfield;label=README;hint=Select one. You MUST add the attributes at the top of the shader file comments to your PreWorldMEL. Use Shading Rate and Image Resolution to control PTC Density. If you're having artifact problems, just increase the PTC density if decreasing the bias doesn't help. It's also important to pick a camera that can 'see' everything you need a PTC for in the scene."
#pragma annotation "grouping" "BAKING/bake_AREA;"
#pragma annotation bake_AREA "gadgettype=checkbox:0:1=custom value;label=Bake area data;hint=This can be used for occlusion and lighting occlusion style with HDRI."
#pragma annotation "grouping" "BAKING/bake_COLOR;"
#pragma annotation bake_COLOR "gadgettype=checkbox:0:1=custom value;label=Bake color/area data;hint=This is needed for GI but can also be used for everything else."
#pragma annotation "grouping" "BAKING/bake_file;"
#pragma annotation bake_file "gadgettype=inputfile;label=PTC Filename;hint=Where the .ptc file gets baked to."
#pragma annotation "grouping" "BAKING/bake_coordsyst;"
#pragma annotation bake_coordsyst "gadgettype=inputfile;label=Coordinate system;hint=Which coordsystem to bake to. Default world."
## REBAKING
#pragma annotation "grouping" "REUSING/rebaked_file;"
#pragma annotation rebaked_file "gadgettype=inputfile;label=PTC Filename;hint=Where the .ptc file gets baked to."
#pragma annotation "grouping" "REUSING/rebaked_coordsyst;"
#pragma annotation rebaked_coordsyst "gadgettype=inputfile;label=Coordinate system;hint=Which coordsystem to bake to. Default world."


volume
    cl_ptc_uber (
                string filename = "<project>/3delight/<scene>/ptc/<scene>.#.ptc",
                envmap = "",
                coordsyst = "world",
                envspace = "world",
                AO_hitsides = "both",
		AO_tex = "",
		DO_tex = "",
		RO_tex = "",
		GRefl_tex = "",
		GRefr_tex = "",
		IBL_tex = "",
		GI_tex = "",
		GI_AO_tex = "",
		SSS_tex = "";
                float composite = 0,
		AO_maxdist = 1e2,
                AO_coneangle = 180, 
                AO_falloff = 1, 
                AO_falloffmode = 1,
                AO_bias = 0.01,
                AO_clamp = 1, 
                AO_maxsolidangle = 0.05,
                AO_maxvariation = 0,
                AO = 0;
                string DO_hitsides = "both";
                float DO_maxdist = 1e2,
                DO_coneangle = 180, 
                DO_falloff = 1, 
                DO_falloffmode = 1,
                DO_bias = 0.01,
                DO_clamp = 1, 
                DO_maxsolidangle = 0.05,
                DO_maxvariation = 0,
                DO = 0;
                normal DO_dir = normal "world" (0,1,-2);
                string RO_hitsides = "both";
                float RO_maxdist = 1e15, 
                RO_falloff = 1, 
                RO_falloffmode = 1,
                RO_bias = 0.01,
                RO_clamp = 1, 
                RO_maxsolidangle = 0.05,
                RO_coneangle = 0.2,
                RO = 0;
                string GRefl_hitsides = "both";
                float GRefl_maxdist = 1e15,
                GRefl_amnt = 1, 
                GRefl_falloff = 1, 
                GRefl_falloffmode = 1,
                GRefl_bias = 0.01,
                GRefl_clamp = 1,
                GRefl_sort = 1, 
                GRefl_maxsolidangle = 0.05,
                GRefl_coneangle = 30,
                GRefl = 0;
                string GRefr_hitsides = "both";
                float GRefr_maxdist = 1e15,
                GRefr_readme = 0,
                GRefr_int = .3,
                GRefr_ior = 1.1,
                GRefr_falloff = 1, 
                GRefr_falloffmode = 1,
                GRefr_bias = 0.01,
                GRefr_clamp = 1,
                GRefr_sort = 1, 
                GRefr_maxsolidangle = 0.05,
                GRefr_coneangle = 30,
                GRefr = 0;
                string IBL_hitsides = "both";
                float IBL_maxdist = 1e15,
                IBL_int = 1, 
                IBL_coneangle = 180,
                IBL_falloff = 1, 
                IBL_falloffmode = 1,
                IBL_bias = 0.01,
                IBL_clamp = 1,
                IBL_maxsolidangle = 0.05, 
                IBL_maxvariation = 0,
                IBL = 0;
                string GI_hitsides = "both";
                float GI_maxdist = 1e4,
                GI_intensity = 1,
                GI_falloff = 1,
                GI_falloffmode = 1,
                GI_bias = 0.045,
                GI_clamp = 1,
                GI_sort = 1,
                GI_coneangle = 180,
                GI_maxsolidangle = .2,
                GI = 0;
                string GI_AO_hitsides = "both";
                float GI_AO_coneangle = 180,
                GI_AO_clamp = 1,
                GI_AO_maxdist = 1e2,
                GI_AO_bias = 0.045,
                GI_AO_maxsolidangle = 0.2,
                GI_AO_falloff = 3,
                GI_AO_falloffmode = 1,
                GI_AO_maxvariation = .02,
                GI_AO = 0;
                string SSS_type = "skin1";
                color SSS_sct = color(1.09, 1.59, 1.79), 
		SSS_abs = color(0.013, 0.070, 0.145);
                float SSS_ior = 1.3,
                SSS_scale = 1,
                SSS_smooth = 0,
                SSS_weight = .4,
		SSS = 0;
                string bake_file = "<project>/3delight/<scene>/ptc/<scene>.#.ptc",
                bake_coordsyst = "world";
                float reuse = 0,
                rebake = 0;
                string rebaked_file = "<project>/3delight/<scene>/ptc/<scene>.#.rebake.ptc",
                rebaked_coordsyst = "world";
                float bake = 0,
                bake_COLOR = 0,
                bake_AREA = 0,
                readme = 0;
                output varying color aov_GI = 0;
                output varying color aov_envcolor = 0;
                output varying color aov_GRefl = 0;
                output varying color aov_GRefr = 0;
                output varying color aov_RO = 0;
                output varying color aov_IBL = 0;
                output varying color aov_SSS = 0;
                output varying color aov_AO = 1;
                output varying color aov_DO = 0;) 
    {
    normal shading_normal = normalize(N);
    color white = (1,1,1); // make a white color so we can mix with AO, when we multiply it will act as null
    color black = (0,0,0); // make a black color so we can use it to block out the areas if we do an add
      
      if(AO == 1) {
        if (reuse != 1) {
        aov_AO = Oi*(1 - occlusion( // performs occlusion with parameters from GUI
                P, shading_normal, 0,
                "pointbased", 1,
                "filename", filename,
                "coordsystem", coordsyst,
                "coneangle", radians(AO_coneangle),
                "hitsides", AO_hitsides,
                "maxdist", AO_maxdist,
                "falloff", AO_falloff,
                "falloffmode", AO_falloffmode,
                "bias", AO_bias,
                "clamp", AO_clamp,
                "maxsolidangle", AO_maxsolidangle,
                "maxvariation", AO_maxvariation));

        } else {
        texture3d(rebaked_file, P, shading_normal,
        "occlusion", aov_AO,
        "coordsystem", rebaked_coordsyst);
        }
	if(AO_tex != "") {
		color AO_texture = texture(AO_tex);  // Bring in the texture
		aov_AO = mix(white, aov_AO, AO_texture); // Mix between white and AO by the texture
	}
	if(composite==1) {
		Ci *= aov_AO;
	}
        if(rebake == 1) {
            bake3d(rebaked_file, "", P, shading_normal, 
            "occlusion", aov_AO,
            "coordsystem", rebaked_coordsyst,
            "interpolate", 1);
        }
      }

      if(DO == 1) {
        if (reuse != 1) {
        aov_DO = Oi*(1 - occlusion( // performs occlusion with parameters from GUI
                P, DO_dir, 0,
                "pointbased", 1,
                "filename", filename,
                "coordsystem", coordsyst,
                "coneangle", radians(DO_coneangle),
                "hitsides", DO_hitsides,
                "maxdist", DO_maxdist,
                "falloff", DO_falloff,
                "falloffmode", DO_falloffmode,
                "bias", DO_bias,
                "clamp", DO_clamp,
                "maxsolidangle", DO_maxsolidangle,
                "maxvariation", DO_maxvariation));

        } else {
        texture3d(rebaked_file, P, DO_dir,
        "occlusion", aov_DO,
        "coordsystem", rebaked_coordsyst);
        }
	if(DO_tex != "") {
		color DO_texture = texture(DO_tex);  // Bring in the texture
		aov_DO = mix(white, aov_DO, DO_texture); // Mix between white and DO by the texture
	}
	if(composite==1) {
		Ci *= aov_DO * Oi;
	}
        if(rebake == 1) {
            bake3d(rebaked_file, "", P, DO_dir, 
            "occlusion", aov_DO,
            "coordsystem", rebaked_coordsyst,
            "interpolate", 1);
        }
      }
      
      if(RO == 1) {
        normal Nn = normalize(N); // Normalize normals
        vector RO_refl = reflect(I, Nn); // Uses the reflected vector to compute occlusion, thus reflection occlusion
        if (reuse != 1) {
        aov_RO = Oi*(1 - occlusion(P, RO_refl, 0, 
                "pointbased", 1, 
                "filename", filename,
                "coordsystem", coordsyst,
                "hitsides", RO_hitsides,
                   "clamp", RO_clamp,
                "maxdist", RO_maxdist, 
                "falloff", RO_falloff,
                "falloffmode", RO_falloffmode,
                "coneangle", radians(RO_coneangle),
                "maxsolidangle", RO_maxsolidangle,
                "bias", RO_bias));
                
        } else {
        texture3d(rebaked_file, P, RO_refl,
        "occlusion", aov_RO,
        "coordsystem", rebaked_coordsyst);
        }
	if(RO_tex != "") {
		color RO_texture = texture(RO_tex);  // Bring in the texture
		aov_RO = mix(white, aov_RO, RO_texture); // Mix between white and RO by the texture
	}
	if(composite==1) {
        	Ci = aov_RO * Oi; // Just uses RO and opacity for the final image
	}
        if(rebake == 1) {
            bake3d(rebaked_file, "", P, RO_refl, 
            "occlusion", aov_RO,
            "coordsystem", rebaked_coordsyst,
            "interpolate", 1);
        }
      }
    
      if(GRefl == 1) {
        normal Nn = normalize(N); // Normalize normals 
        vector GRefl_refl = reflect(I, Nn); // Again, using a reflection vector for computation
        if (reuse != 1) {
        aov_GRefl = Oi*(indirectdiffuse(P, GRefl_refl, 0, 
                "pointbased", 1, 
                "filename", filename,
                "coordsystem", coordsyst,
                "hitsides", GRefl_hitsides, 
                "clamp", GRefl_clamp,
                "sortbleeding", GRefl_sort,
                "maxdist", GRefl_maxdist, 
                "falloff", GRefl_falloff,
                "falloffmode", GRefl_falloffmode,
                "coneangle", radians(GRefl_coneangle),
                "bias", GRefl_bias,
                "maxsolidangle", GRefl_maxsolidangle));

        } else {
        texture3d(rebaked_file, P, GRefl_refl,
        "reflection", aov_GRefl,
        "coordsystem", rebaked_coordsyst);
        }
	if(GRefl_tex != "") {
		color GRefl_texture = texture(GRefl_tex);  // Bring in the texture
		aov_GRefl = mix(black, aov_GRefl, GRefl_texture); // Mix between black and GRefl by the texture
	}
	if(composite==1) {
         	Ci = Oi * Ci + (aov_GRefl * GRefl_amnt); // GRefl are stored on top
	}
        if(rebake == 1) {
            bake3d(rebaked_file, "", P, GRefl_refl, 
            "reflection", aov_GRefl,
            "coordsystem", rebaked_coordsyst,
            "interpolate", 1);
        }
      }
    
      if(GRefr == 1) {
        if (reuse != 1) {
        extern point P;
        extern normal N;
        extern vector I;
        // normalizing
        normal Nn = normalize(N);
        vector IN = normalize(I);
        // stores reflection and refraction vectors
        vector reflDir, refrDir;
        float eta = (IN.Nn < 0) ? 1/GRefr_ior : GRefr_ior;
        float kr, kt;
        // computes fresnel effect
        fresnel(IN, Nn, eta, kr, kt, reflDir, refrDir);
        kt = 1 - kr; 
        
        vector RF = normalize(refrDir);
        color aov_GRefr = Oi*(kt*GRefr_int*indirectdiffuse(P, RF, 0, //glossy refractions
                "filename", filename, 
                "pointbased", 1,
                "hitsides", GRefr_hitsides, 
                "coneangle", radians(GRefr_coneangle),
                   "clamp", GRefr_clamp,
                 "coordsystem", coordsyst,
                  "sortbleeding", GRefr_sort,
                 "maxdist", GRefr_maxdist, 
                "falloff", GRefr_falloff,
                  "falloffmode", GRefr_falloffmode,
                "bias", GRefr_bias,
                   "maxsolidangle", GRefr_maxsolidangle));

        vector RL = normalize(reflDir);
        aov_GRefr += Oi*(kr*GRefr_int*indirectdiffuse(P, RL, 0, //glossy reflections on top
                "filename", filename, 
                "pointbased", 1,
                "hitsides", GRefr_hitsides, 
                "coneangle", radians(GRefr_coneangle),
                "clamp", GRefr_clamp,
                "coordsystem", coordsyst,
                "sortbleeding", GRefr_sort,
                "maxdist", GRefr_maxdist, 
                "falloff", GRefr_falloff,
                "falloffmode", GRefr_falloffmode,
                "bias", GRefr_bias,
                "maxsolidangle", GRefr_maxsolidangle));

        } else {
        texture3d(rebaked_file, P,  shading_normal,
        "refraction", aov_GRefr,
        "coordsystem", rebaked_coordsyst);
        }
	if(GRefr_tex != "") {
		color GRefr_texture = texture(GRefr_tex);  // Bring in the texture
		aov_GRefr = mix(black, aov_GRefr, GRefr_texture); // Mix between black and GRefr by the texture
	}
	if(composite==1) {
		Ci = aov_GRefr; // just use the refractions/reflections for output
	}
        if(rebake == 1) {
            bake3d(rebaked_file, "", P, shading_normal, 
            "refraction", aov_GRefr,
            "coordsystem", rebaked_coordsyst,
            "interpolate", 1);
        }

      }
      
      if(IBL == 1) {
        if (reuse != 1) {
        color IBL_envcol = 0;
        vector IBL_envdir = 0;
        aov_IBL = Oi*(IBL_int*occlusion( // performs occlusion from HDRI with parameters from GUI 
                P, shading_normal, 0, 
                "pointbased", 1, 
                "filename", filename,
                "coordsystem", coordsyst,
                "hitsides", IBL_hitsides,
                "maxdist", IBL_maxdist, 
                "coneangle", radians(IBL_coneangle),
                "falloff", IBL_falloff,
                "falloffmode", IBL_falloffmode,
                "bias", IBL_bias,
                "clamp", IBL_clamp,
                "maxsolidangle", IBL_maxsolidangle,
                "maxvariation", IBL_maxvariation,
                "environmentmap", envmap,
                "environmentcolor", IBL_envcol,
                "environmentdir", IBL_envdir));
        } else {
        texture3d(rebaked_file, P, shading_normal,
        "ibl", aov_IBL,
        "coordsystem", rebaked_coordsyst);
        }
	if(IBL_tex != "") {
		color IBL_texture = texture(IBL_tex);  // Bring in the texture
		aov_IBL = mix(white, aov_IBL, IBL_texture); // Mix between white and IBL by the texture
	}
	if(composite==1) {
        	Ci *= aov_IBL;
	}
        if(rebake == 1) {
            bake3d(rebaked_file, "", P,  shading_normal, 
            "ibl", aov_IBL,
            "coordsystem", rebaked_coordsyst,
            "interpolate", 1);
        }
      }
      
      if(GI == 1) {
        if (reuse != 1) {
        aov_GI = Oi*indirectdiffuse(P,  // performs color bleeding with parameters from GUI
                shading_normal, 0, 
                "pointbased", 1, 
                "filename", filename,
                "hitsides", GI_hitsides, 
                "coneangle", radians(GI_coneangle),
                "clamp", GI_clamp,
                "coordsystem", coordsyst,
                "sortbleeding", GI_sort,
                "maxdist", GI_maxdist, 
                "falloff", GI_falloff,
                "falloffmode", GI_falloffmode,
                "bias", GI_bias,
                "maxsolidangle", GI_maxsolidangle,
                "environmentmap", envmap,
                "environmentspace", envspace,
                "environmentcolor", aov_envcolor)*GI_intensity; // multiplied by GUI intensity controller

        if(GI_AO == 1){ // performs occlusion the same time as color bleeding for faster rendering
            aov_AO = Oi*1-occlusion(  //because we set aov_AO to 1 earlier, we subtract the occlusion from 1
                P, shading_normal, 0, 
                "pointbased", 1,
                "filename", filename,
                "hitsides", GI_AO_hitsides, 
                "coneangle", radians(GI_AO_coneangle),
                "clamp", GI_AO_clamp,
                "coordsystem", coordsyst,
                "maxdist", GI_AO_maxdist,
                "bias", GI_AO_bias,
                "maxsolidangle", GI_AO_maxsolidangle,
                "maxvariation", GI_AO_maxvariation,
                "falloff", GI_AO_falloff,
                "falloffmode", GI_AO_falloffmode);
        }
        } else {
        texture3d(rebaked_file, P, shading_normal,
        "indirectdiffuse", aov_GI,
        "coordsystem", rebaked_coordsyst);
        }
	if(GI_tex != "") {
		color GI_texture = texture(GI_tex);  // Bring in the texture
		aov_GI = mix(black, aov_GI, GI_texture); // Mix between black and GI by the texture
	}
	if(GI_AO_tex != "") {
		color GI_AO_texture = texture(GI_AO_tex);  // Bring in the texture
		aov_AO = mix(white, aov_AO, GI_AO_texture); // Mix between white and AO by the texture
	}
        aov_envcolor=Oi*aov_envcolor;
	if(composite==1) {
        	Ci += aov_GI * aov_AO; // Since we're doing AO and GI at the same time, multiply them onto each other, because we set aov_AO to 1 earlier, if there's no occlusion, it's multiplied by 1
	}
        if(rebake == 1) {
            bake3d(rebaked_file, "", P,  shading_normal, 
            "indirectdiffuse", aov_GI,
            "coordsystem", rebaked_coordsyst,
            "interpolate", 1);
        }
}
        
        if(SSS == 1) {
color SSS_scatter, SSS_absorption;
if (SSS_type == "custom") {
	SSS_scatter = SSS_sct;
	SSS_absorption = SSS_abs;
} else if (SSS_type == "apple") {
	SSS_scatter = color(2.29, 2.39, 1.97);
	SSS_absorption = color(0.003, 0.0034, 0.046);
} else if (SSS_type == "chicken1") {
	SSS_scatter = color(0.15, 0.21, 0.38);
	SSS_absorption = color(0.015, 0.077, 0.19);
} else if (SSS_type == "chicken2") {
	SSS_scatter = color(0.19, 0.25, 0.32);
	SSS_absorption = color(0.018, 0.088, 0.20);
} else if (SSS_type == "cream") {
	SSS_scatter = color(7.38, 5.47, 3.15);
	SSS_absorption = color(0.0002, 0.0028, 0.0163);
} else if (SSS_type == "ketchup") {
	SSS_scatter = color(0.18, 0.07, 0.03);
	SSS_absorption = color(0.061, 0.97, 1.45);
} else if (SSS_type == "marble") {
	SSS_scatter = color(2.19, 2.62, 3.00);
	SSS_absorption = color(0.0021, 0.0041, 0.0071);
} else if (SSS_type == "potato") {
	SSS_scatter = color(0.68, 0.70, 0.55);
	SSS_absorption = color(0.0024, 0.009, 0.12);
} else if (SSS_type == "skimmilk") {
	SSS_scatter = color(0.70, 1.22, 1.9);
	SSS_absorption = color(0.0014, 0.0025, 0.0142);
} else if (SSS_type == "skin1") {
	SSS_scatter = color(0.74, 0.88, 1.01);
	SSS_absorption = color(0.032, 0.17, 0.48);
} else if (SSS_type == "skin2") {
	SSS_scatter = color(1.09, 1.59, 1.79);
	SSS_absorption = color(0.013, 0.07, 0.145);
} else if (SSS_type == "spectralon") {
	SSS_scatter = color(11.6, 20.4, 14.9);
	SSS_absorption = color(0, 0, 0);
} else if (SSS_type == "wholemilk") {
	SSS_scatter = color(2.55, 3.21, 3.77);
	SSS_absorption = color(0.0011, 0.0024, 0.014);
}
        if (reuse != 1) {
        aov_SSS = Oi*(subsurface( // performs subsurface with ptc 
                P, shading_normal, 
                "coordsystem", coordsyst,
                "filename", filename,
                "scale", SSS_scale,
                "smooth", SSS_smooth,
		"scattering", SSS_scatter,
		"absorption", SSS_absorption,
                "ior", SSS_ior));
        } else {
        texture3d(rebaked_file, P, shading_normal,
        "subsurface", aov_SSS,
        "coordsystem", rebaked_coordsyst);
        }
	if(SSS_tex != "") {
		color SSS_texture = texture(SSS_tex);  // Bring in the texture
		aov_SSS = mix(black, aov_SSS, SSS_texture); // Mix between white and DO by the texture
	}
	if(composite==1) {
        	Ci = mix( aov_SSS, Ci, SSS_weight )*Oi;
	}
        if(rebake == 1) {
            bake3d(rebaked_file, "", P,  shading_normal, 
            "subsurface", aov_SSS,
            "coordsystem", rebaked_coordsyst,
            "interpolate", 1);
        }
      }

        if(bake == 1){
            if ((bake_AREA == 1) && (bake_COLOR == 0)){ // If only AREA is selected, only give area
                float a, opacity;

                  a = area(P, "dicing"); // micropolygon area
                  opacity = 0.333333 * (Oi[0] + Oi[1] + Oi[2]); // average opacity
                 a *= opacity; // reduce area if non-opaque      

                  if (a > 0) // only bake if non-transparent
                       bake3d(bake_file, "",
                         P, N, 
                        "coordsystem", bake_coordsyst, 
                        "interpolate", 1, 
                        "_area", a,
			"_opacity", Oi);
            }
            else{ // if both, neither, or just COLOR was selected, default to the bake_COLOR
		float a, opacity;
                a = area(P, "dicing"); // micropolygon area
                opacity = 0.333333 * (Oi[0] + Oi[1] + Oi[2]); // average opacity
                a *= opacity; // reduce area if non-opaque    
                color c=0;
                surface("Ci", c);

                bake3d( bake_file, "", 
                    P, N, 
                    "coordsystem", bake_coordsyst,
                    "_radiosity", c, 
                    "interpolate", 1,
		    "_area", a,
		    "_opacity", Oi);
            }
      }

	Ci *= 1;
	Oi *= 1;
    }
 

Joe Alter’s Shave & Haircut works really well with 3Delight for Maya, if you can get a few things figured out.

First, it’s not as simple as making the hair and rendering it. There’s a few things you have to do in order to get everything working properly. I will assume you have already created your geometry, added hair, added lights, and are ready to render.

Depending on how complex you have your scene lit will depend on how complex this will be. The best way is to have lights which only light up a few objects each. This is the most efficient way to render. You can just put ALL the lights into a set and ALL the objects into a set, but that’s your rendertime, not mine.

So. Select the lights which are effecting the hair and the objects that the hairs shadow will fall upon. Goto Create >Sets > Set to put them into a set. Call it whatever you want, something like hairLights. Now, select all the objects the hair will cast a shadow onto and the hair itself. It is best to do this selection in the viewport, because the hair node you need is the one you get when you select the hair by one of it’s hairs. Create a set for this, and call if something like hairShadowObjects. Select these objects again, and with the 3Delight Assignment Panel assign an Attribs thing to them. Call it what you want, and then press the AE button to open it in the Attribute Editor.

Add the attribute for Lighting > Illumination From. Select the hairLight set in the option menu for that attribute. Add a surface shader. For the hair shader, choose the one in the list called Shave. Now, select the lights that are in the light set. Turn on their depth map shadows. In the 3Delight Assignment Panel, assign Attribs. Press AE for the Attribs and turn on Generate Shadow Maps. Change the Type to Deep. Then, under Shadow Objects, change the set to the hairShadowObjects.

Now, you can render and you SHOULD be getting normal shadows from the hair onto itself and other objects.

 

If you’ve tried to open a Maya 2011 .mb or .ma file in a previous version, most likely you have lost a lot of information. At first glance its scary because you only have the outlines of your models, even in shaded mode. Its easy to think you’ve lost all your polygons. Also, a lot of connections, like expressions, are lost.

Don’t worry, I’ve come up with a solution. Here at work, we have an older non-intel Mac which can’t handle Maya 2011, so we do a lot of cross-version stuff. It got to the point where I had to come up with a solution. And here it is.

This will require a text editor of your choice, and the Maya 2011 file saved as a .ma, or a Maya ASCII file.

Open up the .ma in the text editor (depending on how big the scene file is, this could take a while). Use the find function in your editor to locate “relationship”. Keep find next-ing it until you come to the very last line that has “relationship” on it. It should be something like “relationship “shadowlink” … ” You’ll also notice the previous few lines start with “relationship”.

Select these lines and delete them. If you’re tech savvy, you can write a script that will find and replace these lines in multiple files. The problem is, pre-Maya 2011, there is no “relationship” procedure. When Maya is reading the .ma, it stops at “relationship”. However, after “relationship”, is a lot of valuable information, like connections. So with these lines gone, Maya continues to read the file and hooks up all the connections, preserving your materials, expressions, and more.

Open it in an older Maya version and everything should be fine. You’ll notice in the script error, depending on how big your scene file is, a lot of errors saying the same thing for each object you have, something along the lines of an invalid name of attribute. These can generally be ignored. Your files should be fine.

However, if you have things like Animation layers which aren’t included in older Maya versions, you might get some other weird errors and loss of information, but this can’t be avoided.

© 2011 Cameron's Blog Suffusion theme by Sayontan Sinha