Skip to content
On this page

Material casters

The material casting is a post-process of all mapping image generating processing objects, where the caller application can use the mapping image data to "cast" material and texture data from the original onto the processed geometry.

The casting process requires that the processing object has created a mapping image during the main processing. When creating new maps using material casting, opacity values can be baked down into either diffuse map's alpha value or baked down into a separate opacity map.

MaterialCaster class

All casting objects are derived from the MaterialCaster class, which implements the basic processing parameters of all casting objects and contains settings for the output image format.

When using a caster designed to transfer materials from the original to the output mesh, a reference to the original material table must be set. If the input materials in the material table are defined using shading networks rather than the legacy material system, a texture table containing all textures referenced by the texture nodes in the shading networks must also be created and supplied.

Source material casters

These casters bake material channels from the input scene to the processed scene, and hence require references to the input materials and textures.

  • Color caster
    General color casting (diffuse/basecolor/roughness etc.). If using the remesher, the color values will be accumulated through mapping image layers using the defined opacity channel.

  • Normal caster
    Specialized normal map casting. If there is a normal map setup in the source materials, these will be decoded and baked into the new tangentspace (or objectspace) of the result scene. If no source normal map is set, the geometry normals from the original scene is still baked down to the LOD. Simplygon requires full RGB(TBN) tangent space normal maps, so if you have compressed maps with only two channels, you'll have to calculate the missing channel before setting up the source textures.

  • Opacity caster
    Casts the opacity channel, which for the remesher will be an accumulated opacity through all mapping image layers.

  • Vertex color caster
    This caster is a bit different in that it does not actually generate an output imagedata, instead it bakes the input material channels to vertex colors in the output scene.

    Material casters

Other material casters

These casters do not require any references to the input materials and textures since they generate new data based on the input and output geometries.

  • Ambient occlusion caster
    This caster will compute ambient occlusion for the scene based on the original geometry and create an ambient occlusion texture.

  • Geometry data caster
    This caster can cast arbitrary geometry fields like the original texcoords to imagedata, allowing things like indirect texturing or manual runtime material casting.

  • Displacement caster
    Generates an output texture with vector data containing the displacement between the points on the original scene and the corresponding points on the LOD.

Compute Shader based casting

