Skip to content
On this page

Compute Casting

Compute casting is an alternate way to cast material compared to using traditional casters and shading networks. The following diagram provides an overview of the compute casting workflow and the major component involved.

Compute Casting Overview

Compute Casting as the name suggest uses a compute shader and Vulkan backend to cast textures. The Vulkan backend can either be a GPU or a CPU fallback API (e.g SwiftShader). Like other caster compute caster takes in MappingImage, Materials and Textures for the casting processing. Unlike other caster you also need to provide MaterialEvaluationShader and a user-defined shader block.

Dependencies

Before you get started with compute casting in your pipeline the following dependencies should be installed on machines where you intend to use the feature.

  • VulkanSDK (Version 1.2+) Simplygon uses a Vulkan-based compute casting processor, and needs the VulkanSDK shader compilation tools:
    • glslc.exe for compiling GLSL shaders. glslc.exe is part of the VulkanSDK distro, so if you install VulkanSDK, Simplygon should be able to find glslc.exe automatically. If not, please make sure it is available in the Windows PATH environment variable.
    • dxc.exe for compiling HLSL shaders. dxc.exe and all needed Spir-V support tools are part of the VulkanSDK distro, so if you install VulkanSDK, Simplygon should be able to find dxc.exe automatically. If not, please make sure it is available in the Windows PATH environment variable. (Please note! This is not the standard dxc.exe which is included with Visual Studio and compiles DXIL code, but a version which is able to output and compile Spir-V for Vulkan.)
  • A Vulkan-compatible GPU, with latest drives, -or-
  • Swift Shader (Optional: CPU based fallback Vulkan API implementation)

Material Evaluation Shader and user-defined shader block

Material Evaluation Shader

This object is meta data that is attached to the Material object. This meta data along with the user defined shader block is used by the compute caster to generate a compute shader for the casting process. The ShaderLanguage attribute/property is required.

MaterialEvaluationShader can be defined by either creating API object programmatically or by deserializing a XML file. See Material Evaluation Shader for more info. The following are the main components required for MaterialEvaluationShader.

Attributes

MaterialEvaluationShaderAttribute object declare a buffer resource that is setup during compute shader generation phase. The buffer refers to a field in the source GeometryData used in the user-defined shader block(e.g Texcoords, Coords, Normals, Tangents and custom fields). The Name property refers to the variable or buffer name in the shader. The GeometryFieldType refers to the field type in GeometryData. See EGeometryFieldType. The AttributeFormat refers to the data type(e.g F32vec2,U32 and etc). See EAttributeFormat. Some geometry fields like Texcoords, Colors, UserCornerField, UserVertexField , UserTriangleField are named fields. The FieldName property should be used to refer to the named field. If a named field is not present in the GeometryData and the frequency is known (e.g Triangle, Vertex, Corner) a zero initialized buffer would be created for use by the generated compute shader.See Material Evaluation Shader Attribute for more information.

Evaluation Functions

ShaderEvaluationFunction object declare a mapping between MaterialChannel and a method in user defined shader block to use for casting. At least one ShaderEvaluationFunction object is required. (e.g Diffuse, Basecolor, Normals, Roughness and etc.). See Shader Evaluation Function. The EntryPoint is the name of the function in user defined shader block. Channel property should refer to MaterialChannel on the Material object.

Shader Parameters

The shader parameters are parameter used to setup the generated shader. ShaderParameter is the base class. The following are the concrete types:

Textures

ShaderParameterTexture and ShaderParameterTextureArray objects are used to define texture references, which can be sampled using a texture sampler (defined below). The ShaderParameterTexture object creates a single texture reference in the shader code, and the ShaderParameterTextureArray creates an array of texture references, which can be indexed in the shader code.

ShaderParameterTexture object has a TextureName property which must refer to an existing Texture in the TextureTable. ShaderParameterTextureArray contains a StringArray parameter, which holds the names and indices of all the textures in the texture array.

Samplers

ShaderParameterSampler object declare a texture sampler that is generated by the compute caster. A ShaderParameterSampler object per Texture is required(referred in user-defined shader block). ShaderParameterSampler object has an optional TextureName property which should refer to a Texture in the TextureTable. If the TextureName property is set, the sampler is a combined texture and sampler, and bound to one slot. Each ShaderParameterSampler object can use a default state. Users can override sampler state by declaring a ShaderParameterSamplerState object. The SamplerState property can be used to refer to the name of the ShaderParameterSamplerState object to use. If SamplerState property is not set a default SamplerState is used. See Shader Parameter Sampler

