3ds Max Shaders for Stingray - Part 4 - Custom Shader
In this tutorial, we take a look at creating a custom DirectX Shader from scratch. This means that you will be creating a complete shader tree yourself without relying on the 3ds Max presets. This gives you full flexibility over the shader definition and what’s more, the end-result is guaranteed to be 100% compatible with Stingray.
Recorded in: 3ds Max 2017.1 & Stingray 1.6
This tutorial is intended for use with 3ds Max version 2017.1 Update or higher.
00:00:06 --> 00:00:14
In the last movie, you learn to create DirectX shader by using a preset and by modifying that preset slightly.
00:00:14 --> 00:00:20
Here, you build a complete shader tree from scratch to create sea or ocean water.
00:00:20 --> 00:00:28
In fact, the workflow you will be following is not original, it was first showcased by Dan Matlack on his Stingray channel.
00:00:28 --> 00:00:33
If you haven't checked out Dan's work, I strongly encourage you to do so.
00:00:36 --> 00:00:46
Whereas Dan builds his shader tree directly in Stingray, you will be building it in 3ds Max, thus confirming the perfect interoperability between the two apps.
00:00:50 --> 00:00:53
Continue with your scene from the last movie.
00:00:53 --> 00:00:59
Alternatively, you can start from an empty scene if you've already exported the docks and lampposts to Stingray.
00:01:00 --> 00:01:09
Create a Plane primitive to be used as a water surface. Zero it to the center of the world and make 1000mx1000m in size.
00:01:12 --> 00:01:17
Go to the Material Editor and create a new DirectX Shader in Stingray mode.
00:01:20 --> 00:01:22
Name it Ocean_Shader.
00:01:23 --> 00:01:33
Open the ShaderFX editor. As you learned before, the first thing to do when creating a Custom Shader is to dissociate it from presets and parent materials.
00:01:33 --> 00:01:41
Select the Standard Base output node and click the Make Unique button. Now you can edit the graph to your heart's content.
00:01:42 --> 00:01:48
Start by deleting all the middle nodes, basically removing everything from the tree except the input and output nodes.
00:01:49 --> 00:02:00
Select the output node again and note that it's set to Opaque. Since water is transparent and transparency varies with distance, choose the Transparent Fade option.
00:02:01 --> 00:02:09
Also, since you will eventually create the animated wave/reflections effect using a normal map, set the Normals space to Tangent.
00:02:10 --> 00:02:12
This will work better for this particular effect.
00:02:13 --> 00:02:22
Next you will need controls for water color, roughness, metalness and opacity. You will need a Material Variable node for each.
00:02:22 --> 00:02:26
You can get that by dragging it from the Node Browser,
00:02:29 --> 00:02:32
or you can use a right click.
00:02:34 --> 00:02:38
Start with a Color node, name it appropriately.
00:02:40 --> 00:02:49
If you try to hook it to the output's Base Color map, you will find that you can't. You have to explicitly define the variable type first.
00:02:49 --> 00:02:56
Since a color is usually expressed in RGB values (three values), set the node type to Vector 3.
00:02:57 --> 00:03:02
Now if you try to connect it to the Base Color channel, you wouldn't have any problems.
00:03:02 --> 00:03:09
Copy and paste (Ctrl+C & Ctrl+V) the node in the editor or create a new one.
00:03:10 --> 00:03:21
Rename it Opacity. Opacity is usually expressed as a number or a percentage, so set its type to Scalar and connect it to the proper channel.
00:03:23 --> 00:03:28
Repeat to create nodes for Metalness and Roughness.
00:03:34 --> 00:03:38
Leave some room in the graph to define the Normals tree.
00:03:42 --> 00:03:47
You need to blend normals to animate them in two different directions for a cool water effect.
00:03:48 --> 00:03:56
The Blend Normals node is found in the Utility section, add it to the graph and connect it to the Normal channel.
00:03:56 --> 00:04:03
You get an error as the note turns red, but that's only because you haven't provided inputs to that node yet.
00:04:03 --> 00:04:13
So you need to add a Sample Texture node found under Sampling. In fact you need two, one to provide a base texture, one for detail.
00:04:14 --> 00:04:19
The Sample Texture node will ultimately let you select a bitmap to be used for the normal effect.
00:04:19 --> 00:04:24
Name the first one Water_Normal_Base,
00:04:25 --> 00:04:29
and the second one Water_Normal_Detail.
00:04:30 --> 00:04:39
To create the animated effect, you need to pan the texture, so go ahead and add a Panner node, also from the utility section.
00:04:40 --> 00:04:49
You need two in fact, so that they can affect both the base and the detail normal maps. Hook them to the UV channels so they can shift the pixels.
00:04:50 --> 00:04:56
Now zoom back if you need to and take a look at the Texcoord0 node that you left untouched at the beginning.
00:04:57 --> 00:05:01
This lets you access and manipulate UV coordinates on your model.
00:05:02 --> 00:05:10
In order to also add tiling functionality, start by adding a Multiply node, you'll find that under Math.
00:05:13 --> 00:05:19
Also add a Material Variable node and name it UV_Tiling_Base.
00:05:22 --> 00:05:28
Set it to Vector 2 type as you need two inputs for both U and V directions.
00:05:28 --> 00:05:38
By default, a Vector 2 variable ranges from 0 to 1 but set the Maximum value to about 50 or 100, so you can tile the map further more.
00:05:39 --> 00:05:48
Hook the Texccord and the tiling nodes to the Multiply input, and then hook the Multiply node to the Panner's UV Input.
00:05:49 --> 00:05:56
You still need a few additional inputs for the panner node; one is a Time input found under the Input section.
00:05:58 --> 00:06:05
You also need a couple of Material Variable nodes in Scalar type to control water speed in both U and V directions.
00:06:10 --> 00:06:14
Call them Speed_U_Base,
00:06:16 --> 00:06:19
00:06:27 --> 00:06:36
To complete the graph, copy the nodes under the first panner and paste them to feed the second panner.
00:06:42 --> 00:06:49
Just make sure you replace the "Base" suffix on the copied nodes with "Detail", to respect that second branch.
00:07:05 --> 00:07:12
In fact, you can go as far as using the same Texcoord0 input node for both branches for a cleaner tree.
00:07:16 --> 00:07:23
The work is done. If you want, you can export your graph so you can reuse it at a later time without having to recreate it.
00:07:24 --> 00:07:30
Name it: "Ocean.sfx". A version is already available in the archive you downloaded for this tutorial.
00:07:31 --> 00:07:36
Close the Shader Graph and apply the newly-created shader to the water surface in the scene.
00:07:36 --> 00:07:40
Before you send it to Stingray, here's one last piece of advice:
00:07:40 --> 00:07:45
When you mean to reuse a shader tree you've already exported to disk, do the following:
00:07:46 --> 00:07:49
Create a new DirectX shader in Stingray mode,
00:07:52 --> 00:07:54
and go to the ShaderFX editor.
00:07:55 --> 00:08:04
Select the output node (Standard_Base) and click the Make Unique button. This ensures you lose any links to presets and parent materials.
00:08:04 --> 00:08:09
Only then should you import your saved .sfx graph.
00:08:10 --> 00:08:15
It replaces your existing nodes and the shader is now completely independent.
00:08:16 --> 00:08:20
Okay, let's test our work:
00:08:22 --> 00:08:27
Make sure Stingray is running and that the scene you created in the last movie is opened.
00:08:28 --> 00:08:35
With the water surface selected in 3ds Max, use the Stingray menu to send the selection to Stingray as you've done before.
00:08:35 --> 00:08:41
Name the exported file: "Ocean" and use the same options as before.
00:08:41 --> 00:08:49
In Stingray, go to the content folder and drag the ocean unit into the scene and zero it out.
00:08:51 --> 00:08:56
If you need to, adjust your view so that you are standing on the pier looking out to the horizon.
00:08:57 --> 00:09:01
It would also be a good idea to remove the grid by pressing G.
00:09:02 --> 00:09:09
Make sure the water surface is still selected and note that the associated shader is in fact the Ocean Shader you created in 3ds Max.
00:09:10 --> 00:09:12
Its parameters just need a bit of refinement.
00:09:13 --> 00:09:17
Click the Go to Resource button to access the shader's paramaters.
00:09:18 --> 00:09:22
Most of the adjustments you need are based on numerical values and are easy enough to change.
00:09:23 --> 00:09:27
However, you do need a Normal Map to define the waves that will be animated.
00:09:27 --> 00:09:31
It's actually quite easy to create such a map, especially if you use Photoshop.
00:09:32 --> 00:09:39
In Photoshop, create a new document. It doesn't have to be too large, even a 512x512 pixel image will do.
00:09:40 --> 00:09:49
Make sure the Backward and Forward colors are set to black and white, and then use the Render Clouds filter to create what is essentially a noise map
00:09:50 --> 00:09:58
Once that is done, use either the NVidia Normals filter or Awesome Bump to turn this black and white image into a Normal map.
00:09:58 --> 00:10:04
Both versions of those normal maps are available in the archive you downloaded for this tutorial.
00:10:08 --> 00:10:16
Go to the Textures sub-folder of your Stingray project and drop your wave Normal map in it using Windows Explorer.
00:10:16 --> 00:10:22
Drag the Normal Map into the Water Normal Base and Water Normal Detail slots.
00:10:23 --> 00:10:30
Now you get to alter the other values. The color can remain black although I'm not a big fan of zero values.
00:10:30 --> 00:10:38
Set the RGB values to 0.01 for an extremely dark Gray, almost black water color.
00:10:38 --> 00:10:45
Next play with the Opacity value to change the transparency. A value of 0.8 should work well.
00:10:46 --> 00:10:57
Vary the tiling for the Base and Detail values. I'll set the Base range from 5 to 50 and the detail range from 40 to 50.
00:10:58 --> 00:11:07
Play with the speed values to animate the water. Use small values such as 0.01 or 0.02. Experiment a bit.
00:11:08 --> 00:11:15
Try a touch of metalness and roughness values. You may need to alter the position of the sun to see their effect.
00:11:15 --> 00:11:22
And there you have it. In this series you have built and imported a 3ds Max scene to Stingray, but more importantly,
00:11:22 --> 00:11:30
the materials applied to the geometry were based on the same DirectX Shader that is fully compatible between the two applications.
00:11:31 --> 00:11:39
This means you only had to build the scene in 3ds Max, without having to worry about any material conversion issues that require adjustments in Stingray.
00:11:39 --> 00:11:45
You have also learned a thing or two about PBR textures and material which I hope you have found useful.
00:11:46 --> 00:11:49
This brings us to the end of this series, I hope you have enjoyed it.