Custom Materials
If for some reason you cannot find the material to inherit or you need a special post-process, there is a way of creating a brand new material. This way is not recommended, as even slight changes in the source code can influence your material and it would not work correctly.
The algorithm of a custom material creation is the following:
- Create a material library - a .mat file in the target directory (all of the Unigine libraries are located in the data/core/materials/default directory).
- Create a base material declaration in the created material library.
- Specify a set of shaders - either combine existing shaders or write your own ones.
- Depending on the set of shaders, add required textures, parameters, and states to the declaration.
- Check, if the new material is loaded and rendered correctly.
As an example, lets examine the custom mesh_noise material, written as a sample for shaders (samples/shaders/mesh_noise_00.cpp). This material is changed dynamically according to the noise.
A material file can be found in the samples/shaders/materials/mesh_noise.mat directory. It contains common for all of the materials states, passes and textures. But there are a custom vertex shader and two custom parameters, noise_transform and vertex_noise, which are created specially for this material.
Lets examine a structure of a material file:
-
XML file and material library declaration.
<?xml version="1.0" encoding="utf-8"?> <materials version="1.00" editable="0"> ... </materials>
The version of the XML file is 1.0, the encoding is an UTF-8.
A version of the.mat file is 1.00. The editable flag is set to 0, which indicates that the library is not editable.
-
Material declaration.
<material name="mesh_noise" editable="0"> ... </material>
A name of the new material is mesh_noise. The editable flag is set to 0, which indicates that the base material is not editable.
-
Specifying material states to be displayed in Materials Editor.
<state name="deferred" type="switch" items="none,default">1</state> <state name="ambient" type="switch" items="none,opacity,transparent">1</state> <state name="light_omni" type="switch" items="none,default">1</state> <state name="light_proj" type="switch" items="none,default">1</state> <state name="light_world" type="switch" items="none,default">1</state>
Seven states are used for this material: deferred, ambient, light_omni, light_proj and light_world. The set values of the states are responsible for the shader to be used.
All of the passes have the same attributes: name (their names), type (all of the passes are of the switch type), items (none and default for all of the passes except for the ambient pass; it has none, opacity and transparent items). The default values are specified in the body of the element, so all the passes are enabled.
-
Specifying wireframe shaders to be used.
Wireframe shaders are required for the wireframe mode, to display the mesh grid.
<shader pass="wireframe" object="mesh" defines="BASE_WIREFRAME" vertex="shaders/mesh_noise/vertex.shader" geometry="core/shaders/default/common/geometry_base_wireframe.shader" fragment="core/shaders/default/common/fragment_base_wireframe.shader"/>
A shader element consists of the following attributes:
- pass - a name of the described pass, wireframe
- object - an object to which a shader will be applied, mesh
- defines - shader definitions, BASE_WIREFRAME
- vertex - a path to the custom vertex shader, samples/shaders/shaders/mesh_noise/vertex.shader. This shader is written for OpenGL and DirectX APIs by using GLSL and HLSL shading languages
- geometry - a path to the built-in geometry shader, core/shaders/default/common/geometry_base_wireframe.shader
- fragment - a path to the built-in fragment shader, core/shaders/default/common/fragment_base_wireframe.shader
- Specifying deferred shaders to be used.
<shader pass="deferred" object="mesh" defines="BASE_DEFERRED" deferred="1" vertex="shaders/mesh_noise/vertex.shader" fragment="core/shaders/default/mesh/fragment_base_deferred.shader"/>
A shader element consists of the following attributes:
- pass - a name of the described pass, deferred
- object - an object to which a shader will be applied, mesh
- defines - shader definitions, BASE_DEFERRED
- deferred - a flag, indicating when the deferred pass will be applied. Set to 1, so according to the deferred state, will be applied if state set as default
- vertex - a path to the custom vertex shader, samples/shaders/shaders/mesh_noise/vertex.shader. This shader is written for OpenGL and DirectX APIs by using GLSL and HLSL shading languages
- fragment - a path to the built-in fragment shader, core/shaders/default/mesh/fragment_base_deferred.shader
- Specifying ambient shaders to be used.
<shader pass="ambient" object="mesh" defines="BASE_AMBIENT,AMBIENT" ambient_defines="0,OPACITY,TRANSPARENT" vertex="shaders/mesh_noise/vertex.shader" fragment="core/shaders/default/mesh/fragment_base_ambient.shader"/>
A shader element consists of the following attributes:
- pass - a name of the described pass, ambient
- object - an object to which a shader will be applied, mesh
- defines - shader definitions, BASE_AMBIENT, AMBIENT
- ambient_defines - defines of the ambient pass items. The define will be used in accordance with the set ambient state value, 0 - none, OPACITY - opacity, TRANSPARENT - transparent
- vertex - a path to the custom vertex shader, samples/shaders/shaders/mesh_noise/vertex.shader. This shader is written for OpenGL and DirectX APIs by using GLSL and HLSL shading languages
- fragment - a path to the built-in fragment shader, core/shaders/default/mesh/fragment_base_ambient.shader
- Specifying omni light shaders to be used.
<shader pass="light_omni" object="mesh" defines="BASE_LIGHT_OMNI,OMNI" receive_shadow_defines=",SHADOW" light_omni_defines="0,PHONG_RIM" vertex="shaders/mesh_noise/vertex.shader" fragment="core/shaders/default/mesh/fragment_base_light_omni.shader"/>
A shader element consists of the following attributes:
- pass - a name of the described pass, light_omni
- object - an object to which a shader will be applied, mesh
- defines - shader definitions, BASE_LIGHT_OMNI, OMNI
- receive_shadow_defines - defines of the Receive shadow option. If enabled, the SHADOW define will be passed
- light_omni_defines - defines of the omni light pass. If the light_omni state is set as default, a PHONG_RIM define will be passed; if it is set to none, 0 will be passed
- vertex - a path to the custom vertex shader, samples/shaders/shaders/mesh_noise/vertex.shader. This shader is written for OpenGL and DirectX APIs by using GLSL and HLSL shading languages.
- fragment - a path to the built-in fragment shader, core/shaders/default/mesh/fragment_base_light_omni.shader
- Specifying projected light shaders to be used.
<shader pass="light_proj" object="mesh" defines="BASE_LIGHT_PROJ,PROJ" receive_shadow_defines=",SHADOW" light_proj_defines="0,PHONG_RIM" vertex="shaders/mesh_noise/vertex.shader" fragment="core/shaders/default/mesh/fragment_base_light_proj.shader"/>
A shader element consists of the following attributes:
- pass - a name of the described pass, light_proj
- object - an object to which a shader will be applied, mesh
- defines - shader definitions, BASE_LIGHT_PROJ, PROJ
- receive_shadow_defines - defines of the Receive shadow option. If enabled, the SHADOW define will be passed
- light_proj_defines - defines of the projected light pass. If the light_proj state is set as default, a PHONG_RIM define will be passed; if it is set to none, 0 will be passed
- vertex - a path to the custom vertex shader, samples/shaders/shaders/mesh_noise/vertex.shader. This shader is written for OpenGL and DirectX APIs by using GLSL and HLSL shading languages.
- fragment - a path to the built-in fragment shader, core/shaders/default/mesh/fragment_base_light_proj.shader
- Specifying world light shaders to be used.
<shader pass="light_world" object="mesh" defines="BASE_LIGHT_WORLD,WORLD" receive_world_shadow_defines=",SHADOW" light_world_defines="0,PHONG_RIM" vertex="shaders/mesh_noise/vertex.shader" fragment="core/shaders/default/mesh/fragment_base_light_world.shader"/>
A shader element consists of the following attributes:
- pass - a name of the described pass, light_world
- object - an object to which a shader will be applied, mesh
- defines - shader definitions, BASE_LIGHT_WORLD, WORLD
- receive_shadow_defines - defines of the Receive shadow option. If enabled, the SHADOW define will be passed
- light_world_defines - defines of the world light pass. If the light_world state is set as default, a PHONG_RIM define will be passed; if it is set to none, 0 will be passed
- vertex - a path to the custom vertex shader, samples/shaders/shaders/mesh_noise/vertex.shader. This shader is written for OpenGL and DirectX APIs by using GLSL and HLSL shading languages.
- fragment - a path to the built-in fragment shader, core/shaders/default/mesh/fragment_base_light_world.shader
- Specifying shadow shaders to be used.
A separate shadow shaders are required to render correct shadows.
<shader pass="shadow" object="mesh" defines="BASE_SHADOW" vertex="shaders/mesh_noise/vertex.shader" fragment="core/shaders/default/mesh/fragment_base_shadow.shader"/>
A shader element consists of the following attributes:
- pass - a name of the described pass, shadow
- object - an object to which a shader will be applied, mesh
- defines - shader definitions, BASE_SHADOW
- vertex - a path to the custom vertex shader, samples/shaders/shaders/mesh_noise/vertex.shader. This shader is written for OpenGL and DirectX APIs by using GLSL and HLSL shading languages.
- fragment - a path to the built-in fragment shader, core/shaders/default/mesh/fragment_base_shadow.shader
- Specifying translucency shaders to be used.
<shader pass="translucent" object="mesh" defines="BASE_SHADOW,TRANSLUCENT" vertex="shaders/mesh_noise/vertex.shader" fragment="core/shaders/default/mesh/fragment_base_shadow.shader"/>
A shader element consists of the following attributes:
- pass - a name of the described pass, translucent
- object - an object to which a shader will be applied, mesh
- defines - shader definitions, BASE_SHADOW, TRANSLUCENT
- vertex - a path to the custom vertex shader, samples/shaders/shaders/mesh_noise/vertex.shader. This shader is written for OpenGL and DirectX APIs by using GLSL and HLSL shading languages.
- fragment - a path to the built-in fragment shader, core/shaders/default/mesh/fragment_base_shadow.shader
-
Set bindings.
<bind object="mesh_cluster" to="mesh"/> <bind object="mesh_clutter" to="mesh"/> <bind object="mesh_dynamic" to="mesh"/>
Cluster, clutter and dynamic mesh will act like a mesh.
-
Specify textures to be used for the material.
<texture name="diffuse" anisotropy="1">core/textures/mesh_base_diffuse.dds</texture> <texture name="normal" pass="deferred,ambient,light_omni,light_proj,light_world,translucent" format="signed" anisotropy="1">core/textures/mesh_base_normal.dds</texture> <texture name="specular" pass="deferred,ambient,light_omni,light_proj,light_world" anisotropy="1">core/textures/mesh_base_specular.dds</texture> <texture name="ambient" pass="ambient" unit="12" format="srgb">core/textures/mesh_base_ambient.dds</texture> <texture name="deferred_occlusion" pass="ambient" unit="13" type="deferred_occlusion"/> <texture name="deferred_light" pass="ambient" unit="15" type="deferred_light"/> <texture name="light_image" pass="light_omni,light_proj,light_world" unit="11" type="light_image"/> <texture name="light_color" pass="light_omni,light_proj,light_world" type="light_color"/> <texture name="light_depth" pass="light_omni,light_proj,light_world" type="light_depth"/> <texture name="light_noise" pass="light_omni,light_proj,light_world" type="light_noise"/> <texture name="light_vcube" pass="light_omni" type="light_vcube"/>
To create a material, 11 textures were used. Four textures, named diffuse, normal, specular and ambient are using custom textures, written in the body of the texture element. The other seven textures use built-in texture types. They are specified by the type attribute: deferred_occlusion, deferred_light, light_image, light_color, light_depth, light_noise and light_vcube correspondingly.
An anisotropy flag of the diffuse texture is set to 1, so anisotropy effect for the diffuse texture is enabled.
The pass element specifies the pass during which textures will be rendered: deferred, ambient, light_omni, light_proj, light_world or translucent depending on the texture. For the diffuse texture, the pass is not specified, so it will be rendered during all of the passes.
The ambient, deferred_light, deferred_occlusion and light_image textures have an unit attribute, specifying the number of a Texture Mapping Unit: 12, 13, 15 and 11 correspondingly.
The normal and ambient textures have an attribute format, specifying the format of the texture, signed and srgb correspondingly.
-
Set parameters of the material.
<parameter name="base_transform" type="expression" shared="1">vec4(1.0f,1.0f,0.0f,0.0f)</parameter> <parameter name="environment_scale" type="slider" shared="1" min="0.0" max="4.0" flags="max_expand">1.0</parameter> <parameter name="diffuse_color" type="color" shared="1">1.0 1.0 1.0 1.0</parameter> <parameter name="diffuse_scale" type="slider" min="0.0" max="4.0" flags="max_expand">1.0</parameter> <parameter name="specular_color" type="color" shared="1">1.0 1.0 1.0 1.0</parameter> <parameter name="specular_scale" type="slider" min="0.0" max="4.0" flags="max_expand">1.0</parameter> <parameter name="specular_power" type="slider" shared="1" min="0.0" max="2.0" flags="log10,max_expand">16.0</parameter> <parameter name="phong_rim_width" type="slider" min="0.0" max="1.0">0.5</parameter> <parameter name="phong_rim_scale" type="slider" min="0.0" max="1.0">0.0</parameter> <parameter name="fresnel_bias" type="slider" min="0.0" max="1.0">1.0</parameter> <parameter name="fresnel_power" type="slider" min="0.0" max="1.0" flags="log10,max_expand">5.0</parameter> <parameter name="noise_transform" type="constant" shared="1">0.0 0.0 0.0 0.0</parameter> <parameter name="vertex_noise" type="array" shared="1"/>
The material has 11 built-in and 2 custom parameters. Built-in parameters: base_transform, environment_scale, diffuse_color, diffuse_scale, specular_color, specular_scale, specular_power, phong_rim_width, phong_rim_scale, fresnel_bias and fresnel_power. Custom parameters: noise_transform and vertex_noise.
The vertex_noise is an array of 66 variables. The noise_transform parameter changes the coordinates of the mesh vertices each frame in accordance with the noise, created by the vertex_noise parameter.
The parameter elements consist of the following attributes: