• Assets
  • Featured
  • Intro

Materials

By: SKY ENGINE AI
scroll down ↓to find out morematerials_5_resourcesTutorial

Materials Introduction

In this tutorial you will learn how materials are processed in SkyRenderer. We will walk through the process
of defining Material instance and applying this Material to the mesh.

Agenda:

  • Material Definition
  • Setting Material to an Object
  • HDR Textures

Material Definition

MaterialDefinition is an object that stores properties describing how the material behaves.
Each Material consists of following parameters:

  • Texture Provider - asset and data source for material (e.g. texture loading interface),
  • Shader (Procedure) - procedures responsible for shading,
  • Parameter Provider - procedure's parameters required by procedure to work,
  • Strategy and Randomization Group - rules for randomization.

Texture Provider

It should be considered as an interface that loads textures from files. Texture Providers look for textures in
connected assets repository. SkyRenderer contains two main interfaces to load textures from available assets:

  • FileTextureProvider - texture file maps (.png, .jpg, .tiff) from directory "textures"
  • SubstanceTextureProvider - materials from substance maps (.sbsar) from directory "substances"

Shader

A procedure responsible for shading process describing how particular surface will physically behave under
the rays. In SkyRenderer we have many types of shaders implemented like:

  • PBRShader (Physically Based Rendering Shader)
  • SkinShader
  • PhongShader
  • TranslucentShader
  • GlassShader
  • many more

Most effects are covered by PBRShader since it is the most universal shader, however for some materials it is
worth to use specialized shaders for a higher quality of the output renders.

Parameter Provider

Each shader has their own Parameter Provider class, that passes values of shader-specific parameters to the
shader procedure. To create a Parameter Provider we call shader's .create_parameter_provider() method.
In case we do not specify parameter values, default one are used. Available parameters and their default values
can be checked in shader's documentation.

Strategy and Randomization Group

We can define Material's Randomization Strategy and Group to enable randomization and synchronization of
materials.

Detailed usage of Texture Providers, Shaders and Randomization can be found in detailed cases for each of these
topics.

Setting Material to an Object

Let's render a scene with a shaderball with a default texture applied and see how we can set a Material Definition
to an Object.

    from skyrenderer.cases.utils import MaterialsSceneComposer
    scene_composer = MaterialsSceneComposer(antialiasing_level=256)
    scene_composer.setup_scene(render_width=1600, render_height=1000)
    scene_composer.visualize(scene_composer.get_render())
materials_1_resourcesTutorial
2025-02-06 14:03:38,952 | skyrenderer.scene.renderer_context |  INFO: Root paths:
- root path: /dli/skyenvironment/skyrenderer/skyrenderer
- assets path: /dli/mount/assets
- config path: /dli/skyenvironment/skyrenderer/skyrenderer/config
- gpu sources path: /dli/skyenvironment/skyrenderer/skyrenderer/optix_sources/sources
- cache path: /dli/mount/cache
- ptx cache path: compiled_ptx/ptx
- ocio path: ocio_configs/aces_1.2/config.ocio

2025-02-06 14:03:39,388 | skyrenderer.utils.time_measurement |  INFO: Setup time: 402 ms

2025-02-06 14:03:42,134 | skyrenderer.utils.time_measurement |  INFO: Context update time: 2.74 seconds

2025-02-06 14:03:54,681 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-02-06 14:03:54,682 | skyrenderer.utils.time_measurement |  INFO: Render time: 12.55 seconds

Let's create a glass Material Definition using GlassShader and assign this material to the shaderball
To assign the material we will use RendererContext's .set_material_definition() method.

    from skyrenderer.scene.scene_layout.layout_elements_definitions import MaterialDefinition
    from skyrenderer.basic_types.procedure.shader.basic_shaders.glass_shader import GlassShader
    glass_shader = GlassShader(scene_composer.renderer_context)
    glass_material_definition = MaterialDefinition(shader=glass_shader)
    scene_composer.renderer_context.set_material_definition(
        node_name="shaderball_GEO", material_definition=glass_material_definition
    )
    scene_composer.visualize(scene_composer.get_render())