Samplers States

The ShaderParameterSamplerState object declare the behavior of a sampler like filtering and addressing modes. See ESamplerAddressMode, ESamplerFilter and Shader Parameter Sampler state. This shader parameter type is optional. To refer to ShaderParameterSampler object. The SamplerState property on ShaderParameterSampler object should refer to the Name of the ShaderParameterSamplerState object to use.

Note: Since HLSL and GLSL handle sampler states a bit differently, samplers in GLSL are automatically applied to each sampler, while in HLSL, the samplers are explicitly selected in the shader. For HLSL, it is recommended to specify samplers and textures separately, to be able to defined the names of the objects specifically.

Default Samplers State

PropertyDefault
MagFilterLinear
MinFilterLinear
AddressModeURepeat
AddressModeVRepeat
AddressModeWRepeat
UnnormalizedCoordinatesfalse

Preprocessor Defines

MaterialEvaluationShaderDefine object can be used to declare a preprocessor define in the generated compute shader before the user block begins. The define is undefined after the user block ends. The Name property is required. The Value property is optional.

Built-in values

Some values are always defined in the generated shader file. These have specific properties, and can be used by the shader code to modify behaviour etc. The values are listed below.

ValueTypeDescription
sg_MaterialIdFilter#define (unsigned value)The Id of the current material being compiled
sg_TriangleIdintThe triangle Id of the current triangle
sg_BCoord0floatThe barycentric coordinate of the current sample in the current triangle, value 0
sg_BCoord1floatThe barycentric coordinate of the current sample in the current triangle, value 1
sg_BCoord2floatThe barycentric coordinate of the current sample in the current triangle, value 2
sg_WorldCoord3d vectorThe projected world coordinate of the current sample
sg_HasPreviousValueboolWhen there are multiple layers, this is set to true if there are previous values to blend with. Note: Layers are blended back-to-front
sg_PreviousValue4d vectorIf there is a previous layer data (sg_HasPreviousValue == true), this is the accumulated value
sg_DiscardValueboolSet to true when the value should be discarded. Useful if the casting is based on a pixel/fragment shader with a discard/clip call and you want the same behaviour in the compute shader
sg_DestinationWorldCoord3d vectorThe projected world coordinate of the destination sample, on the destination mesh
sg_DestinationTangent3d vectorThe tangent basis tangent vector of the destination sample, on the destination mesh
sg_DestinationBitangent3d vectorThe tangent basis bitangent vector of the destination sample, on the destination mesh
sg_DestinationNormal3d vectorThe tangent basis normal vector of the destination sample, on the destination mesh

Setting up Material Evaluation Shader and Exporting the XML

If you have access to the Simplygon API prefer creating MaterialEvaluationShader object over XML. In case your shader export module can not take a dependency on you can export an XML using any XML writer for ingestion into your LOD generation module.

The following code example shows how to setup a MaterialEvaluationShader object. Load a shader from disk and export it as an XML. This is mainly to validate what kind of XML is read by Simplygon and deserialized. You can adapt your XML writer to export similarly.

