Out of many shaders available in SkyEngine one of specialized shader enabling representation of thin translucent surfaces is SimpleTranslucentShader.
Translucency is a phenomenon quite common in surrounding us world. It should not be mistaken with transparency. Transparent objects pass light - as glass, however translucent objects pass light only partially. In transparency phenomenon light rays' direction after passing transparent layer is unchanged, in translucency rays passing translucent layers are slightly bent.
SimpleTranslucentShader is created based on translucent and PBR diffuse mix model based rendering. This model is modelling translucency by scattering transmission rays upon surface intersection. This shader is suitable for mostly one-sided or double-sided thin geometries for which translucency is required, such as sheet paper or leaf material.
Firstly we need to configure logging, RendererContext and ExampleAssistant.
from skyrenderer.core.logger_config import configure_logger
from skyrenderer.example_assistant.display_config import DisplayConfig
from skyrenderer.example_assistant.example_assistant import ExampleAssistant
from skyrenderer.scene.renderer_context import RendererContext
from skyrenderer.utils.visualization_helper import visualize
from 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:00:55,598 | 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:00:55,599 | skyrenderer.core.asset_manager.asset_manager | INFO: Syncing assets...
Then we load a scene.
renderer_context.load_abc_scene("translucent_shader/autumn_leaves")
logger.info(renderer_context.layout())
2024-11-11 11:01:00,509 | skyrenderer | INFO:
top_node
|-- point_LIGHT_NUL
|-- leaf_GEO_NUL_001
| +-- leaf_GEO_001
|-- leaf_GEO_NUL
| +-- leaf_GEO
+-- camera_CAM_NUL
+-- camera_CAM
Then, setup lights and scene background.
from skyrenderer.basic_types.light import PointLightfrom
skyrenderer.basic_types.provider import HdrTextureProviderfrom
skyrenderer.basic_types.item_component import Backgroundfrom
skyrenderer.basic_types.procedure import EnvMapMiss
renderer_context.set_light(
PointLight(
renderer_context, "point_LIGHT_NUL", PointLight.create_parameter_provider(renderer_context, illuminance=2.5)
)
)
renderer_context.set_light(
PointLight(
renderer_context, "camera_CAM_NUL", PointLight.create_parameter_provider(renderer_context, illuminance=10)
)
)
renderer_context.define_env(
Background(
renderer_context,
EnvMapMiss(renderer_context),
HdrTextureProvider(renderer_context, "light_sky", angular_shift=-90, gamma_light=1, gamma=1),
EnvMapMiss.create_parameter_provider(renderer_context, max_hdr_value=1),
)
)
2024-11-11 11:01:00,520 | skyrenderer.basic_types.provider.unit_providers.hdr_texture_provider | WARNING: Parameter light_adapt provided in HDR json is not supported
2024-11-11 11:01:00,520 | skyrenderer.basic_types.provider.unit_providers.hdr_texture_provider | WARNING: Parameter color_adapt provided in HDR json is not supported
Then we can set up materials for our test objects. The scene consists of two leaves. One of leaves is assigned a PBR and a second SimpleTranslucentShader. Behind the leaves there is a point light located, enabling visualization of translucency phenomenon. Now, lets setup leaves. We will start with PBRShader leaf. Each material, as described in 12_materials tutorial, requires the 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,
- procedure - pack of programs responsible for shading - for a first leaf we will use default one, for a second SimpleTranslucentShader,
- parameter_provider - parameters required by the procedure to work - these allow further customization, we will present with a second leaf using SimpleTranslucentShader,
- strategy and randomization_group - rules for randomization, not used in this demo script.
from skyrenderer.scene.scene_layout.layout_elements_definitions import MaterialDefinition
from skyrenderer.basic_types.provider import FileTextureProvider
leaf_texture_provider = FileTextureProvider(renderer_context, "maple_leaf")
renderer_context.set_material_definition(
"leaf_GEO_001",
MaterialDefinition(
texture_provider=leaf_texture_provider,
),
)
We will now define the parameters for SimpleTranslucentShader rendering. These are described in detail in the table below:
Parameter name | Parameter description | Parameter default value |
---|---|---|
alpha | Material transparency - 0-fully transparent, 1-opaque. | 1.0 |
ambient_color | This parameter represents color of the material's ambient light response. | (1, 1, 1) |
ambient_gain | This parameter represents how strong is material's ambient light response. | 0 |
base_color | Default color of material - often replaced with base_color map. | (1, 1, 1) |
clearcoat_factor | This parameter represents how strong is material's clearcoat layer. | 0.0 |
clearcoat_roughness | Roughness value for clearcoat layer. | 0.0 |
min_shadow_attenuation | Cutoff for shadows (importance below attenuation would be ignored). | 0.1 |
roughness | This parameter simulates tiny bumps and scratches on the surface which increases the spread of light. | 0.5 |
specular_gain | This parameter represents how strong is material's specular component in BRDF function. | 0.04 |
tex_scale | Scaling factor for tiled textures - the higher the parameter value, the denser pattern is produced. | (1, 1) |
translucency | Translucency blend factor between translucent and PBR Shader - the higher the value, the more transparent/translucent the object. | 0.5 |
translucency_roughness | Translucency roughness factor. The higher the value, more translucent the object; the lower the value - the more transparent the object. | 0.1 |
use_reflections | Parameter turning on/off reflections for shader. | True |
from skyrenderer.basic_types.procedure.shader.basic_shaders.simple_translucent_shader import SimpleTranslucentShader
renderer_context.set_material_definition(
"leaf_GEO",
MaterialDefinition(
shader=SimpleTranslucentShader(renderer_context),
parameter_set=SimpleTranslucentShader.create_parameter_provider(
renderer_context, base_color=(0.8, 0.2, 0), translucency=1.0
),
),
)
Finally, we can set up render chain, post process steps and visualization.
from skyrenderer.render_chain import VisibleLightRenderStep
from skyrenderer.render_chain.camera_steps.Lens.pinhole_lens import PinholeLens
from skyrenderer.render_chain import Denoiser
from skyrenderer.render_chain import RenderChain
lens = PinholeLens(renderer_context, PinholeLens.create_hfov_parameter_provider(renderer_context, hfov=20))
vis_step = VisibleLightRenderStep(
renderer_context,
lens=lens,
origin_name="camera_CAM_NUL",
target_name="leaf_GEO_NUL",
parameter_provider=VisibleLightRenderStep.create_parameter_provider(renderer_context, antialiasing_level=128),
)
denoiser = Denoiser(renderer_context, Denoiser.create_parameter_provider(renderer_context, blend=0.5))
renderer_context.define_render_chain(RenderChain([vis_step, denoiser], width=960, height=540))
Then we can setup, print and render our scene.
from skyrenderer.utils.visualization_helper import generate_renders
renderer_context.setup()logger.info(renderer_context.layout())visualize(example_assistant, generate_renders(renderer_context))
2024-11-11 11:01:02,516 | skyrenderer.utils.time_measurement | INFO: Setup time: 1.96 seconds
2024-11-11 11:01:02,517 | skyrenderer | INFO:
top_node
|-- point_LIGHT_NUL
|-- leaf_GEO_NUL_001
| +-- leaf_GEO_001
|-- leaf_GEO_NUL
| +-- leaf_GEO
+-- camera_CAM_NUL
+-- camera_CAM
2024-11-11 11:01:02,520 | skyrenderer.basic_types.provider.unit_providers.hdr_texture_provider | INFO: Background HDR (/dli/mount/assets/ren_tutorials/background_hdrs/light_sky/light_sky_bg.hdr) is being processed, this may take a while...
2024-11-11 11:01:03,755 | skyrenderer.utils.time_measurement | INFO: Context update time: 1.24 seconds
2024-11-11 11:01:12,170 | skyrenderer.utils.time_measurement | INFO: Key points calculation time: 0 ms
2024-11-11 11:01:12,171 | skyrenderer.utils.time_measurement | INFO: Render time: 8.42 seconds
Let's change values of some parameters of the shader to get better understanding how they influence render. We will start with base_color by decreasing value of Red channel and increasing Green channel. We will use generate_renders_with_setup wrapper, so we have less lines of code.
from skyrenderer.utils.visualization_helper import generate_renders_with_setup
renderer_context.instancers["leaf_GEO"].modify_material_definition(
shader=SimpleTranslucentShader(renderer_context),
parameter_provider=SimpleTranslucentShader.create_parameter_provider(
renderer_context, base_color=(0.2, 0.8, 0), translucency=1.0
),
)
visualize(example_assistant, generate_renders_with_setup(renderer_context))
2024-11-11 11:01:12,482 | skyrenderer.utils.time_measurement | INFO: Setup time: 83 ms
2024-11-11 11:01:13,082 | skyrenderer.utils.time_measurement | INFO: Context update time: 599 ms
2024-11-11 11:01:17,125 | skyrenderer.utils.time_measurement | INFO: Key points calculation time: 0 ms
2024-11-11 11:01:17,125 | skyrenderer.utils.time_measurement | INFO: Render time: 4.04 seconds
Now we will return to the previous values of the leaf color, however we will increase value of translucency roughness expecting a leaf to bend rays more causing a leaf behind to be more blured.
renderer_context.instancers["leaf_GEO"].modify_material_definition(
shader=SimpleTranslucentShader(renderer_context),
parameter_provider=SimpleTranslucentShader.create_parameter_provider(
renderer_context, base_color=(0.8, 0.2, 0), translucency=1.0, translucency_roughness=1.0
),
)
visualize(example_assistant, generate_renders_with_setup(renderer_context))
2024-11-11 11:01:17,391 | skyrenderer.utils.time_measurement | INFO: Setup time: 73 ms
2024-11-11 11:01:17,983 | skyrenderer.utils.time_measurement | INFO: Context update time: 591 ms
2024-11-11 11:01:23,622 | skyrenderer.utils.time_measurement | INFO: Key points calculation time: 0 ms
2024-11-11 11:01:23,623 | skyrenderer.utils.time_measurement | INFO: Render time: 5.64 seconds
Let's decrease translucency_roughness value to get sharper leaf.
renderer_context.instancers["leaf_GEO"].modify_material_definition(
shader=SimpleTranslucentShader(renderer_context),
parameter_provider=SimpleTranslucentShader.create_parameter_provider(
renderer_context, base_color=(0.8, 0.2, 0), translucency=1.0, translucency_roughness=0.1
),
)
visualize(example_assistant, generate_renders_with_setup(renderer_context))
2024-11-11 11:01:23,921 | skyrenderer.utils.time_measurement | INFO: Setup time: 74 ms
2024-11-11 11:01:24,517 | skyrenderer.utils.time_measurement | INFO: Context update time: 595 ms
2024-11-11 11:01:28,561 | skyrenderer.utils.time_measurement | INFO: Key points calculation time: 0 ms
2024-11-11 11:01:28,561 | skyrenderer.utils.time_measurement | INFO: Render time: 4.04 seconds
Now we will decrease translucency value what will cause leaf to pass less light.
renderer_context.instancers["leaf_GEO"].modify_material_definition(
shader=SimpleTranslucentShader(renderer_context),
parameter_provider=SimpleTranslucentShader.create_parameter_provider(
renderer_context, base_color=(0.8, 0.2, 0), translucency=0.4, translucency_roughness=0.1
),
)
visualize(example_assistant, generate_renders_with_setup(renderer_context))
2024-11-11 11:01:28,844 | skyrenderer.utils.time_measurement | INFO: Setup time: 75 ms
2024-11-11 11:01:29,437 | skyrenderer.utils.time_measurement | INFO: Context update time: 591 ms
2024-11-11 11:01:33,100 | skyrenderer.utils.time_measurement | INFO: Key points calculation time: 0 ms
2024-11-11 11:01:33,101 | skyrenderer.utils.time_measurement | INFO: Render time: 3.66 seconds
Now we will increase translucency_roughness to again blur a leaf behind a bit.
renderer_context.instancers["leaf_GEO"].modify_material_definition(
shader=SimpleTranslucentShader(renderer_context),
parameter_provider=SimpleTranslucentShader.create_parameter_provider(
renderer_context, base_color=(0.8, 0.2, 0), translucency=0.4, translucency_roughness=0.4
),
)
visualize(example_assistant, generate_renders_with_setup(renderer_context))
2024-11-11 11:01:33,399 | skyrenderer.utils.time_measurement | INFO: Setup time: 75 ms
2024-11-11 11:01:33,989 | skyrenderer.utils.time_measurement | INFO: Context update time: 589 ms
2024-11-11 11:01:37,671 | skyrenderer.utils.time_measurement | INFO: Key points calculation time: 0 ms
2024-11-11 11:01:37,671 | skyrenderer.utils.time_measurement | INFO: Render time: 3.68 seconds
In the final render let's add texture provider to the leaf with translucent shader.
renderer_context.instancers["leaf_GEO"].modify_material_definition(
texture_provider=leaf_texture_provider,
shader=SimpleTranslucentShader(renderer_context),
parameter_provider=SimpleTranslucentShader.create_parameter_provider(
renderer_context, translucency=1.0, translucency_roughness=1.0
),
)
visualize(example_assistant, generate_renders_with_setup(renderer_context))
2024-11-11 11:01:37,981 | skyrenderer.utils.time_measurement | INFO: Setup time: 74 ms
2024-11-11 11:01:38,580 | skyrenderer.utils.time_measurement | INFO: Context update time: 599 ms
2024-11-11 11:01:48,137 | skyrenderer.utils.time_measurement | INFO: Key points calculation time: 0 ms
2024-11-11 11:01:48,138 | skyrenderer.utils.time_measurement | INFO: Render time: 9.56 seconds
Other parameters can be also modified in the SimpleTranslucentShader, however modifications presented in this tutorial should be a good starting point for the further experiments of this shader's capabilities.
The end.