materials_2_resourcesTutorial
2025-02-06 14:03:55,309 | skyrenderer.utils.time_measurement |  INFO: Setup time: 70 ms

2025-02-06 14:03:58,166 | skyrenderer.utils.time_measurement |  INFO: Context update time: 2.86 seconds

2025-02-06 14:04:04,476 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-02-06 14:04:04,477 | skyrenderer.utils.time_measurement |  INFO: Render time: 6.31 seconds

We can also assign a texture from files. Let's use black and white test grid texture available in assets
repository and PBRShader.

    from skyrenderer.basic_types.procedure import PBRShader
    from skyrenderer.basic_types.provider import FileTextureProvider
    grid_bw_file_texture_provider = FileTextureProvider(scene_composer.renderer_context, "test_grid_bw")
    pbr_shader = PBRShader(scene_composer.renderer_context)
    grid_bw_material_definition = MaterialDefinition(
        texture_provider=grid_bw_file_texture_provider,
        shader=pbr_shader,
    )
    scene_composer.renderer_context.set_material_definition(
        node_name="shaderball_GEO", material_definition=grid_bw_material_definition
    )
    scene_composer.visualize(scene_composer.get_render())
materials_3_resourcesTutorial
2025-02-06 14:04:05,055 | skyrenderer.utils.time_measurement |  INFO: Setup time: 62 ms

2025-02-06 14:04:07,925 | skyrenderer.utils.time_measurement |  INFO: Context update time: 2.87 seconds

2025-02-06 14:04:20,413 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-02-06 14:04:20,414 | skyrenderer.utils.time_measurement |  INFO: Render time: 12.49 seconds

Each shader has a vast range of parameters that are available to manipulate. To check parameters' values can be
changed check shader's documentation.
We will change texture scale for our shader via PBRShader's Parameter Provider:

    pbr_shader_parameter_provider = PBRShader.create_parameter_provider(scene_composer.renderer_context, tex_scale=5)
    grid_bw_material_definition = MaterialDefinition(
        texture_provider=grid_bw_file_texture_provider,
        shader=pbr_shader,
        parameter_set=pbr_shader_parameter_provider,
    )
    scene_composer.renderer_context.set_material_definition(
        node_name="shaderball_GEO", material_definition=grid_bw_material_definition
    )
    scene_composer.visualize(scene_composer.get_render())
materials_4_resourcesTutorial
2025-02-06 14:04:20,988 | skyrenderer.utils.time_measurement |  INFO: Setup time: 61 ms

2025-02-06 14:04:23,732 | skyrenderer.utils.time_measurement |  INFO: Context update time: 2.74 seconds

2025-02-06 14:04:36,961 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-02-06 14:04:36,962 | skyrenderer.utils.time_measurement |  INFO: Render time: 13.23 seconds

Textures can also origin from Substance Archive:

    from skyrenderer.basic_types.provider import SubstanceTextureProvider
    granite_substance_texture_provider = SubstanceTextureProvider(scene_composer.renderer_context, "granite")
    granite_material_definition = MaterialDefinition(
        texture_provider=granite_substance_texture_provider,
        shader=pbr_shader,
        parameter_set=pbr_shader_parameter_provider,
    )
    scene_composer.renderer_context.set_material_definition(
        node_name="shaderball_GEO", material_definition=granite_material_definition
    )
    scene_composer.visualize(scene_composer.get_render())
materials_5_resourcesTutorial
2025-02-06 14:04:37,498 | skyrenderer.basic_types.provider.unit_providers.substance_texture_provider |  WARNING: Unable to map purpose diffuse. Map will be parsed with legacy system.
	Purpose not present in ['ambientocclusion', 'basecolor', 'coatweight', 'coatroughness', 'emissive', 'height', 'metallic', 'normal', 'opacity', 'refractioncolor', 'roughness', 'specular', 'scattering', 'scatteringcolor', 'visibility', 'texturesemanticmap', 'any', 'mask']
	See: Texture and substance convention for more details. Remember, purpose mapping is case insensitive. 
	Parsed purpose : diffuse_map

