Here’s something I whipped up in a couple of hours earlier this morning.

A 3D character from Cyanide and Happiness composited onto a photo

It features a 3D character from the web comic, Cyanide and Happiness. I’ve rigged him and posed him sitting on something in the scene. I used a panoramic latitude longitude image for the environment’s lighting and 3Delight using my custom shaders. Here’s a few example passes that I also rendered out to help in the composite:

The character from Cyanide and Happiness is one that I modeled and rigged before for a different piece. I created this Cyanide and Happiness scene in 3D and composited it onto a photo I took as an exercise to use 3Delight with my custom point cloud based shaders to composite a 3D character onto a background photo-realistically.

 

It’s been a while since I’ve posted anything here, but I’ve been really busy. The fact that I do most of this stuff when I’m at work means that when I’m at home, I don’t want to do it that much anymore. With that said, I’ve felt the urge to start something small here. Less time spend making things means more time spent observing things, and today I wanted to create something small. I used to love making interiors, and I haven’t gotten to do one lately. So, I decided to make a very quick (gave myself two hours) interior kitchen scene. After doing this, I realized that I could create a few very targeted interior scenes without putting days of work into each. So you might expect more from me in the next few weeks as I find some time.

3D Kitchen scene

Also, I’ve been doing a lot of things 3Delight related (including rewriting all of my shaders). Expect updates on those as well.

 

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.

 

Just posted a new script in the code section. You might have to refresh the blog to get it to show up in that menu, though.

Basically, it’s a python script for Maya that will randomize keyframe values and frames for the selected objects. Very useful if you have a lot of objects doing the same animation and you want to change it up a little so it’s not so mechanical.

 

Quite the update.

For one, www.cameronleger.com is now completely different. I have updated it to allow me to much easier add new content to it later on, and it looks a bit different.

This blog is now completely different.

Check out my demo reel. You can find it on my new website or watch it at the end of this post.

There’s a new navigation feature at the top of this site. It’s all outside links to my other information, except for that code tab.

That tab is now where all of my writing will go. I will post updates here about new things in there, but I will link directly to them because that is what I’ll be updating.

Let me know what you guys think.

httpvh://www.youtube.com/watch?v=djYeVGR0lic

 

Here’s the latest video I’ve been working on. It’s featuring the characters from the popular online comic site, Cyanide & Happiness. It’s kind of part of a series, so expect more of these animations. The only thing is, I’ll be pretty busy for a while so there might be some other stuff in between the next release. The usual, everything done in Maya, rendered with 3Delight.

httpvh://www.youtube.com/watch?v=T82-gJING-I

 

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;
    }
 

I’ve updated my website with two new videos from this last quarter of school. That’s basically what I’ve been up to for the past few months. Although a lot of work was put into them, they were still rushed. So, I’ll probably be revisiting them sometime in the future. For right now, I’m on a break, so I’m back to working on fun things. Expect a couple short animations pretty soon.

Check out the two newest videos in the Portfolio section of my site.

http://cameronleger.com/

 

Done. =]


© 2011 Cameron's Blog Suffusion theme by Sayontan Sinha