This is a specialized caster that uses Vulkan backend and compute shader for casting. Vulkan backend can either be a GPU or a software fallback (i.e Google's SwiftShader). See compute casting concepts for more details.

Usage examples

ColorCaster

The ColorCaster is used to cast material color information from the original geometries. The caster can cast ambient, diffuse, specular, emmisive and opacity color data. It is possible to add color data, which is set using the ColorType parameter.

When casting the specular channel, Simplygon will cast the shininess of the input materials into the alpha channel of the output texture if one is available. To get the correct result, the alpha component of the base-color of the destination material must be set to 128 to ensure correct scaling of the shininess factor when the texture is created. For an example of how to bake shininess, see the reduction example. Simplygon supports textures both with and without sRGB color format. Call SetsRGB to set whether textures are in sRGB format.

The following example shows how to use the IColorCaster to cast diffuse color data.

cpp
void CastDiffuseColorData( spMaterial output_material, spMappingImage mapping_image, spMaterialTable source_materials )
{
    // Cast diffuse texture data using a color caster.
    spColorCaster cast = sg->CreateColorCaster();       
    cast->SetColorType( SG_MATERIAL_CHANNEL_DIFFUSE );
    cast->SetSourceMaterials( source_materials );   
    // The mapping image from the process.
    cast->SetMappingImage( mapping_image );
    cast->SetOutputChannels( 3 ); // RGB, 3 channels
    cast->SetOutputChannelBitDepth( 8 ); // 8 bits per channel, 24bpp
    cast->SetOutputFilePath( "diffuse_out.png" );
    cast->CastMaterials();
    // Set the diffuse multiplier for the texture.
    // 1 means it will not differ from original texture,       
    // Example: 0 would ignore a specified color and
    // 2 would make a color twice as pronounced as the others.     
    output_material->SetColor( SG_MATERIAL_CHANNEL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
   
    // Set material to point to created texture filename.      
    output_material->SetTexture( SG_MATERIAL_CHANNEL_DIFFUSE, "diffuse_out.png" );
}
csharp
void CastDiffuseColorData(spMaterial output_material, spMappingImage mapping_image, spMaterialTable source_materials)
{
    // Cast diffuse texture data using a color caster.
    spColorCaster cast = sg.CreateColorCaster();
    cast.SetColorType(Simplygon.Simplygon.SG_MATERIAL_CHANNEL_DIFFUSE);
    cast.SetSourceMaterials(source_materials);
    // The mapping image from the process.
    cast.SetMappingImage(mapping_image);
    cast.SetOutputChannels(3); // RGB, 3 channels
    cast.SetOutputChannelBitDepth(8); // 8 bits per channel, 24bpp
    cast.SetOutputFilePath("diffuse_out.png");
    cast.RunProcessing();
    // Set the diffuse multiplier for the texture.
    // 1 means it will not differ from original texture,       
    // Example: 0 would ignore a specified color and
    // 2 would make a color twice as pronounced as the others.     
    output_material.SetColor(Simplygon.Simplygon.SG_MATERIAL_CHANNEL_DIFFUSE, 1.0, 1.0, 1.0, 1.0);

    // Set material to point to created texture filename.      
    output_material.SetTexture(Simplygon.Simplygon.SG_MATERIAL_CHANNEL_DIFFUSE, "diffuse_out.png");
}
python
def CastDiffuseColorData( output_material, mapping_image, source_materials ):
    #  Cast diffuse texture data using a color caster.
    cast = sg.CreateColorCaster()       
    cast.SetColorType( Simplygon.SG_MATERIAL_CHANNEL_DIFFUSE )
    cast.SetSourceMaterials( source_materials )   
	
    #  The mapping image from the process.
    cast.SetMappingImage( mapping_image )
    cast.SetOutputChannels( 3 ) #  RGB, 3 channels
    cast.SetOutputChannelBitDepth( 8 ) #  8 bits per channel, 24bpp
    cast.SetOutputFilePath( "diffuse_out.png" )
    cast.CastMaterials()
    
	#  Set the diffuse multiplier for the texture.
    #  1 means it will not differ from original texture,       
    #  Example: 0 would ignore a specified color and
    #  2 would make a color twice as pronounced as the others.     
    output_material.SetColor( Simplygon.SG_MATERIAL_CHANNEL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 )
   
    #  Set material to point to created texture filename.      
    output_material.SetTexture( Simplygon.SG_MATERIAL_CHANNEL_DIFFUSE, "diffuse_out.png" )

DisplacementCaster

The DisplacementCaster is used to generate a displacement map containing the delta-values between the original and the processed geometries. The caster can be configured to generate either a scalar displacement value, or a displacement vector.

The values are divided by a scaling value and clamped into the [-1,1] range, or clamped to length 1 in the case of vectors, before being stored in the map.

The following example shows how to use the IDisplacementCaster to generate a displacement map.

cpp
void GenerateDisplacementMap( spMappingImage mapping_image )
{
    // Cast displacement texture data.
    spDisplacementCaster cast = sg->CreateDisplacementCaster();       
    // The mapping image from the process.
    cast->SetMappingImage( mapping_image );
    cast->SetGenerateScalarDisplacement( true );
    cast->SetDistanceScaling( 0.1 ); // Divide values by 0.1
    cast->SetOutputChannels( 1 ); // 1 channel
    cast->SetOutputChannelBitDepth( 8 ); // 8 bits per channel
    cast->SetOutputFilePath( "displacement_out.png" );
    cast->CastMaterials();
}
csharp
void GenerateDisplacementMap(spMappingImage mapping_image)
{
    // Cast displacement texture data.
    spDisplacementCaster cast = sg.CreateDisplacementCaster();
    // The mapping image from the process.
    cast.SetMappingImage(mapping_image);
    cast.SetGenerateScalarDisplacement(true);
    cast.SetDistanceScaling(0.1f); // Divide values by 0.1
    cast.SetOutputChannels(1); // 1 channel
    cast.SetOutputChannelBitDepth(8); // 8 bits per channel
    cast.SetOutputFilePath("displacement_out.png");
    cast.RunProcessing();
}
python
def GenerateDisplacementMap( mapping_image ):
    #  Cast displacement texture data.
    cast = sg.CreateDisplacementCaster()       
	
    #  The mapping image from the process.
    cast.SetMappingImage( mapping_image )
    cast.SetGenerateScalarDisplacement( True )
    cast.SetDistanceScaling( 0.1 ) #  Divide values by 0.1
    cast.SetOutputChannels( 1 ) #  1 channel
    cast.SetOutputChannelBitDepth( 8 ) #  8 bits per channel
    cast.SetOutputFilePath( "displacement_out.png" )
    cast.CastMaterials()

NormalCaster

The NormalCaster is used to cast normals data from the original geometries.

The following example shows how to use the NormalCaster to generate a normal map.

cpp
void CastNormalData( spMaterial output_material, spMappingImage mapping_image, spMaterialTable source_materials )
{
    // Cast the data using a normal caster.
    spNormalCaster cast = sg->CreateNormalCaster();       
    cast->SetSourceMaterials( source_materials );
    cast->SetMappingImage( mapping_image );       
    // Set output image settings. Use 3 channels
    // (the x, y and z values for the normal).
    cast->SetOutputChannels( 3 );
    cast->SetOutputChannelBitDepth( 8 );       
    cast->SetDilation( 10 );       
    cast->SetOutputFilePath( "normals_out.png" );
    cast->SetFlipBackfacingNormals( false );       
    cast->SetGenerateTangentSpaceNormals( true );   
   
    // Cast the data   
    cast->CastMaterials();
       
    // Set material to point to created texture filename.      
    output_material->SetTexture( SG_MATERIAL_CHANNEL_NORMALS, "normals_out.png" );
}
csharp
void CastNormalData(spMaterial output_material, spMappingImage mapping_image, spMaterialTable source_materials)
{
    // Cast the data using a normal caster.
    spNormalCaster cast = sg.CreateNormalCaster();
    cast.SetSourceMaterials(source_materials);
    cast.SetMappingImage(mapping_image);
    // Set output image settings. Use 3 channels
    // (the x, y and z values for the normal).
    cast.SetOutputChannels(3);
    cast.SetOutputChannelBitDepth(8);
    cast.SetDilation(10);
    cast.SetOutputFilePath("normals_out.png");
    cast.SetFlipBackfacingNormals(false);
    cast.SetGenerateTangentSpaceNormals(true);

    // Cast the data   
    cast.RunProcessing();

    // Set material to point to created texture filename.      
    output_material.SetTexture(Simplygon.Simplygon.SG_MATERIAL_CHANNEL_NORMALS, "normals_out.png");
}
python
def CastNormalData( output_material, mapping_image, source_materials ):
{
    #  Cast the data using a normal caster.
    cast = sg.CreateNormalCaster()       
    cast.SetSourceMaterials( source_materials )
    cast.SetMappingImage( mapping_image )       
	
    #  Set output image settings. Use 3 channels
    #  (the x, y and z values for the normal).
    cast.SetOutputChannels( 3 )
    cast.SetOutputChannelBitDepth( 8 )       
    cast.SetDilation( 10 )       
    cast.SetOutputFilePath( "normals_out.png" )
    cast.SetFlipBackfacingNormals( False )       
    cast.SetGenerateTangentSpaceNormals( True )   
   
    #  Cast the data   
    cast.CastMaterials()
       
    #  Set material to point to created texture filename.      
    output_material.SetTexture( Simplygon.SG_MATERIAL_CHANNEL_NORMALS, "normals_out.png" )
}

OpacityCaster

The OpacityCaster is used to cast opacity values, and can be used when opacity is needed as a separate texture.

The following example shows how to use the IOpacityCaster to generate an opacity map.

cpp
void GenerateOpacityMap( spMaterial output_material, spMappingImage mapping_image, spMaterialTable source_materials )
{
    // Cast displacement texture data.
    spOpacityCaster cast = sg->CreateOpacityCaster();       
    cast->SetSourceMaterials( source_materials );
    cast->SetMappingImage( mapping_image );
   
    cast->SetOutputChannels( 1 ); // 1 channel
    cast->SetOutputChannelBitDepth( 8 ); // 8 bits per channel
    cast->SetOutputFilePath( "opacity_out.png" );
    cast->CastMaterials();
       
    // Set material to point to created texture filename.      
    output_material->SetTexture( SG_MATERIAL_CHANNEL_OPACITY, "opacity_out.png" );
}
csharp
void GenerateOpacityMap(spMaterial output_material, spMappingImage mapping_image, spMaterialTable source_materials)
{
    // Cast displacement texture data.
    spOpacityCaster cast = sg.CreateOpacityCaster();
    cast.SetSourceMaterials(source_materials);
    cast.SetMappingImage(mapping_image);

    cast.SetOutputChannels(1); // 1 channel
    cast.SetOutputChannelBitDepth(8); // 8 bits per channel
    cast.SetOutputFilePath("opacity_out.png");
    cast.RunProcessing();

    // Set material to point to created texture filename.      
    output_material.SetTexture(Simplygon.Simplygon.SG_MATERIAL_CHANNEL_OPACITY, "opacity_out.png");
}
python
def GenerateDisplacementMap( output_material, mapping_image, source_materials ):
    #  Cast displacement texture data.
    cast = sg.CreateOpacityCaster()       
    cast.SetSourceMaterials( source_materials )
    cast.SetMappingImage( mapping_image )
    cast.SetOutputChannels( 1 ) #  1 channel
    cast.SetOutputChannelBitDepth( 8 ) #  8 bits per channel
    cast.SetOutputFilePath( "opacity_out.png" )
    cast.CastMaterials()
       
    #  Set material to point to created texture filename.      
    output_material.SetTexture( SG_MATERIAL_CHANNEL_OPACITY, "opacity_out.png" )

ComputeCaster

The compute caster is complimentatry caster to all the previously mentioned casters except for vertex color casteer. Therefore it can be used to cast color, normal, opacity and etc to a image data object.

The following example shows how to use the IComputeCaster to generate a ddiffuse map. Note the below snippet only cover the setting up of compute caster object. See Compute Casting for more details on what else is required from the users side to use the compute caster.

cpp
void GenerateDiffuseMapUsingComputeCaster( spMaterial output_material, spMappingImage mapping_image, spMaterialTable source_materials, spTextureTable source_textures )
{
    // Cast color data.
    auto cast = sg->CreateComputeCaster();
    cast->SetSourceMaterials( source_materials );
    cast->SetSourceTextures( source_textures );
    cast->SetMappingImage( mapping_image );

    cast->GetComputeCasterSettings()->SetDilation( 8 ); 
    cast->GetComputeCasterSettings()->SetMaterialChannel( SG_MATERIAL_CHANNEL_DIFFUSE );
	cast->GetComputeCasterSettings()->SetOutputPixelFormat( EPixelFormat::R8G8B8 );
	cast->GetComputeCasterSettings()->SetOutputColorSpace( EImageColorSpace::sRGB );
	cast->GetComputeCasterSettings()->SetFillMode( EAtlasFillMode::NoFill );

    cast->SetOutputFilePath( "diffuse.png" );

    auto errorCode = cast->RunProcessing();
    
    // Set material to point to created texture filename. 
    output_material->SetTexture( SG_MATERIAL_CHANNEL_DIFFUSE, "diffuse.png" );
}
csharp
void GenerateDiffuseMapUsingComputeCaster(spMaterial output_material, spMappingImage mapping_image, spMaterialTable source_materials, spTextureTable source_textures)
{
    // Cast color data.
    var cast = sg.CreateComputeCaster();
    cast.SetSourceMaterials( source_materials );
    cast.SetSourceTextures( source_textures );
    cast.SetMappingImage( mapping_image );

    cast.GetComputeCasterSettings().SetDilation( 8 ); 
    cast->GetComputeCasterSettings().SetMaterialChannel( Simplygon.Simplygon.SG_MATERIAL_CHANNEL_DIFFUSE );
	cast->GetComputeCasterSettings().SetOutputPixelFormat( Simplygon.Simplygon.EPixelFormat.R8G8B8 );
	cast->GetComputeCasterSettings().SetOutputColorSpace( Simplygon.Simplygon.EImageColorSpace.sRGB );
	cast->GetComputeCasterSettings().SetFillMode( Simplygon.Simplygon.EAtlasFillMode.NoFill );

    cast.SetOutputFilePath("diffuse.png");

    var errorCode = cast.RunProcessing();

    // Set material to point to created texture filename.      
    output_material.SetTexture(Simplygon.Simplygon.SG_MATERIAL_CHANNEL_DIFFUSE, "diffuse.png");
}
python
def GenerateDiffuseMapUsingComputeCaster( output_material, mapping_image, source_materials, source_textures ):
    #  Cast color data.
    cast = sg.CreateComputeCaster()       
    cast.SetSourceMaterials( source_materials )
    cast.SetSourceTextures( source_materials )
    cast.SetMappingImage( mapping_image )
    
    cast.GetComputeCasterSettings().SetDilation( 8 ); 
    cast.GetComputeCasterSettings().SetMaterialChannel( Simplygon.SG_MATERIAL_CHANNEL_DIFFUSE )
	cast.GetComputeCasterSettings().SetOutputPixelFormat( Simplygon.EPixelFormat_R8G8B8 )
	cast.GetComputeCasterSettings().SetOutputColorSpace( Simplygon.EImageColorSpace_sRGB )
	cast.GetComputeCasterSettings().SetFillMode( Simplygon.EAtlasFillMode_NoFill )

    cast.SetOutputFilePath( "diffuse.png" )
    cast.CastMaterials()
       
    #  Set material to point to created texture filename.      
    output_material.SetTexture( SG_MATERIAL_CHANNEL_OPACITY, "diffuse.png" )