2025-02-06 14:04:37,499 | skyrenderer.basic_types.provider.unit_providers.substance_texture_provider |  WARNING: Unable to map purpose glossiness. Map will be parsed with legacy system.
	Purpose not present in ['ambientocclusion', 'basecolor', 'coatweight', 'coatroughness', 'emissive', 'height', 'metallic', 'normal', 'opacity', 'refractioncolor', 'roughness', 'specular', 'scattering', 'scatteringcolor', 'visibility', 'texturesemanticmap', 'any', 'mask']
	See: Texture and substance convention for more details. Remember, purpose mapping is case insensitive. 
	Parsed purpose : glossiness_map

2025-02-06 14:04:37,566 | skyrenderer.utils.time_measurement |  INFO: Setup time: 66 ms

2025-02-06 14:04:40,493 | skyrenderer.utils.time_measurement |  INFO: Context update time: 2.93 seconds

2025-02-06 14:04:53,055 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-02-06 14:04:53,056 | skyrenderer.utils.time_measurement |  INFO: Render time: 12.56 seconds

HDR Textures

HDR Textures are a different type of textures since they are not defined by Material Definition because we do not
assign them to the mesh object. We define a whole environment in Renderer Context, and it is done via a Background
object.
Background object similarly to Material Definition requires:

  • Texture Provider - asset and data source for material (e.g. texture loading interface),
  • Shader (Procedure) - procedures responsible for shading,
  • Parameter Provider - procedure's parameters required by procedure to work.

Texture Provider

There is only one Texture Provider that works on HDRs - HDRTextureProvider. This interface loads HDR textures
from a "background_hdrs" directory in assets repository.

Shader

We distinguish two miss shader procedures that describe behavior for rays that do not hit any target and their
way and environment maps is sampled (hence "miss").

  • EnvMapMiss - returning color value from the sampled HDR map
  • ConstantColorMiss - returning constant color value regardless of the HDR map

Parameter Provider

Analogically to regular shaders each of miss programs have their Parameter Providers enabling to pass values for
procedures' parameters.

    from skyrenderer.basic_types.item_component import Background
    from skyrenderer.basic_types.provider import HdrTextureProvider
    from skyrenderer.basic_types.procedure import EnvMapMiss
    scene_composer.renderer_context.define_env(
        Background(
            renderer_context=scene_composer.renderer_context,
            texture_provider=HdrTextureProvider(scene_composer.renderer_context, "flower_road_4k", gamma_light=3),
            shader=EnvMapMiss(scene_composer.renderer_context),
        )
    )
    scene_composer.renderer_context.remove_subtree("plane_GEO")
    scene_composer.visualize(scene_composer.get_render())
materials_6_resourcesTutorial
2025-02-06 14:04:53,639 | skyrenderer.scene.renderer_context |  WARNING: Setting background definition after setup.

2025-02-06 14:04:53,639 | skyrenderer.scene.renderer_context |  WARNING: Setting light after setup. Origin refers to last scene tree set up. Lights are stored in dict - change is visible immediately; Wrong parameter provider possible

2025-02-06 14:04:53,640 | skyrenderer.scene.renderer_context |  WARNING: You are removing subtree after context setup. No changes would be done in current scene.

2025-02-06 14:04:53,702 | skyrenderer.utils.time_measurement |  INFO: Setup time: 62 ms

2025-02-06 14:04:56,893 | skyrenderer.utils.time_measurement |  INFO: Context update time: 3.19 seconds

2025-02-06 14:05:07,086 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-02-06 14:05:07,087 | skyrenderer.utils.time_measurement |  INFO: Render time: 10.19 seconds

Summary

In this section you have learnt:

  • Material Definition is an object that describes materials behavior.
  • Texture Providers, Shaders, Parameter Providers can be used to create Material Definition object.
  • Material Definition can be assigned to the Object via set_material_definition() method.
  • We can assign an environment texture via Background object via HDRTextureProvider.