Skip to content

Configuration

This page contains class defined in the hkw.setup module.

Config

Config dataclass

Configuration for rendering.

Attributes:

Name Type Description
sensor Sensor

Sensor settings.

film Film

Film settings.

sampler Sampler

Sampler settings.

emitters list[Emitter]

Emitter settings.

integrator Integrator

Integrator settings.

albedo_only bool

Whether to render albedo only (i.e. without shading).

Source code in hakowan/setup/config.py
@dataclass(kw_only=True, slots=True)
class Config:
    """Configuration for rendering.

    Attributes:
        sensor: Sensor settings.
        film: Film settings.
        sampler: Sampler settings.
        emitters: Emitter settings.
        integrator: Integrator settings.
        albedo_only: Whether to render albedo only (i.e. without shading).
    """
    sensor: Sensor = field(default_factory=Perspective)
    film: Film = field(default_factory=Film)
    sampler: Sampler = field(default_factory=Independent)
    emitters: list[Emitter] = field(default_factory=lambda: [Envmap()])
    integrator: Integrator = field(default_factory=Path)
    _albedo_only: bool = False

    def z_up(self):
        """Update configuration for z-up coordinate system."""
        self.sensor.location = np.array([0, -5, 0])
        self.sensor.up = np.array([0, 0, 1])
        for emitter in self.emitters:
            if isinstance(emitter, Envmap):
                emitter.up = np.array([0, 0, 1])
                emitter.rotation = 180.0

    def z_down(self):
        """Update configuration for z-down coordinate system."""
        self.sensor.location = np.array([0, 5, 0])
        self.sensor.up = np.array([0, 0, -1])
        for emitter in self.emitters:
            if isinstance(emitter, Envmap):
                emitter.up = np.array([0, 0, -1])
                emitter.rotation = 180.0

    def y_up(self):
        """Update configuration for y-up coordinate system."""
        self.sensor.location = np.array([0, 0, 5])
        self.sensor.up = np.array([0, 1, 0])
        for emitter in self.emitters:
            if isinstance(emitter, Envmap):
                emitter.up = np.array([0, 1, 0])
                emitter.rotation = 180

    def y_down(self):
        """Update configuration for y-down coordinate system."""
        self.sensor.location = np.array([0, 0, -5])
        self.sensor.up = np.array([0, -1, 0])
        for emitter in self.emitters:
            if isinstance(emitter, Envmap):
                emitter.up = np.array([0, -1, 0])
                emitter.rotation = 180

    @property
    def albedo_only(self) -> bool:
        """Whether to render albedo only (i.e. without shading)."""
        return self._albedo_only

    @albedo_only.setter
    def albedo_only(self, value: bool):
        """Whether to render albedo only (i.e. without shading).

        Note that this setting will modify Config.integrator property.
        """
        self._albedo_only = value
        if self._albedo_only:
            if not isinstance(self.integrator, AOV):
                self.integrator = AOV(
                    aovs=["albedo:albedo"], integrator=self.integrator
                )
            else:
                logger.warning("Albedo only is already enabled!")
        else:
            if isinstance(self.integrator, AOV):
                if self.integrator.integrator is not None:
                    self.integrator = self.integrator.integrator
                else:
                    self.integrator = Path()
            else:
                logger.warning("Albedo only is already disabled!")

albedo_only: bool property writable

Whether to render albedo only (i.e. without shading).

y_down()

Update configuration for y-down coordinate system.

Source code in hakowan/setup/config.py
def y_down(self):
    """Update configuration for y-down coordinate system."""
    self.sensor.location = np.array([0, 0, -5])
    self.sensor.up = np.array([0, -1, 0])
    for emitter in self.emitters:
        if isinstance(emitter, Envmap):
            emitter.up = np.array([0, -1, 0])
            emitter.rotation = 180

y_up()

Update configuration for y-up coordinate system.

Source code in hakowan/setup/config.py
def y_up(self):
    """Update configuration for y-up coordinate system."""
    self.sensor.location = np.array([0, 0, 5])
    self.sensor.up = np.array([0, 1, 0])
    for emitter in self.emitters:
        if isinstance(emitter, Envmap):
            emitter.up = np.array([0, 1, 0])
            emitter.rotation = 180

z_down()

Update configuration for z-down coordinate system.

