Summary
BSDF.get_rgba() gives emissive_texture unconditional precedence over an authored PBR base-color texture. The packed RGBA representation therefore replaces a vehicle's intended base color with its emissive map.
HLOD tiles are the complementary case: they deliberately use a black base-color factor and place visible imagery in emissive. A fix must preserve ordinary PBR base color without regressing that representation.
Minimal reproduction
repro.py creates two 2×2 in-memory textures; it requires only a local genesis-world install and NumPy:
Before the fix, the normal-PBR assertion fails. After the fix both material shapes print PASS. It uses no GPU, renderer, downloaded asset, or network request.
Expected behavior
A nonblack PBR base-color texture remains authoritative. When its effective factor is black, the packed representation falls back to emissive imagery.
Root cause
The selection gives emissive unconditional precedence. That does not match glTF PBR semantics, where emissive is additive rather than a replacement for base color.
Proposed fix
Prefer a nonblack diffuse_texture; otherwise use emissive_texture. This retains normal PBR color while supporting black-factor emissive terrain.
Proposed change
Implemented by #3038.
Reproduction script
#!/usr/bin/env python3
"""Hermetic repro for packed-RGBA PBR/emissive selection.
Run with a local genesis-world install:
python repro.py
Before the fix, the normal-PBR assertion fails. No renderer, GPU, or external
asset is required.
"""
import numpy as np
import genesis as gs
def image(rgb: tuple[int, int, int], *, factor: tuple[float, float, float] = (1.0, 1.0, 1.0)):
return gs.textures.ImageTexture(
image_array=np.full((2, 2, 3), rgb, dtype=np.uint8),
image_color=factor,
)
def rgb(surface) -> np.ndarray:
return surface.get_rgba().image_array[..., :3]
def main() -> None:
gs.init(backend=gs.cpu, logging_level="warning")
try:
base_color = image((201, 166, 105))
emissive = image((76, 122, 64))
# Ordinary PBR keeps its base color even when an emissive map exists.
pbr = gs.surfaces.BSDF(diffuse_texture=base_color, emissive_texture=emissive)
assert np.array_equal(rgb(pbr), base_color.image_array)
# HLOD uses a base-color texture with a black factor and
# stores the visible imagery in emissive. This guards the fallback
# needed when replacing unconditional emissive precedence.
disabled_base_color = image((201, 166, 105), factor=(0.0, 0.0, 0.0))
hlod = gs.surfaces.BSDF(diffuse_texture=disabled_base_color, emissive_texture=emissive)
assert np.array_equal(
rgb(hlod),
emissive.image_array,
)
finally:
gs.destroy()
print("PASS: packed RGBA preserves PBR base color and HLOD emissive imagery")
if __name__ == "__main__":
main()
Summary
BSDF.get_rgba()givesemissive_textureunconditional precedence over an authored PBR base-color texture. The packed RGBA representation therefore replaces a vehicle's intended base color with its emissive map.HLOD tiles are the complementary case: they deliberately use a black base-color factor and place visible imagery in emissive. A fix must preserve ordinary PBR base color without regressing that representation.
Minimal reproduction
repro.pycreates two 2×2 in-memory textures; it requires only a localgenesis-worldinstall and NumPy:python repro.pyBefore the fix, the normal-PBR assertion fails. After the fix both material shapes print
PASS. It uses no GPU, renderer, downloaded asset, or network request.Expected behavior
A nonblack PBR base-color texture remains authoritative. When its effective factor is black, the packed representation falls back to emissive imagery.
Root cause
The selection gives emissive unconditional precedence. That does not match glTF PBR semantics, where emissive is additive rather than a replacement for base color.
Proposed fix
Prefer a nonblack
diffuse_texture; otherwise useemissive_texture. This retains normal PBR color while supporting black-factor emissive terrain.Proposed change
Implemented by #3038.
Reproduction script