• System

Texture compression

By: SKY ENGINE AI
scroll down ↓to find out moretexture-compression_1_resourcesTutorial

Texture compression

In this section you will get to know how to utilize texture compression.

Agenda:

  • Texture compression introduction
  • FileTextureProvider compression configuration
  • HDRTextureProvider compression configuration
  • SubstanceTextureProvider compression confguration
  • Add textures, substances and background

Scene setup

Let's use custom scene composer to set up the scene.
Scene consists of:

  • sphere - location: (0, 0, -1.1)
  • cube - location: (0, 0, 1.1)
  • green sphere light - location: (6, 4, -5)
  • red sphere light - location: (6, 4, -5)
  • camera - location: (6, 4, 3))
    from skyrenderer.cases.utils import TextureCompressionSceneComposer
    scene_composer = TextureCompressionSceneComposer()
    scene_composer.setup_scene()
2025-02-14 12:47:01,844 | skyrenderer.scene.renderer_context |  INFO: Root paths:
- root path: /home/skyengine/anaconda/lib/python3.6/site-packages/skyrenderer
- assets path: /dli/mount/assets
- config path: /home/skyengine/anaconda/lib/python3.6/site-packages/skyrenderer/config
- gpu sources path: /home/skyengine/anaconda/lib/python3.6/site-packages/skyrenderer/optix_sources/sources
- cache path: /dli/mount/cache
- ptx cache path: compiled_ptx/ptx
- ocio path: ocio_configs/aces_1.2/config.ocio

Texture compression introduction

Texture compression is a technique that enables efficient storage and rendering of texture data by reducing VRAM
memory usage without affecting visual quality.

In SkyRenderer compression is generally handled automatically; all we need to do is enable it and configure the
compression settings.
There are three independent switches and configurations for texture compression, each specific to:

  • FileTextureProvider: for standard textures loaded from formats like PNG, JPG, HDR, EXR, etc.
  • HdrTextureProvider: for HDR environment maps
  • SubstanceTextureProvider: for textures rendered through Substance
  • SubstanceTextureProvider compression configuration
    We use all three providers here and enable compression for each of them.

FileTextureProvider compression configuration

For FileTextureProvider we are using predefined "default" compression configuration.
Should be fine for typical use.

    from skyrenderer.basic_types.provider import FileTextureProvider
    FileTextureProvider.configure_image_compression("default")
    FileTextureProvider.COMPRESSION_ENABLED = True

HDRTextureProvider compression configuration

For both env_map and env_map_light we are using BC6H format.
This is the only format that supports 16-bit floating-point channels.
It supports only RGB (no alpha), but for environment maps this is fine.
There is no higher quality format for environment maps available.
This format has 8 bits per texel.

    from skyrenderer.basic_types.provider import HdrTextureProvider
    import numpy as np
    hdr_compression_config = {
        ("env_map", np.dtype(np.float32)): "BC6H",
        ("env_map_light", np.dtype(np.float32)): "BC6H",
    }
    HdrTextureProvider.configure_image_compression(hdr_compression_config)
    HdrTextureProvider.COMPRESSION_ENABLED = True

SubstanceTextureProvider compression confguration

  • For base_color_map we are using BC7 format. This is the highest quality format that supports RGB/RGBA
    textures with 8-bit channels (uint8).
    This format has 8 bits per texel, so for float32 we are compressing by a factor of 16.
    Note, that Substance actually produces float32 texture here.
    We are loosing bit-depth here by reducing to uint8, but it's fine for this texture.
  • For roughness_map we are using BC4 format. This is the only single-channel compressed format available.
    It supports only 8-bit channels (uint8).
    This format has 4 bits per texel, so for float32 we are compressing by a factor of 8.
    Note, that Substance actually produces float32 texture here.
    We are loosing bit-depth here by reducing to uint8, but it's fine for this texture.
  • For normal_map we are using BC6H format. This is the only format that supports 16-bit floating-point
    channels. It supports only RGB (no alpha), but for normals this is fine.
    There is no higher quality format for normals available.
    Note, that Substance actually produces float32 texture here, we are reducing it to float16.
    from skyrenderer.basic_types.provider import SubstanceTextureProvider
    substance_compression_config = {
        ("base_color_map", np.dtype(np.float32)): "BC7",
        ("roughness_map", np.dtype(np.float32)): "BC4",
        ("normal_map", np.dtype(np.float32)): "BC6H",
    }
    SubstanceTextureProvider.configure_image_compression(substance_compression_config)
    SubstanceTextureProvider.COMPRESSION_ENABLED = True

Add textures, substances and background

Create texture providers

Everything is done as usual here, no need to do anything related to compression.
Note, that specific textures might have override compression parameters defined in their JSON's.

    texture_provider = FileTextureProvider(scene_composer.renderer_context, "yummy_scones/wood")
    substance_provider = SubstanceTextureProvider(scene_composer.renderer_context, "marble_valencia")
    background_texture_provider = HdrTextureProvider(
        scene_composer.renderer_context,
        "spruit_sunrise_4k",
        gamma=1.0,
        intensity=1.0,
        gamma_light=1.0,
        intensity_light=1.0,
    )
2025-02-14 12:47:02,753 | skyrenderer.basic_types.provider.unit_providers.hdr_texture_provider |  WARNING: Parameter light_adapt provided in HDR json is not supported

2025-02-14 12:47:02,754 | skyrenderer.basic_types.provider.unit_providers.hdr_texture_provider |  WARNING: Parameter color_adapt provided in HDR json is not supported

Create shader and set materials

Create shader and materials in a regular way, nothing related to compression here.

    from skyrenderer.basic_types.procedure import PBRShader
    from skyrenderer.scene.scene_layout.layout_elements_definitions import MaterialDefinition
    shader_procedure = PBRShader(scene_composer.renderer_context)
    shader_parameter_provider = PBRShader.create_parameter_provider(
        scene_composer.renderer_context, base_color=(1.0, 1.0, 1.0), roughness=0.02, specular_factor=0.8
    )
    scene_composer.renderer_context.set_material_definition(
        "sphere_GEO", MaterialDefinition(substance_provider, shader_procedure, shader_parameter_provider)
    )
    scene_composer.renderer_context.set_material_definition(
        "cube_001_GEO", MaterialDefinition(texture_provider, shader_procedure, shader_parameter_provider)
    )

Add background envmap

Also nothing unusual here, no need to worry about texture compression.

    from skyrenderer.basic_types.procedure import EnvMapMiss
    from skyrenderer.basic_types.item_component import Background
    background_def = Background(
        scene_composer.renderer_context,
        EnvMapMiss(scene_composer.renderer_context),
        background_texture_provider,
        EnvMapMiss.create_parameter_provider(scene_composer.renderer_context, max_hdr_value=10),
    )
    scene_composer.renderer_context.define_env(background_def)
    scene_composer.visualize()
texture-compression_1_resourcesTutorial
2025-02-14 12:47:04,953 | skyrenderer.utils.time_measurement |  INFO: Setup time: 2.18 seconds

2025-02-14 12:47:08,718 | skyrenderer.utils.time_measurement |  INFO: Context update time: 3.76 seconds

2025-02-14 12:47:13,406 | skyrenderer.utils.time_measurement |  INFO: Key points calculation time: 0 ms

2025-02-14 12:47:13,408 | skyrenderer.utils.time_measurement |  INFO: Render time: 4.69 seconds

Summary

In this section you have learnt:

  • Texture compression can help you reduce VRAM usage.
  • SkyRenderer provides texture compression for file, hdr and substance textures.
  • To turn texture compression on, we need to set certain global flags to true.