Source code in hakowan/setup/config.py
def z_down(self):
    """Update configuration for z-down coordinate system."""
    self.sensor.location = np.array([0, 5, 0])
    self.sensor.up = np.array([0, 0, -1])
    for emitter in self.emitters:
        if isinstance(emitter, Envmap):
            emitter.up = np.array([0, 0, -1])
            emitter.rotation = 180.0

z_up()

Update configuration for z-up coordinate system.

Source code in hakowan/setup/config.py
def z_up(self):
    """Update configuration for z-up coordinate system."""
    self.sensor.location = np.array([0, -5, 0])
    self.sensor.up = np.array([0, 0, 1])
    for emitter in self.emitters:
        if isinstance(emitter, Envmap):
            emitter.up = np.array([0, 0, 1])
            emitter.rotation = 180.0

Emitter

Emitter dataclass

Emitter dataclass contains lighting-related settings.

Source code in hakowan/setup/emitter.py
@dataclass(kw_only=True, slots=True)
class Emitter:
    """Emitter dataclass contains lighting-related settings."""

    pass

Envmap dataclass

Bases: Emitter

Environment light (i.e. image-based lighting).

Attributes:

Name Type Description
filename Path

Path to the environment light image file.

scale float

Scaling factor to be applied to the environment light.

up list

Up vector of the environment light.

rotation float

Rotation angle of the environment light around the up direction.

Source code in hakowan/setup/emitter.py
@dataclass(kw_only=True, slots=True)
class Envmap(Emitter):
    """Environment light (i.e. image-based lighting).

    Attributes:
        filename: Path to the environment light image file.
        scale: Scaling factor to be applied to the environment light.
        up: Up vector of the environment light.
        rotation: Rotation angle of the environment light around the up direction.
    """

    filename: Path = field(
        default_factory=lambda: Path(__file__).parents[1] / "envmaps" / "museum.exr"
    )
    scale: float = 1.0
    up: list = field(default_factory=lambda: [0, 1, 0])
    rotation: float = 180.0

Point dataclass

Bases: Emitter

Point light source.

Attributes:

Name Type Description
intensity Color | float

Light intensity.

position list[float]

Light position.

Source code in hakowan/setup/emitter.py
@dataclass(kw_only=True, slots=True)
class Point(Emitter):
    """Point light source.

    Attributes:
        intensity: Light intensity.
        position: Light position.
    """

    intensity: Color | float
    position: list[float]

Film

Film dataclass

Film dataclass stores specifications of the output image.

Attributes:

Name Type Description
width int

Width of the output image in pixels.

height int

Height of the output image in pixels.

file_format str

File format of the output image.

pixel_format str

Pixel format of the output image.

component_format str

Component format of the output image.

crop_offset NDArray | None

Offset of the crop window in pixels.

crop_size NDArray | None

Size of the crop window in pixels.

Together, width and height specify the output image resolution. crop_offset and crop_size defines a crop region. If either is None, no cropping is performed. file_format, pixel_format and component_format are for advanced user only. The default values should work in most cases.

Source code in hakowan/setup/film.py
@dataclass(kw_only=True, slots=True)
class Film:
    """Film dataclass stores specifications of the output image.

    Attributes:
        width: Width of the output image in pixels.
        height: Height of the output image in pixels.
        file_format: File format of the output image.
        pixel_format: Pixel format of the output image.
        component_format: Component format of the output image.
        crop_offset: Offset of the crop window in pixels.
        crop_size: Size of the crop window in pixels.

    Together, `width` and `height` specify the output image resolution.
    `crop_offset` and `crop_size` defines a crop region. If either is `None`, no cropping is performed.
    `file_format`, `pixel_format` and `component_format` are for advanced user only. The default
    values should work in most cases.
    """
    width: int = 1024
    height: int = 800
    file_format: str = "openexr"
    pixel_format: str = "rgba"
    component_format: str = "float16"
    crop_offset: npt.NDArray | None = None
    crop_size: npt.NDArray | None = None

Integrator

AOV dataclass

Bases: Integrator

Arbitrary output variable (AOV) integrator.

Attributes:

Name Type Description
aovs list[str]

List of AOVs to render.

integrator Integrator | None

Integrator to use for rendering AOVs.

Note

See Mitsuba doc for supported AOV types and other details.

