⚠️ Beta State

PyBevy is in an early and experimental stage. The API is incomplete, subject to breaking changes without notice, and you should expect bugs. Many features are still under development.

Lighting and PBR Materials

Understand different light types and Physically Based Rendering (PBR).

Introduction

Physically Based Rendering (PBR) is a rendering model that aims to simulate how light interacts with materials in a physically plausible way. pybevy's StandardMaterial is a PBR material.

This example demonstrates two key PBR properties:

  • Metallic: How much a material behaves like a metal. 0.0 is a dielectric (like plastic), 1.0 is a metal.
  • Perceptual Roughness: How rough or smooth a surface is. 0.0 is perfectly smooth (like a mirror), 1.0 is very rough (like chalk).
from pybevy.prelude import *

The Setup

We will create a grid of spheres. Each sphere will have a different combination of metallic and perceptual_roughness values, allowing us to see how they interact. We also add a DirectionalLight to simulate a sun, which is essential for PBR to look correct.

def setup(
    commands: Commands,
    meshes: ResMut[Assets[Mesh]],
    materials: ResMut[Assets[StandardMaterial]],
):
    # Create a sphere mesh that we can reuse for all entities
    sphere_mesh = meshes.add(Sphere(0.45))
 
    # Create a grid of spheres
    for y in range(-2, 3):
        for x in range(-5, 6):
            x01 = (x + 5) / 10.0
            y01 = (y + 2) / 4.0
            commands.spawn(
                Mesh3d(sphere_mesh),
                MeshMaterial3d(materials.add(StandardMaterial(
                    base_color=Color.srgb(0.9, 0.5, 0.3),
                    metallic=y01,
                    perceptual_roughness=x01,
                ))),
                Transform.from_xyz(x, y + 0.5, 0.0),
            )
 
    # Add a light and camera
    commands.spawn(DirectionalLight(illuminance=1500.0))
    commands.spawn(
        Camera3d(),
        Transform.from_xyz(0.0, 0.0, 8.0).looking_at(Vec3.ZERO, Vec3.Y),
    )

Running the App

When you run this, you'll see a grid of spheres. The spheres on the left are smooth, and they get rougher as you move to the right. The spheres at the bottom are dielectric, and they become more metallic as you move up.

@entrypoint
def main(app: App) -> App:
    return app.add_plugins(DefaultPlugins).add_systems(Startup, setup)
 
if __name__ == "__main__":
    main().run()