3Delight’s Physical Sun into DAZ Studio: a yet another Shader Builder mini-tutorial

If you have done my lens flare shader tutorial and want something else to play with, here is a how-to for a light that has long become a staple of my renders.

It is a yet another interesting light shader supplied with 3Delight Studio Pro: physicalsun.sl by the Jupiter Jazz group. As you can infer from the name, it simulates sunlight. If you have followed my previous Shader Builder tutorials, you should have no problem getting this sun to shine onto your DAZ Studio scenes.

PhysicalSun can be combined with just about any light shader you have. Here are a few test renders using PhysicalSun at different angles and settings, and omnifreaker’s UberSoftLightKit Master (environment) light set to do a combo of AO-based IBL and indirect lighting (with various “sky” colours); the scene is an old DAZ freebie called Seer’s Fountain with displacement applied (hence the seam issues).

physky_fix_noon_seamphysky_fix_notmorning_seamphysky_fix_sunset_seam

What you need:

– DAZ Studio with a working Shader Builder (the 4.8 beta won’t do; DAZ devs promise that the final release will have the plugin fixed, so let’s hope);
– an installation of 3Delight Studio Pro;
– a good text editor like Notepad++; RSL/RIB syntax highlighter recommended.

1) Locate the “shaders/src” folder in your 3DSP installation and copy the “physicalsun.sl” file to your working folder.
2) Open the file you just copied in your Notepad++ and take a long hard look at it. You will see a lot of functions; scroll down till you see the actual light shader heading with its parameters:


light physicalsun(
	float i_multiplier = 1.0;
	float i_rgb_unit_conversion[3] = {0, 0, 0};
	float i_haze = 0.0;
	float i_redblueshift = 0.0;
	float i_saturation = 0.7;
	float i_horizon_height = 0.0;
	float i_shadow_softness = 0.0;

	string i_shadowmap = "raytrace";
	float i_shadow_samples = 3;
	bool i_y_is_up = false; )
	

We don’t really need the unit conversion thing in DS, so we will kill that line and then edit the body to remove the reference. We should also do away with horizon height because it’s not appearing anywhere else in the shader. And as for the “up” vector, again, we’re setting the shader up to work in DS, so kill that line, too, and get these two in:


	point from = point "shader" ( 0, 0, 0 );
	point to = point "shader" ( 0, 0, -1 );
	

Then, you may need to use this light with shadow catchers one day, so let’s cover this as well. For this, we need to add an output variable to the shader. Thankfully, it’s easy to do in code. We just need to type this:


output varying color __inShadow = color (0,0,0);

The spelling of the variable name is important because DS shadow catchers are hardwired to call this particular one.

Here is what you should end up with:


light physicalsun(
	float i_multiplier = 1.0;
	float i_haze = 0.0;
	float i_redblueshift = 0.0;
	float i_saturation = 0.7;
	float i_shadow_softness = 0.0;
	point from = point "shader" ( 0, 0, 0 );
	point to = point "shader" ( 0, 0, -1 );
	string i_shadowmap = "raytrace";
	float i_shadow_samples = 3;
	output varying color __inShadow = color (0,0,0);
	)
	

Save the file.

3) Now let’s tell the shader where “axis” is. Find the comment that says “Compute the world space sun direction” (around line 115):


		// Compute the world space sun direction.
		uniform vector up = (i_y_is_up == true)
			? vector "shader" (0.0, 1.0, 0.0) : vector "shader" (0.0, 0.0, 1.0);
			

Replace these two lines of code with this:


		// Compute the world space sun direction.
		uniform vector axis = to - from;
		

In the solar() construct coming next, replace the “up” vector with the new “axis” one, like this:


		solar( axis, 0.0 )
		

Scroll down to find the “Compute the zenith angle of the sun, in radians” comment.


			// Compute the zenith angle of the sun, in radians.
			float cos_theta_sun = -L[1];
			