Source code in hakowan/setup/integrator.py
@dataclass(kw_only=True, slots=True)
class AOV(Integrator):
    """Arbitrary output variable (AOV) integrator.

    Attributes:
        aovs: List of AOVs to render.
        integrator: Integrator to use for rendering AOVs.

    Note:
        See
        [Mitsuba
        doc](https://mitsuba.readthedocs.io/en/stable/src/generated/plugins_integrators.html#arbitrary-output-variables-integrator-aov)
        for supported AOV types and other details.
    """
    aovs: list[str]
    integrator: Integrator | None = None

Direct dataclass

Bases: Integrator

Direct integrator.

Attributes:

Name Type Description
shading_samples int | None

Number of shading samples.

emitter_samples int | None

Number of emitter samples.

bsdf_samples int | None

Number of BSDF samples.

Note

See Mitsuba doc for more details.

Source code in hakowan/setup/integrator.py
@dataclass(kw_only=True, slots=True)
class Direct(Integrator):
    """Direct integrator.

    Attributes:
        shading_samples: Number of shading samples.
        emitter_samples: Number of emitter samples.
        bsdf_samples: Number of BSDF samples.

    Note:
        See
        [Mitsuba doc](https://mitsuba.readthedocs.io/en/stable/src/generated/plugins_integrators.html#direct-illumination-integrator-direct)
        for more details.
    """
    shading_samples: int | None = None
    emitter_samples: int | None = None
    bsdf_samples: int | None = None

Integrator dataclass

Integrator dataclass contains parameters of various rendering techniques.

Attributes:

Name Type Description
hide_emitters bool

Whether to hide emitters from the camera.

Source code in hakowan/setup/integrator.py
@dataclass(kw_only=True, slots=True)
class Integrator:
    """Integrator dataclass contains parameters of various rendering techniques.

    Attributes:
        hide_emitters: Whether to hide emitters from the camera.
    """
    hide_emitters: bool = True

Path dataclass

Bases: Integrator

Path integrator.

Attributes:

Name Type Description
max_depth int

Maximum path depth. (-1 for unlimited)

rr_depth int

Depth at which Russian roulette starts.

Note

This integrator should work well for most surface-based scenes. See Mitsuba doc for more details.

Source code in hakowan/setup/integrator.py
@dataclass(kw_only=True, slots=True)
class Path(Integrator):
    """Path integrator.

    Attributes:
        max_depth: Maximum path depth. (-1 for unlimited)
        rr_depth: Depth at which Russian roulette starts.

    Note:
        This integrator should work well for most surface-based scenes.
        See
        [Mitsuba
        doc](https://mitsuba.readthedocs.io/en/stable/src/generated/plugins_integrators.html#path-tracer-path)
        for more details.
    """
    max_depth: int = -1
    rr_depth: int = 5

VolPath dataclass

Bases: Integrator

Volumetric path integrator.

Attributes:

Name Type Description
max_depth int

Maximum path depth. (-1 for unlimited)

rr_depth int

Depth at which Russian roulette starts.

Note

This integrator should work well for most volume-based scenes. For example, if dielectric material is involved, VolPath integrator sometimes produces better results than Path integrator.

See Mitsuba doc for more details.

Source code in hakowan/setup/integrator.py
@dataclass(kw_only=True, slots=True)
class VolPath(Integrator):
    """Volumetric path integrator.

    Attributes:
        max_depth: Maximum path depth. (-1 for unlimited)
        rr_depth: Depth at which Russian roulette starts.

    Note:
        This integrator should work well for most volume-based scenes. For example, if dielectric
        material is involved, `VolPath` integrator sometimes produces better results than `Path`
        integrator.

        See
        [Mitsuba
        doc](https://mitsuba.readthedocs.io/en/stable/src/generated/plugins_integrators.html#volumetric-path-tracer-volpath)
        for more details.
    """
    max_depth: int = -1
    rr_depth: int = 5

VolPathMIS dataclass

Bases: Integrator

Volumetric path integrator with spectral MIS.

Attributes:

Name Type Description
max_depth int

Maximum path depth. (-1 for unlimited)

rr_depth int

Depth at which Russian roulette starts.

Note

See Mitsuba doc for more details.

Source code in hakowan/setup/integrator.py
@dataclass(kw_only=True, slots=True)
class VolPathMIS(Integrator):
    """Volumetric path integrator with spectral MIS.

    Attributes:
        max_depth: Maximum path depth. (-1 for unlimited)
        rr_depth: Depth at which Russian roulette starts.

    Note:
        See
        [Mitsuba
        doc](https://mitsuba.readthedocs.io/en/stable/src/generated/plugins_integrators.html#volumetric-path-tracer-with-spectral-mis-volpathmis)
        for more details.
    """
    max_depth: int = -1
    rr_depth: int = 5