cpp
void SetupMaterialEusevaluationShaderAndExportXML( const std::string& xmlPath, const std::string& shaderFilePath )
{
    
 auto materialEvaluationShader = sg->CreateMaterialEvaluationShader();

 //create a texcoord attribute
 auto texCoordAttribute = sg->CreateMaterialEvaluationShaderAttribute();
 
 //reference name used inside the shader
 texCoordAttribute
     ->SetName( "TEXCOORD0" );
 
 //type of field (spGeometryData)
 texCoordAttribute
     ->SetFieldType(Simplygon::EGeometryDataFieldType::TexCoords);
 
 //type of data the field contains
 texCoordAttribute
     ->SetFieldFormat(Simplygon::EAttributeFormat::F32vec2);
 
 //name of the field (spGeometryData). (i.e if read from FBX or if you  
 texCoordAttribute
     ->SetFieldName( "UVMap1" );

 //add attributes to the attribute table
 materialEvaluationShader->GetMaterialEvaluationShaderAttributeTable()->AddAttribute(texCoordAttribute);

 //create an evaluation function
 auto baseColorEvalFunction = sg->CreateShaderEvaluationFunction();
 baseColorEvalFunction
     ->SetName( "EvalFunction" );
 //the channel name that is present in the spMaterial
 baseColorEvalFunction->SetChannel( SG_MATERIAL_CHANNEL_BASECOLOR );

 //the name of the method that is in the shader
 baseColorEvalFunction->SetEntryPoint( "EvaluateBaseColor" );

 materialEvaluationShader->GetShaderEvaluationFunctionTable()->AddShaderEvaluationFunction(baseColorEvalFunction);
 
 //create a samplersate
 auto samplerStateParameter = sg->CreateShaderParameterSamplerState();
 samplerStateParameter->SetName( "LinearRepeat" );
 samplerStateParameter->SetAddressU( Simplygon::ESamplerAddressMode::MirrorRepeat);
 samplerStateParameter->SetAddressV( Simplygon::ESamplerAddressMode::MirrorRepeat);
 samplerStateParameter->SetAddressW( Simplygon::ESamplerAddressMode::MirrorRepeat);
 samplerStateParameter->SetMagFilter( Simplygon::ESamplerFilter::Linear);
 samplerStateParameter->SetMinFilter( Simplygon::ESamplerFilter::Linear);
 samplerStateParameter->SetUnNormalizedCoordinates( false );

 //create a sampler
 auto sampler = sg->CreateShaderParameterSampler();

 //reference of the sampler used in the shader
 sampler->SetName( "BaseColorTexture" );

 //reference the sampler sate created above.
 sampler->SetSamplerState( "LinearRepeat" );

 //name of the texture in the Scene's(spScene) texture table (spTextureTable)
 sampler->SetTextureName( "wood_D" );

 //add to table
 materialEvaluationShader->GetShaderParameterTable()->AddShaderParameter(samplerStateParameter);
 materialEvaluationShader->GetShaderParameterTable()->AddShaderParameter(sampler);
 materialEvaluationShader->SetShaderLanguage(Simplygon::EShaderLanguage::GLSL);

 //add a shader define to flip the uv values in baking process. See the user code block 
 auto shaderDefine = sg->CreateMaterialEvaluationShaderDefine();
    shaderDefine->SetName( "FLIP_UV" );

 //add to table
    materialEvaluationShader->GetMaterialEvaluationShaderDefineTable()->AddMaterialEvaluationShaderDefine(shaderDefine);

 //load shader (optionally you can set the shader string with SetShaderCode
 materialEvaluationShader->LoadShaderFromFilePath( shaderFilePath.c_str() );

 auto materialEvaluationShaderSerializer = sg->CreateMaterialEvaluationShaderSerializer();       
 
 materialEvaluationShaderSerializer->SaveMaterialEvaluationShaderToFile( xmlPath.c_str(), materialEvaluationShader );
}
csharp
void SetupMaterialEvaluationShaderAndExportXML(string xmlPath, string shaderFilePath)
{
    var materialEvaluationShader = sg.CreateMaterialEvaluationShader();

 //create a texcoord attribute
 var texCoordAttribute = sg.CreateMaterialEvaluationShaderAttribute();
 
 //reference name used inside the shader
 texCoordAttribute.SetName( "TEXCOORD0" );
 
 //type of field (spGeometryData)
 texCoordAttribute.SetFieldType(Simplygon::EGeometryDataFieldType::TexCoords);
 
 //type of data the field contains
 texCoordAttribute.SetFieldFormat(Simplygon::EAttributeFormat::F32vec2);
 
 //name of the field (spGeometryData). (i.e if read from FBX or if you  
 texCoordAttribute.SetFieldName( "UVMap1" );

 //add attributes to the attribute table
 materialEvaluationShader.GetMaterialEvaluationShaderAttributeTable().AddAttribute(texCoordAttribute);

 //create an evaluation function
 var baseColorEvalFunction = sg.CreateShaderEvaluationFunction();
 baseColorEvalFunction.SetName( "EvalFunction" );
 //the channel name that is present in the spMaterial
 baseColorEvalFunction.SetChannel( Simplygon.Simplygon.SG_MATERIAL_CHANNEL_BASECOLOR );

 //the name of the method that is in the shader
 baseColorEvalFunction.SetEntryPoint( "EvaluateBaseColor" );

 materialEvaluationShader.GetShaderEvaluationFunctionTable().AddShaderEvaluationFunction(baseColorEvalFunction);
 
 //create a samplersate
 var samplerStateParameter = sg.CreateShaderParameterSamplerState();
 samplerStateParameter.SetName( "LinearRepeat" );
 samplerStateParameter.SetAddressU( Simplygon.Simplygon.ESamplerAddressMode,MirrorRepeat);
 samplerStateParameter.SetAddressV( Simplygon.Simplygon.ESamplerAddressMode.MirrorRepeat);
 samplerStateParameter.SetAddressW( Simplygon.Simplygon.ESamplerAddressMode.MirrorRepeat);
 samplerStateParameter.SetMagFilter( Simplygon.Simplygon.ESamplerFilter.Linear);
 samplerStateParameter.SetMinFilter( Simplygon.Simplygon.ESamplerFilter.Linear);
 samplerStateParameter.SetUnNormalizedCoordinates( false );

 //create a sampler
 var sampler = sg.CreateShaderParameterSampler();

 //reference of the sampler used in the shader
 sampler.SetName( "BaseColorTexture" );

 //reference the sampler sate created above.
 sampler.SetSamplerState( "LinearRepeat" );

 //name of the texture in the Scene's(spScene) texture table (spTextureTable)
 sampler.SetTextureName( "wood_D" );

 //add to table
 materialEvaluationShader.GetShaderParameterTable().AddShaderParameter(samplerStateParameter);
 materialEvaluationShader.GetShaderParameterTable().AddShaderParameter(sampler);
 materialEvaluationShader.SetShaderLanguage(Simplygon.Simplygon.EShaderLanguage.GLSL);

 //add a shader define to flip the uv values in baking process. See the user code block 
 var shaderDefine = sg.CreateMaterialEvaluationShaderDefine();
    shaderDefine.SetName( "FLIP_UV" );

 // add to table
    materialEvaluationShader.GetMaterialEvaluationShaderDefineTable().AddMaterialEvaluationShaderDefine(shaderDefine);
 
 //load shader (optionally you can set the shader string with SetShaderCode
 materialEvaluationShader.LoadShaderFromFilePath( shaderFilePath );

 var materialEvaluationShaderSerializer = sg.CreateMaterialEvaluationShaderSerializer();       
 
 materialEvaluationShaderSerializer.SaveMaterialEvaluationShaderToFile( xmlPath, materialEvaluationShader );
}
python
def SetupMaterialEvaluationShaderAndExportXML( xmlPath, shaderFilePath ):
 materialEvaluationShader = sg.CreateMaterialEvaluationShader()
 
 #create a texcoord attribute
 texCoordAttribute = sg.CreateMaterialEvaluationShaderAttribute()
 
 #reference name used inside the shader
 texCoordAttribute.SetName( "TEXCOORD0" )
 
 #type of field (spGeometryData)
 texCoordAttribute.SetFieldType(Simplygon::EGeometryDataFieldType::TexCoords)
 
 #type of data the field contains
 texCoordAttribute.SetFieldFormat(Simplygon::EAttributeFormat::F32vec2)
 
 #name of the field (spGeometryData). (i.e if read from FBX or if you  
 texCoordAttribute.SetFieldName( "UVMap1" )

 #add attributes to the attribute table
 materialEvaluationShader.GetMaterialEvaluationShaderAttributeTable().AddAttribute(texCoordAttribute)

 #create an evaluation function
 baseColorEvalFunction = sg.CreateShaderEvaluationFunction()
 baseColorEvalFunction.SetName( "EvalFunction" )
 #the channel name that is present in the spMaterial
 baseColorEvalFunction.SetChannel( Simplygon.Simplygon.SG_MATERIAL_CHANNEL_BASECOLOR )

 #the name of the method that is in the shader
 baseColorEvalFunction.SetEntryPoint( "EvaluateBaseColor" )

 materialEvaluationShader.GetShaderEvaluationFunctionTable().AddShaderEvaluationFunction(baseColorEvalFunction)
 
 #create a samplersate
 samplerStateParameter = sg.CreateShaderParameterSamplerState()
 samplerStateParameter.SetName( "LinearRepeat" )
 samplerStateParameter.SetAddressU( Simplygon.Simplygon.ESamplerAddressMode,MirrorRepeat)
 samplerStateParameter.SetAddressV( Simplygon.Simplygon.ESamplerAddressMode.MirrorRepeat)
 samplerStateParameter.SetAddressW( Simplygon.Simplygon.ESamplerAddressMode.MirrorRepeat)
 samplerStateParameter.SetMagFilter( Simplygon.Simplygon.ESamplerFilter.Linear)
 samplerStateParameter.SetMinFilter( Simplygon.Simplygon.ESamplerFilter.Linear)
 samplerStateParameter.SetUnNormalizedCoordinates( false )

 #create a sampler
 sampler = sg.CreateShaderParameterSampler()

 #reference of the sampler used in the shader
 sampler.SetName( "BaseColorTexture" )

 #reference the sampler sate created above.
 sampler.SetSamplerState( "LinearRepeat" )

 #name of the texture in the Scene's(spScene) texture table (spTextureTable)
 sampler.SetTextureName( "wood_D" )

 #add to table
 materialEvaluationShader.GetShaderParameterTable().AddShaderParameter(samplerStateParameter)
 materialEvaluationShader.GetShaderParameterTable().AddShaderParameter(sampler)
 materialEvaluationShader.SetShaderLanguage(Simplygon.Simplygon.EShaderLanguage.GLSL)

 #add a shader define to flip the uv values in baking process. See the user code block 
 var shaderDefine = sg.CreateMaterialEvaluationShaderDefine()
    shaderDefine.SetName( "FLIP_UV" )

 #add to table
    materialEvaluationShader.GetMaterialEvaluationShaderDefineTable().AddMaterialEvaluationShaderDefine(shaderDefine)
 
 #load shader (optionally you can set the shader string with SetShaderCode
 materialEvaluationShader.LoadShaderFromFilePath( shaderFilePath )

 materialEvaluationShaderSerializer = sg.CreateMaterialEvaluationShaderSerializer()
 
 materialEvaluationShaderSerializer.SaveMaterialEvaluationShaderToFile( xmlPath, materialEvaluationShader )

