Skip to content

PBR Material ​

PBRMaterial is a Physically Based Rendering material built on energy conservation and microfacet theory, realistically expressing physical surface properties such as Metallic and Roughness.

It is automatically created as the default material when loading external .gltf / .glb models via GLTFLoader, and can also be instantiated directly and applied to primitive meshes.

1. Implementing Physical Surfaces with Texture Maps ​

PBRMaterial follows the standard glTF 2.0 Metallic-Roughness workflow and combines the following core texture maps to achieve photorealistic surfaces.

Texture MapRoleEffect
baseColorTextureAlbedo MapDefines the intrinsic surface color and pattern without lighting information
metallicRoughnessTextureMetallic-Roughness MapDefines surface roughness in the G channel and metallicness in the B channel
normalTextureNormal MapExpresses fine surface bumps and depth without subdividing geometry
occlusionTextureAmbient Occlusion (AO) MapAdds subtle contact shadows in crevices where ambient light is blocked (R channel)
emissiveTextureEmissive MapSpecifies areas that emit light independently of scene lighting

2. Key Property Control ​

Even without textures, you can express a wide range of surfaces—from non-metallic plastic to smooth pure metal—by adjusting the core factor values.

javascript
const material = new RedGPU.Material.PBRMaterial(redGPUContext);

// 1. Base color (RGBA: 0.0 ~ 1.0)
material.baseColorFactor = [1.0, 0.85, 0.35, 1.0];

// 2. Metallic and roughness control (0.0 ~ 1.0)
material.metallicFactor = 1.0;  // 0.0: Dielectric (plastic, wood) ~ 1.0: Pure metal
material.roughnessFactor = 0.2; // 0.0: Smooth mirror surface ~ 1.0: Rough matte surface

[Recommended: Use with IBL Environment Lighting]

Highly metallic and smooth surfaces reveal their material quality by reflecting their surroundings. For realistic reflections with PBRMaterial, we recommend using it together with IBL (Image-Based Lighting).

3. Practical Example: Surface Variation by Roughness ​

Let's place five identical golden metallic spheres (metallicFactor = 1.0) and vary roughnessFactor from 0.0 to 1.0 to observe how surface reflections change.

javascript
import * as RedGPU from "https://redcamel.github.io/RedGPU/dist/index.js";

RedGPU.init(canvas, (redGPUContext) => {
    const scene = new RedGPU.Display.Scene();

    // 1. Configure lighting and IBL environment map
    const light = new RedGPU.Light.DirectionalLight();
    scene.lightManager.addDirectionalLight(light);

    const ibl = new RedGPU.Resource.IBL(
        redGPUContext,
        'https://redcamel.github.io/RedGPU/examples/assets/hdr/2k/the_sky_is_on_fire_2k.hdr'
    );

    // 2. Place 5 PBR spheres with different roughness values
    const sphereGeometry = new RedGPU.Primitive.Sphere(redGPUContext, 1.2, 64, 64);

    for (let i = 0; i < 5; i++) {
        const material = new RedGPU.Material.PBRMaterial(redGPUContext);
        material.baseColorFactor = [1.0, 0.82, 0.35, 1.0];
        material.metallicFactor = 1.0;
        material.roughnessFactor = i / 4; // 0.0 (mirror) ~ 1.0 (matte)

        const mesh = new RedGPU.Display.Mesh(redGPUContext, sphereGeometry, material);
        mesh.x = (i - 2) * 3;
        scene.addChild(mesh);
    }

    const controller = new RedGPU.Camera.OrbitController(redGPUContext);
    controller.distance = 12;

    const view = new RedGPU.Display.View3D(redGPUContext, scene, controller);
    view.ibl = ibl;
    view.skybox = new RedGPU.Display.SkyBox(redGPUContext, ibl.environmentTexture);
    redGPUContext.addView(view);

    new RedGPU.Renderer().start(redGPUContext);
});

Live Demo ​

Observe how highlights and environment reflections change from left (roughnessFactor: 0.0, sharp mirror reflection) to right (roughnessFactor: 1.0, diffuse matte reflection).


Next Steps ​

Learn how to implement shadows cast when light is blocked and add a realistic sense of space to the scene.