This is the cosine taken from the coordinates of light vector, but it’s defined in “current” aka camera space. We need to make sure this cosine value does not change with camera angle. So we should review vector algebra a bit: a dot product of two vectors divided by their lengths multiplied should give us the cosine we need. The other vector will be a (0,-1,0) vector in “world” space (remember I wrote a post about rotated coordinate systems? Here they go again).

Replace the line doing the cos_theta_sun calculation with these:

			// Compute the zenith angle of the sun, in radians.
			vector Y = vector "world" (0,-1,0);
			float cos_theta_sun = (axis.Y)/(length(axis)*length(Y));

Save the file.

4) Shadow calculation comes next. Remember we supplied the output variable that shadow catchers can read? Now we need to set its value. See the shadow() shadeop that feeds its results into the “shad” variable? (approx. lines 123-126) Right after that, make a new line and insert this code to share these results with the output:

			__inShadow = shad;

Save the file.

5) Find the “Rescale the final color” comment (around line 141). We don’t need that code, so erase everything up until applying the global multiplier – apart from just one line:


			// Rescale the final color.
				Cl *= 1.0 / 80000.0;

Save the file.

6) Launch DAZ Studio and open Shader Builder. Go to the “Light” category and create a new Distant Light type of shader with a name like “PhysSun_JupiterJazz”. The Designer window will pop up; right-click it and add your edited “physicalsun.sl” as a macro. As soon as it imports, connect its Cl output with the Cl on the “root” on the right.

7) Chances are you need to change the “i_shadowmap” macro input type to “string” and assign a constant value of “raytrace” to it. Double-click the macro editor, click on the “i_shadowmap” variable in the list at the top, change its type to “string”, accept everything DS offers. Then right-click the newly-blue dot, select “Constant value” and type “raytrace” there.

Save the network.

8) Now it’s time to check out the User Parameters. Double-click them to launch the editor.

We don’t supply a colour to the PhysicalSun – it calculates the correct one based on the angle and the haze etc settings. So we don’t need the Color parameter. But we need an output colour variable to communicate with shadow catchers, so here is what we do: change the label, name and variable to “__inShadow” (no quotes!), set it to “hidden”, then in the leftmost dropdown, we set the class to “none” (if we set the class first, we wouldn’t be able to hide the parameter); on the right, the default value should be 0, and type – “output varying” + “color”. Update the attributes.

You should also unhide the “__category” parameter, set it to belong to some group (“Light” should do) and assign a default empty string (“”) to it. Accept the edits and close the parameter editor.

9) The “Intensity” parameter can be connected to the “i_multiplier” variable (I set the default at 180%, but YMMV), and the __inShadow to its corresponding macro input. As for the other variables, it’s time to start doing the “connect/create user parameter” thing. In the user interface, they should all be float save for “i_shadow_samples” which is integer. It makes sense to put them all, apart from “i_shadow_softness” and “i_shadow_samples”, in the “Light” group, while those two go into the “Shadow” group. You could also set the default value for shadow softness to something like 0.02 (2%) and have it display itself in percent. As for shadow samples, the range could be from 0 to 512, and a nice default value is 64.

Save the network and compile the shader. You should see the empty “Log” tab. If you don’t, retrace your steps and see what you missed.

10) One day you may want to use this sun to get caustics via photon mapping. To add photon casting to the light, you will need to click back to the “Block Network” tab and right-click the empty space to add a rendertime script block. When it appears, connect it to where it belongs, then double-click it, erase whatever there is and insert this:

Shader.setStringAttrib( "light", "emitphotons", "on");

Save the network and compile shader.

11) Enjoy your new sun.

Tips:
– Just like with any other distant light, you can look through its light camera to point it where you want.
– The “haze” control will change the colour of sunlight as if it were shining through, well, haze. It won’t change shadow softness (this is controlled manually and separately).
– Positive values of “red/blue shift” will increase the red and decrease the blue in the sunlight; negative values will do it the other way around.
– Saturation will further control the light colour: the less saturation is, the closer it would be to white/gray.

Advertisements

Comment here

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s