<< Click to Display Table of Contents >> Navigation: Simplygon API 7.1 User guide > Material Nodes |
An alternate way to define a specific material channel is by using a shading network. If a shading network is set for a material channel, this will be used instead of the legacy layered texture system.
Material nodes are systems that are used to generate a color for each surface element on a model. Some nodes will solely be used to create colors from pre-defined values or from the sampling of textures. Some nodes are designed to modify the values generated by other nodes. The nodes that modify color values have one or multiple input slots.
Every node outputs the same type of RGBA data, so every node can be plugged into any input slot. If an input slot doesn't have a node plugged into it, the slot will evaluate to a default value. This value can be set for every node's specific slot. A node may appear multiple times in the same node tree but may not be an ancestor to itself.
The material node network is identified by the last node in the network, which is referred to as the exit node. When each surface element is evaluated (for casting/rendering etc.) the entire node tree will be traversed from the exit node.
To use a node network as a material, the exit node is assigned to a selected channel in the IMaterial object using SetShadingNetwork()for the IMaterial.
See the MaterialNodeExample for a complete code example where a material node network is created from scratch and used in a scene - with shader code generation, rendering of a preview and casting a new texture.
ShadingTextureNode No input slots. Contains a texture name and a UV-set. The name set here is supposed to be a uniquely identifying name that is also present in the scenes texture table.
ShadingColorNode No input slots. Contains a color.
ShadingVertexColorNode No input slots. Contains an index to a vertex color.
ShadingInterpolateNode Three input slots. Will interpolate between the colors (pointwise) of slot0/slot1 using slot3.
ShadingClampNode Three input slots. Will clamp the color (pointwise) of slot0 using the slot1/slot2.
ShadingAddNode Two input slots. Will add the colors (pointwise) of slot0 and slot1.
ShadingSubtractNode Two input slots. Will subtract the color (pointwise) of slot0 with slot1.
ShadingMultiplyNode Two input slots. Will multiply the colors (pointwise) of slot0 and slot1.
ShadingDivideNode Two input slots. Will divide the color (pointwise) of slot0 with slot1.
spShadingNode CreateGroundMaterialNetwork()
{
spTextureNode DirtMap = sg->CreateTextureNode();
DirtMap->SetTextureLevel( 0 );
DirtMap->SetTexturePath( "dirt.png" );
spTextureNode NoiseMap = sg->CreateTextureNode();
DirtMap->SetTextureLevel( 1 );
DirtMap->SetTexturePath( "noise.png" );
SpInterpolateNode Ground = sg->CreateInterpolateNode();
Ground->SetInput( 0, DirtMap );
Ground->SetDefaultParameter( 1, 0.45f, 0.32f, 0.04f );
Ground->SetInput( 2, NoiseMap );
// Return the exit node
return spShadingNode( Ground );
}
void AddMaterialNodeNetworkToMaterial( spMaterial ground_material )
{
// Create a material node network consisting of an arbitrary
// amount of shading nodes
spShadingNode exit_node = CreateGroundMaterialNetwork();
// Assign the exit node of the material node network to the
// diffuse channel in the ground_material
ground_material->SetShadingNetwork( SG_MATERIAL_CHANNEL_DIFFUSE, exit_node );
}
Figure 6: Node concept diagram. Two textures nodes plugged into an interpolating node. The texture nodes don't have input slots, but they have settable paramaters.
Generating HLSL/GLSL shader code from material nodes
When a material node network has been created and assigned to a channel of a material. Simplygon can generate a shader used to render the material.
void GenerateShaderCode( spMaterial island_material )
{
// We create a shader data object
spShaderData island_shader = sg->CreateShaderData();
// We add the material to it
island_shader->SetMaterial( island_material );
// We tell the shader data object to traverse the material node tree
// and gather the information needed to create a shader from the nodes.
island_shader->GenerateShaderData();
// Once the GenerateShaderData() has been called, the shader data object
// will contain the information needed to setup the renderer for the
// GLSL or HLSL shader.
// Get all the texture paths that should be loaded and sent to the shader.
// The textures should be uploaded to the shader at the texture slot
// corresponding to its position in the collection.
spStringArray texture_paths_collection = island_shader->GetShaderInputTexturePaths();
// Get the UV sets that should be uploaded to the shader.
// The slot in the array corresponds to the slot in the shader.
// The values in the array corresponds to the tex coord level being used.
spRidArray UV_set_collection = island_shader->GetShaderInputUVSets();
// Get the vertex colors that should be uploaded to the shader.
// The slot in the array corresponds to the slot in the shader.
// The values in the array corresponds to the vertex color field being used.
spRidArray vertex_color_collection = island_shader->GetShaderInputVertexColors();
// Get the entire shader code for HLSL and GLSL.
spString hlsl_code = island_shader->GetHLSLCode();
spString glsl_vertex_code = island_shader->GetGLSLVertexCode();
spString glsl_fragment_code = island_shader->GetGLSLFragmentCode();
}