It is also possieble to export all material evaluation shaders, along with their material mapping and used textures, by using the SaveSceneMaterialEvaluationShadersToFile call. This will output an extended XML.

Example Material Evaluation Shader XML

The following is a an example XML what can be deserialized into a MaterialEvaluationShader object. The following XML was generated using the above sample code. ShaderLanguage attribute is required for appropriate shader bindings generation by compute caster.

xml
<?xml version="1.0" encoding="UTF-8"?>
<MaterialEvaluationShader Version="1.0" ShaderLanguage="GLSL">
    <!-- This attribute defines that from source geometry we want to use a named TexCoord field named UVMap -->
    <Attribute Name="TEXCOORD0" FieldType="TexCoords" FieldName="UVMap1" FieldFormat="F32vec2"/>

    <!-- A method called CastDiffuse will be used to cast to diffuse channel -->
    <EvaluationFunction Channel="Basecolor" EntryPoint="EvaluateBaseColor"/>
    <!-- A non default sampler state -->
    <ShaderParameterSamplerState Name="LinearRepeat" MinFilter="Linear" MagFilter="Linear" AddressU="MirrorRepeat" AddressV="MirrorRepeat" AddressW="MirrorRepeat" UnNormalizedCoordinates="true"/>
    <!-- A sampler using non default sampler state called LinearRepeat which is used to sample wood_D texture -->
    <ShaderParameterSampler Name="BaseColorTexture" TextureName="wood_D" SamplerState="LinearRepeat"/>
 <!-- A Shader define that would be declared in generated code-->
 <Define Name="FLIP_UV"/>
    <!-- If SetShaderCode or LoadShaderFromFile is used the shader is embedded as cdata -->
    <Shader><![CDATA[
vec4 EvaluateBaseColor() 
{ 
#ifdef FLIP_UV 
 return vec4(TEXCOORD0.y,TEXCOORD0.x,0,1); 
#else 
 return vec4(TEXCOORD0.x,TEXCOORD0.y,0,1); 
#endif 
}]]></Shader>
</MaterialEvaluationShader>