Sampler

Independent dataclass

Bases: Sampler

Independent sampler.

Note

See Mitsuba doc for more details.

Source code in hakowan/setup/sampler.py
@dataclass(kw_only=True, slots=True)
class Independent(Sampler):
    """Independent sampler.

    Note:
        See
        [Mitsuba
        doc](https://mitsuba.readthedocs.io/en/stable/src/generated/plugins_samplers.html#independent-sampler-independent)
        for more details.
    """
    pass

Sampler dataclass

Sampler dataclass contains sampling-related settings.

Attributes:

Name Type Description
sample_count int

Number of samples per pixel.

seed int

Seed for random number generate.

Source code in hakowan/setup/sampler.py
@dataclass(kw_only=True, slots=True)
class Sampler:
    """Sampler dataclass contains sampling-related settings.

    Attributes:
        sample_count: Number of samples per pixel.
        seed: Seed for random number generate.
    """
    sample_count: int = 256  # Samples per pixel.
    seed: int = 0

Stratified dataclass

Bases: Sampler

Stratified sampler.

Attributes:

Name Type Description
jitter bool

Whether to jitter the samples.

Note

See Mitsuba doc for more details.

Source code in hakowan/setup/sampler.py
@dataclass(kw_only=True, slots=True)
class Stratified(Sampler):
    """Stratified sampler.

    Attributes:
        jitter: Whether to jitter the samples.

    Note:
        See [Mitsuba
        doc](https://mitsuba.readthedocs.io/en/stable/src/generated/plugins_samplers.html#stratified-sampler-stratified)
        for more details.
    """
    jitter: bool = True

Sensor

Orthographic dataclass

Bases: Sensor

Orthographic camera dataclass.

Source code in hakowan/setup/sensor.py
@dataclass(kw_only=True, slots=True)
class Orthographic(Sensor):
    """Orthographic camera dataclass."""

    pass

Perspective dataclass

Bases: Sensor

Perspective camera dataclass.

Attributes:

Name Type Description
fov float

Field of view in degrees.

fov_axis str

Axis to which fov is applied. Can be "x" or "y" or "diagonal" or "smaller" or "larger".

Source code in hakowan/setup/sensor.py
@dataclass(kw_only=True, slots=True)
class Perspective(Sensor):
    """Perspective camera dataclass.

    Attributes:
        fov: Field of view in degrees.
        fov_axis: Axis to which fov is applied. Can be "x" or "y" or "diagonal" or "smaller" or "larger".
    """

    fov: float = 28.8415  # degrees
    fov_axis: str = "smaller"

Sensor dataclass

Sensor dataclass contains camera-related settings.

Attributes:

Name Type Description
location list

Camera location in world space.

target list

Camera look-at location in world space.

up list

Camera up vector in world space.

near_clip float

Near clipping plane distance.

far_clip float

Far clipping plane distance.

Source code in hakowan/setup/sensor.py
@dataclass(kw_only=True, slots=True)
class Sensor:
    """Sensor dataclass contains camera-related settings.

    Attributes:
        location: Camera location in world space.
        target: Camera look-at location in world space.
        up: Camera up vector in world space.
        near_clip: Near clipping plane distance.
        far_clip: Far clipping plane distance.
    """

    location: list = field(default_factory=lambda: [0, 0, 5])
    target: list = field(default_factory=lambda: [0, 0, 0])
    up: list = field(default_factory=lambda: [0, 1, 0])
    near_clip: float = 1e-2
    far_clip: float = 1e4

ThinLens dataclass

Bases: Perspective

Thin lens camera dataclass.

Attributes:

Name Type Description
aperture_radius float

Radius of the aperture in world space.

focus_distance float

Distance to the focal plane in world space.

Source code in hakowan/setup/sensor.py
@dataclass(kw_only=True, slots=True)
class ThinLens(Perspective):
    """Thin lens camera dataclass.

    Attributes:
        aperture_radius: Radius of the aperture in world space.
        focus_distance: Distance to the focal plane in world space.
    """

    aperture_radius: float = 0.1
    focus_distance: float = 0.0