Material Scripting¶
Material Asset Request¶
The simplest way to get a material from code:
let material = request_material("my_material.material")
Material Creation¶
See MaterialImport for additional info.
Create a material with the standard shader and red color:
let material = create_material(MaterialImport(
shaderName = "standard_diffuse_shader",
properties = MaterialProperties("color", RED_COLOR)
))
The standard shader can be omitted:
let material = create_material(MaterialImport(
properties = MaterialProperties("color", RED_COLOR)
))
Create a material with a specified diffuse texture and green color:
let noiseTexture = request_texture("%builtin_package/logo.png")
let material = create_material(MaterialImport(
shaderName = "standard_diffuse_shader",
diffuse = noiseTexture,
properties = MaterialProperties("color", GREEN_COLOR)
))
shaderName is the name of a built-in shader, see Shaders.
A shader written in the project is a separate resource, pass it as shaderId:
let material = create_material(MaterialImport(
shaderId = request_shader("shaders/my_shader.shader"),
properties = MaterialProperties("strength", 0.5)
))
Material Update¶
update_material changes properties and keeps the rest of the material as is - its shader,
its textures and the properties that are not listed:
let material = request_material("my_material.material")
update_material(material, MaterialProperties("color", GREEN_COLOR))
Properties are matched by name, so the same call also rebinds a texture slot or changes the render state:
update_material(material, MaterialProperties("diffuse", request_texture("assets/wood.jpg")))
update_material(material, MaterialProperties("transparencyMode", TransparencyMode.AlphaBlend))
Names of the properties come from the shader: for a built-in shader they are listed on the
Shaders page, for a shader written in the project they are the
names of its var block. A name the shader does not have is ignored.
A material asset is shared by everything that uses it, so an update is visible on every mesh with
that material. It also survives a reload of the asset, and can be called right after
request_material, before the asset has finished loading.
To rebuild a material from scratch - to change its shader, for example - use replace_material.
It drops everything that is not listed in MaterialImport, including properties set by
update_material:
replace_material(material, MaterialImport(
shaderName = "standard_unlit_shader",
properties = MaterialProperties("color", GREEN_COLOR)
))
Material Copy¶
To change a single instance instead of every user of the asset, copy the material first:
let material = request_material("my_material.material")
let team1Material = copy_material(material)
let team2Material = copy_material(material)
update_material(team1Material, MaterialProperties("color", GREEN_COLOR))
update_material(team2Material, MaterialProperties("color", RED_COLOR))
Material Request¶
There is a way to reduce the number of materials in the scene. You can call request to avoid creating a new material every time.
This function will return an already created material if a request with the same settings was called before.
Example:
let materialSettings = MaterialImport(
properties = MaterialProperties("color", RED_COLOR)
)
let requestedMaterial1 = create_material(materialSettings)
let requestedMaterial2 = create_material(materialSettings)
assert(requestedMaterial1 == requestedMaterial2)
let createdMaterial1 = create_material(materialSettings, MaterialReusePolicy.AlwaysCreateNew)
let createdMaterial2 = create_material(materialSettings, MaterialReusePolicy.AlwaysCreateNew)
assert(createdMaterial1 != createdMaterial2)
Note
Instead of creating multiple materials with different colors, it is better (for render performance) to create one material and use Mesh.setPerInstanceData.