Below is an example of the extended XML which also maps the evaluation shader into a material called "wood_material", and also adds the texture "wood_D" (filename: "wood.png") into the texture table. Note that if the material and texture exists in the current scene, their data is replaced. If the material or texture does not exist in the scene, they are added.

xml
<?xml version="1.0" encoding="UTF-8"?>
<Scene>
   <TextureTable>
      <Texture Name="wood_D" FilePath="wood.png" ColorSpace="Linear"/>
   </TextureTable>
   <MaterialTable>
      <Material Name="wood_material">
         <MaterialEvaluationShader Version="1.0" ShaderLanguage="GLSL">
            <!-- This attribute defines that from source geometry we want to use a named TexCoord field named UVMap -->
            <Attribute Name="TEXCOORD0" FieldType="TexCoords" FieldName="UVMap1" FieldFormat="F32vec2"/>

            <!-- A method called CastDiffuse will be used to cast to diffuse channel -->
            <EvaluationFunction Channel="Basecolor" EntryPoint="EvaluateBaseColor"/>
            <!-- A non default sampler state -->
            <ShaderParameterSamplerState Name="LinearRepeat" MinFilter="Linear" MagFilter="Linear" AddressU="MirrorRepeat" AddressV="MirrorRepeat" AddressW="MirrorRepeat" UnNormalizedCoordinates="true"/>
            <!-- A sampler using non default sampler state called LinearRepeat which is used to sample wood_D texture -->
            <ShaderParameterSampler Name="BaseColorTexture" TextureName="wood_D" SamplerState="LinearRepeat"/>
         <!-- A Shader define that would be declared in generated code-->
         <Define Name="FLIP_UV"/>
            <!-- If SetShaderCode or LoadShaderFromFile is used the shader is embedded as cdata -->
            <Shader><![CDATA[
         vec4 EvaluateBaseColor() 
         { 
         #ifdef FLIP_UV 
         return vec4(TEXCOORD0.y,TEXCOORD0.x,0,1); 
         #else 
         return vec4(TEXCOORD0.x,TEXCOORD0.y,0,1); 
         #endif 
         }]]></Shader>
         </MaterialEvaluationShader>
      </Material>
   </MaterialTable>
