First, we just need to configure logging, RendererContext and the ExampleAssistant.
from skyrenderer.core.logger_config import configure_loggerfrom skyrenderer.scene.renderer_context import RendererContextfrom skyrenderer.example_assistant.display_config import DisplayConfigfrom skyrenderer.example_assistant.example_assistant import ExampleAssistantfrom skyrenderer.utils.visualization_helper import generate_renders_with_setup, visualizefrom skyrenderer.utils.tutorial_config import get_tutorial_root_paths
logger = configure_logger()root_paths_config = get_tutorial_root_paths()renderer_context = RendererContext(root_paths_config)example_assistant = ExampleAssistant(context=renderer_context, display_config=DisplayConfig.create_display_config())
2024-11-11 11:41:06,499 | skyrenderer.scene.renderer_context | INFO: Root paths:
- root path: /dli/skyenvironment/skyrenderer/skyrenderer
- assets path: /dli/mount/assets/ren_tutorials
- 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
2024-11-11 11:41:06,500 | skyrenderer.core.asset_manager.asset_manager | INFO: Syncing assets...
Default material
In SkyRenderer freshly created RendererContext has simple default scene configured. This scene consists of one
object - a sphere, paired with PBR material with no maps.
2024-11-11 11:41:11,105 | skyrenderer.scene.renderer_context | WARNING: Scene layout "user_defined" is empty - using default
2024-11-11 11:41:11,660 | skyrenderer.utils.time_measurement | INFO: Setup time: 572 ms
2024-11-11 11:41:11,735 | skyrenderer.utils.time_measurement | INFO: Context update time: 74 ms
2024-11-11 11:41:12,522 | skyrenderer.utils.time_measurement | INFO: Key points calculation time: 0 ms
2024-11-11 11:41:12,523 | skyrenderer.utils.time_measurement | INFO: Render time: 787 ms
You have probably noticed warning - every use of defaults in SkyRenderer is reported in order to avoid undefined behavior, especially for day lasting experiments.
renderer_context.copy_default_layout("user_defined")
In SkyRenderer each object (rendered item, light, camera, locator) has its own node in scene tree. Sphere from default layout is attached to sphere_GEO node.
logger.info(renderer_context.layout(name="user_defined"))
2024-11-11 11:41:12,659 | skyrenderer | INFO:
top_node
|-- sphere_GEO
|-- camera_CAM
|-- camera_target_NUL
+-- light_LIGHT_NUL
Material definition
In that example we will present the same scene with different material configured.
In the beginning we should prepare a new material definition and store it in our RendererContext.
We don't have to store reference, material will be stored in context with key defined as name.
Each material requires following parameters to be fully defined:
- provider - asset and data source for material (e.g. texture loading interface).
In this example we will use FileTextureProvider, which binds ours script with texture directory - test_grid_bw. - procedure/shader - pack of programs responsible for shading.
- parameter_provider - parameters required by procedure to work.
- strategy and randomization_group - rules for randomization, not used here.
We can reconfigure material for object by invoking set_material_definition
method. We will start with
simple Phong's model. As a texture we will use black and white test grid.
from skyrenderer.basic_types.provider import FileTextureProvider
from skyrenderer.scene.scene_layout.layout_elements_definitions import MaterialDefinition
from skyrenderer.basic_types.procedure import PhongShader
renderer_context.set_material_definition(
"sphere_GEO",
MaterialDefinition(
texture_provider=FileTextureProvider(renderer_context, "test_grid_bw"),
shader=PhongShader(renderer_context),
parameter_set=PhongShader.create_parameter_provider(renderer_context),
),
)
visualize(example_assistant, generate_renders_with_setup(renderer_context))
2024-11-11 11:41:12,741 | skyrenderer.utils.time_measurement | INFO: Setup time: 74 ms
2024-11-11 11:41:12,810 | skyrenderer.utils.time_measurement | INFO: Context update time: 68 ms
2024-11-11 11:41:13,345 | skyrenderer.utils.time_measurement | INFO: Key points calculation time: 0 ms
2024-11-11 11:41:13,347 | skyrenderer.utils.time_measurement | INFO: Render time: 536 ms
Physically based rendering - metallic roughness shader
Now we could change shading model.
Bidirectional scattering distribution function (BSDF in short), names a model which describes complex surface-light interactions. Phong's model used in previous example is one of BSDF models, where both specular and diffuse factors are modeled with linear function of ray-light angle cosine.
Physically based rendering's principle is to approximate real material's BSDF function to achieve photorealistic results and reduce computational complexity. What is more, hyper-parameters used in that model are defined in a more intuitive and handful way. In order to reduce computational complexity additional pre-made maps (e.g. normal map, specular map, etc) are used.
We can also change part of material definition by accessing object intstancer. In that case, we can modify
shader, provider and parameter set independently.
renderer_context.instancers["sphere_GEO"].modify_material_definition(
parameter_provider=PhongShader.create_parameter_provider(renderer_context, tex_scale=3)
)
visualize(example_assistant, generate_renders_with_setup(renderer_context))
2024-11-11 11:41:13,512 | skyrenderer.utils.time_measurement | INFO: Setup time: 56 ms
2024-11-11 11:41:13,582 | skyrenderer.utils.time_measurement | INFO: Context update time: 69 ms
2024-11-11 11:41:14,124 | skyrenderer.utils.time_measurement | INFO: Key points calculation time: 0 ms
2024-11-11 11:41:14,125 | skyrenderer.utils.time_measurement | INFO: Render time: 543 ms
from skyrenderer.basic_types.procedure import PBRShader
renderer_context.set_material_definition(
"sphere_GEO",
MaterialDefinition(
texture_provider=FileTextureProvider(renderer_context, "bricks"),
parameter_set=PBRShader.create_parameter_provider(renderer_context, specular_factor=0.0, tex_scale=(3, 3)),
),
)
visualize(example_assistant, generate_renders_with_setup(renderer_context))
2024-11-11 11:41:14,298 | skyrenderer.utils.time_measurement | INFO: Setup time: 63 ms
2024-11-11 11:41:14,546 | skyrenderer.utils.time_measurement | INFO: Context update time: 247 ms
2024-11-11 11:41:15,798 | skyrenderer.utils.time_measurement | INFO: Key points calculation time: 0 ms
2024-11-11 11:41:15,800 | skyrenderer.utils.time_measurement | INFO: Render time: 1.25 seconds
Substance shader
In this example we will load adobe's substance as a source of shader maps.
If the assets are ordered correctly inside our assets structure, we can simply use the folder name as configuration.
from skyrenderer.basic_types.provider import SubstanceTextureProvider
substance_provider = SubstanceTextureProvider(renderer_context, "cliff")
renderer_context.instancers["sphere_GEO"].modify_material_definition(texture_provider=substance_provider)
visualize(example_assistant, generate_renders_with_setup(renderer_context))
2024-11-11 11:41:19,793 | 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
2024-11-11 11:41:19,794 | 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
2024-11-11 11:41:19,859 | skyrenderer.utils.time_measurement | INFO: Setup time: 65 ms
2024-11-11 11:41:19,931 | skyrenderer.utils.time_measurement | INFO: Context update time: 71 ms
2024-11-11 11:41:21,112 | skyrenderer.utils.time_measurement | INFO: Key points calculation time: 0 ms
2024-11-11 11:41:21,113 | skyrenderer.utils.time_measurement | INFO: Render time: 1.18 seconds