</Scene>

XML Elements & Evaluation Shader Setup

XML ElementAPI Object*Additional Info
MaterialEvaluationShaderMaterialEvaluationShaderRoot
EvaluationFunctionShaderEvaluationFunctionRequired
AttributeMaterialEvaluationShaderAttributeOptional
ShaderParameterSamplerStateShaderParameterSamplerStateOptional. (Is a ShaderParameter)
ShaderParameterSamplerShaderParameterSamplerOptional. (Is a ShaderParameter)
ShaderParameterTextureShaderParameterTextureOptional. (Is a ShaderParameter)
ShaderParameterTextureArrayShaderParameterTextureArrayOptional. (Is a ShaderParameter)
DefineMaterialEvaluationShaderDefineOptional
Shader-Optional user (GLSL/HLSL) block as CDATA. Requires ShaderLanguage attribute be set on MaterialEvaluationShader element. Or use LoadMaterialEvaluationShaderFromFile(MaterialEvaluationShader) to load from file.

User-defined shader block

User defined shader block define how to evaluate the pixel for the baked texture. It is a block of GLSL code. Its is a partial code block that is injected into the final compute shader generated by the compute caster. Any resources (i.e textures, geometry data fields from source geometry are define by the MaterialEvaluationShader object.

glsl
vec4 AlphaOffset(in sampler2D alphaMask, vec2 uv, vec4 offset)
{
 vec4 alphaMaks = texture(alphaMask, uv);
 vec4 maskOffset = alphaMaks - offset;
 vec4 clampOffset = clamp(maskOffset,0.0,1.0);
 return ceil(clampOffset);
}

vec4 BlendTextures(in sampler2D primary, in sampler2D secondary,vec2 UV,vec4 alphaMasks)
{
 vec4 allOnes = vec4(1);
 
 vec4 primaryColor = texture(primary,UV);
 vec4 secondaryColor = texture(secondary,UV);

    vec4 oneMinus = allOnes-alphaMasks;

 vec4 filterPrimary =  oneMinus*primaryColor;
 vec4 filterSecondary =  alphaMasks*secondaryColor;
 return filterPrimary+filterSecondary;
}

// The Evaluation Function in XML as referenced in
// TEXCOORD0 DiffuseA, DiffuseB & Mask are also referenced in the XML
// These are the samplers and buffer resources that will be bound to the generated compute shader
vec4 CastDiffuse()
{
 vec4 diffuseColor;
 vec4 alphaMasks = AlphaOffset(Mask,TEXCOORD0,vec4(0.10));
 diffuseColor = BlendTextures(DiffuseA,DiffuseB, TEXCOORD0, alphaMasks);
 return diffuseColor;
}

Loading Shader block and XML Example

The following code snippet on how users can use the serializer to deserialize the XML to and MaterialEvaluationShader object and assign it to the Material.

cpp
void SetupMaterialEvaluationShaderForMaterial(spMaterial material, const std::string& assetPath)
{
    auto materialName = material->GetName();
    
    // each material has material evaluation shader xml. Note this can be shared between material as long as the surface is evaluated in the same way.
    const auto evaluationShaderXml = assetPath + "\\" + materilaName + ".xml";

    // Create the serializer object
 spMaterialEvaluationShaderSerializer serializer = 
    sg->CreateMaterialEvaluationShaderSerializer();

    // deserialize xml to material evaluation shader object
 auto evaluationShader = serializer->LoadMaterialEvaluationShaderFromFile( evaluationShaderXml.c_str() );

    //load GLSL file from disk . This is the user-defined shader block
    const auto evaluationShaderGlsl = assetPath + "\\" + materilaName + ".glsl";
    evaluationShader->LoadShaderFromFilePath(evaluationShaderGlsl.c_str());

    // set material evaluation shader on the material
 material->SetMaterialEvaluationShader( evaluationShader );
}
csharp
void SetupMaterialEvaluationShaderForMaterial(Simplygon.spMaterial material, string assetPath)
{
    var materialName = material.GetName();
    
    // each material has material evaluation shader xml. Note this can be shared between material as long as the surface is evaluated in the same way.
    
    var evaluationShaderXml = assetPath + "\\" + materilaName + ".xml";

    // Create the serializer object
 var serializer = 
    sg.CreateMaterialEvaluationShaderSerializer();

    // deserialize xml to material evaluation shader object
 auto evaluationShader = serializer->LoadMaterialEvaluationShaderFromFile( evaluationShaderXml );

    //load GLSL file from disk . This is the user-defined shader block
    var evaluationShaderGlsl = assetPath + "\\" + materilaName + ".glsl";
    evaluationShader.LoadShaderFromFilePath(evaluationShaderGlsl);

    // set material evaluation shader on the material
 material.SetMaterialEvaluationShader( evaluationShader );
}
python
def SetupMaterialEvaluationShaderForMaterial(material:Simplygon.spMaterial, assetPath:str):
    materialName = material.GetName()
    # each material has material evaluation shader xml. Note this can be shared between material as long as the surface is evaluated in the same way.
    evaluationShaderXml = assetPath + "\\" + materilaName + ".xml"
    # Create the serializer object
    serializer =
    sg.CreateMaterialEvaluationShaderSerializer()
    # deserialize xml to material evaluation shader object
    evaluationShader = serializer.LoadMaterialEvaluationShaderFromFile( evaluationShaderXml )
    
    #load GLSL file from disk . This is the user-defined shader block
    evaluationShaderGlsl = assetPath + "\\" + materilaName + ".glsl"
    evaluationShader.LoadShaderFromFilePath(evaluationShaderGlsl)
    #set material evaluation shader on the material
    material.SetMaterialEvaluationShader( evaluationShader )

Debugging

To be able to debug compute caster's generated shader users can set a custom path on ComputeCaster object. See DebugOutputShaderFolder setting in Compute Caster.

Global override

Simplygon selects a physical device based on the device properties. If you have multiple devices and want to override which device is used, use the global string setting "VulkanDevice" (SetGlobalVulkanDevice) to set the name of the device, or a substring of the name, and Simplygon will only consider devices which match the name. E.g. "3080", "AMD" or "NVidia GeForce 3070". To see all available device names, please look in the log, using an ELogLevel verbosity setting of at least Info.

.

Limitations

When using compute casters with pipeline you are limited to using RunScene method. RunSceneFromFile should be avoided as there is no clear way to define and read MaterialEvaluationShader or shader code when using third-party file formats. Therefore RunScene approach is recommended.

Example

Here is a compute casting example showing how to make a custom casting using a compute shader written by the user.