2. Materials and Textures¶

Materials define how objects appear when rendered. This guide will progressively teach you how to use materials in Vuer, from simple material types to advanced properties and texture mapping.

We’ll build upon the scene from the previous guide, adding materials step by step to create increasingly realistic renders.

Simple Materials¶

Vuer supports three simple material types that are easy to use and perform well: basic, lambert, and phong.

These materials are perfect for most visualization needs.

Simple materials in action: phong, lambert, and basic materials with the same geometry as the PBR example below

Understanding Simple Material Types¶

The materialType parameter determines how an object interacts with lights:

from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Cylinder, Sphere, Octahedron, Torus, Box, Plane

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        # Phong material - plastic-like glossy
        Cylinder(
            args=[0.8, 0.8, 0.5, 32],
            position=[-3.5, 0.25, -1],
            materialType="phong",
            material=dict(color="#4a3428"),
            key="phong-cylinder",
        ),

        # Lambert material - simple matte
        Sphere(
            args=[0.7, 32, 32],
            position=[-3.5, 1.1, -1],
            materialType="lambert",
            material=dict(color="#6b4e3d"),
            key="lambert-sphere",
        ),

        # Basic material - unlit, always bright
        Octahedron(
            args=[0.9, 0],
            position=[-1.8, 1.5, 0.3],
            rotation=[0, 0, 0.393],
            materialType="basic",
            key="basic-octahedron",
        ),

        # Phong with material dict for shininess
        Torus(
            args=[0.5, 0.15, 32, 64],
            position=[0, 0.4, 0.8],
            rotation=[1.571, 0, 0],
            materialType="phong",
            material=dict(
                color="#d5e8ff",
                shininess=100,       # Sharper specular highlights
            ),
            key="phong-torus",
        ),

        # Lambert material
        Box(
            args=[1.2, 1.2, 1.2],
            position=[0.4, 0.5, -2],
            materialType="lambert",
            material=dict(color="#a17c50"),
            key="lambert-box",
        ),

        # Phong material
        Sphere(
            args=[0.65, 32, 32],
            position=[1.8, 0.7, 0],
            materialType="phong",
            material=dict(color="#b8925f"),
            key="phong-sphere",
        ),

        # Floor
        Plane(
            args=[20, 20],
            position=[0, 0, 0],
            rotation=[-1.57, 0, 0],
            materialType="lambert",
            key="floor",
        ),

        # Backdrop
        Plane(
            args=[20, 20],
            position=[0, 0, -3],
            materialType="lambert",
            key="backdrop",
        ),

        up=[0, 1, 0],
        grid=False,
    )

    await session.forever()

Simple Material Types¶

  • "basic" - Unlit, always fully bright (not affected by lights). Good for UI elements or objects that need constant visibility.

  • "lambert" - Simple diffuse lighting with matte appearance. Efficient and great for most non-reflective objects.

  • "phong" - Diffuse + specular highlights for a glossy, plastic-like look. Supports shininess parameter via the material dict.

Usage Tip: All simple materials (basic, lambert, phong) must specify color inside the material dict (e.g., material=dict(color="#ff0000")).

Physically-Based Rendering (PBR) Materials¶

For photorealistic rendering, Vuer provides Physically-Based Rendering (PBR) materials: standard and physical. These materials require the material parameter with properties like roughness, metalness, and transmission:

PBR materials with fine-tuned properties: matte (high roughness), glass (transmission), and glossy (low roughness) finishes

Using the material Parameter¶

The material parameter accepts a dictionary of properties for fine-grained control.

Key Material Properties¶

For simple materials (basic, lambert, phong):

  • color: Must be inside material dict (e.g., material=dict(color="#ff0000"))

  • shininess (phong only): Controls specular highlight sharpness (0-150, default 30), must be inside material dict

For standard materials:

  • color: Must be inside material dict

  • roughness (0.0-1.0): Controls surface smoothness

    • 0.0 = perfect mirror

    • 1.0 = completely matte

  • metalness (0.0-1.0): Controls metallic appearance

    • 0.0 = dielectric (plastic, wood, stone)

    • 1.0 = metallic (gold, silver, copper)

For physical materials:

  • All standard properties, plus:

  • transmission (0.0-1.0): Light transmission (for glass effects)

  • thickness (number): Material thickness for transmission

  • ior (number): Index of refraction (1.0 = air, 1.5 = glass, 2.4 = diamond)

  • clearcoat (0.0-1.0): Clear coat layer (for car paint)

Complete Example with Material Properties¶

Source Code
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Cylinder, Sphere, Octahedron, Torus, Box, Plane

app = Vuer()

@app.spawn(start=True)
async def main(session: VuerSession):
    session.set @ Scene(
        # Matte cylinder
        Cylinder(
            args=[0.8, 0.8, 0.5, 32],
            position=[-3.5, 0.25, -1],
            materialType="standard",
            material=dict(
                color="#4a3428",
                roughness=0.96,
                metalness=0,
            ),
            key="matte-cylinder",
        ),

        # Matte sphere
        Sphere(
            args=[0.7, 32, 32],
            position=[-3.5, 1.1, -1],
            materialType="standard",
            material=dict(
                color="#6b4e3d",
                roughness=1,
                metalness=0,
            ),
            key="matte-sphere",
        ),

        # Glass octahedron
        Octahedron(
            args=[0.9, 0],
            position=[-1.8, 1.5, 0.3],
            rotation=[0, 0, 0.393],
            materialType="physical",
            material=dict(
                color="#ffffff",
                transmission=1,
                thickness=0.8,
                roughness=0,
                ior=1.5,
            ),
            key="glass-octahedron",
        ),

        # Glass torus
        Torus(
            args=[0.5, 0.15, 32, 64],
            position=[0, 0.4, 0.8],
            rotation=[1.571, 0, 0],
            materialType="physical",
            material=dict(
                color="#d5e8ff",
                transmission=0.93,
                thickness=0.5,
                roughness=0.08,
                ior=1.45,
            ),
            key="glass-torus",
        ),

        # Glossy box
        Box(
            args=[1.2, 1.2, 1.2],
            position=[0.4, 0.5, -2],
            materialType="standard",
            material=dict(
                color="#a17c50",
                roughness=0.32,
                metalness=0.75,
            ),
            key="glossy-box",
        ),

        # Glossy sphere
        Sphere(
            args=[0.65, 32, 32],
            position=[1.8, 0.7, 0],
            materialType="standard",
            material=dict(
                color="#b8925f",
                roughness=0.11,
                metalness=0.75,
            ),
            key="glossy-sphere",
        ),

        # Floor
        Plane(
            args=[20, 20],
            position=[0, 0, 0],
            rotation=[-1.57, 0, 0],
            materialType="lambert",
            key="floor",
        ),

        # Backdrop
        Plane(
            args=[20, 20],
            position=[0, 0, -3],
            materialType="lambert",
            key="backdrop",
        ),

        up=[0, 1, 0],
        grid=False,
    )

    await session.forever()

Texture Mapping¶

Finally, let’s add texture maps to the floor and backdrop to create a more realistic environment:

Enhancing realism: adding texture maps to floor and backdrop for environmental detail

Adding Textures¶

Textures are images that wrap around your 3D objects. The most common is the color map (also called diffuse map or albedo):

# Textured floor
Plane(
    args=[20, 20],
    position=[0, 0, 0],
    rotation=[-1.57, 0, 0],
    materialType="standard",
    material=dict(
        map="https://raw.githubusercontent.com/vuer-ai/vuer/main/docs/_static/03_floor.jpg",
        roughness=0.9,
    ),
    key="floor",
)

# Textured backdrop
Plane(
    args=[20, 20],
    position=[0, 0, -3],
    materialType="standard",
    material=dict(
        map="https://raw.githubusercontent.com/vuer-ai/vuer/main/docs/_static/03_backdrop.jpg",
        roughness=0.95,
    ),
    key="backdrop",
)

Serving Local Textures¶

For local texture files, configure the Vuer server to serve static assets:

from vuer import Vuer

# Serve files from the ./assets directory
app = Vuer(static_root="./assets")

# Now you can reference textures like:
# "http://localhost:8012/static/my_texture.jpg"

Advanced Textures¶

You can use multiple texture maps together for photorealistic materials:

Box(
    materialType="standard",
    material=dict(
        # Color/albedo map
        map="http://localhost:8012/static/wood_albedo.jpg",

        # Surface detail (bumps and dents)
        normalMap="http://localhost:8012/static/wood_normal.jpg",
        normalScale=[1.0, 1.0],

        # Roughness variation
        roughnessMap="http://localhost:8012/static/wood_roughness.jpg",
        roughness=1.0,

        # Ambient occlusion (crevice darkening)
        aoMap="http://localhost:8012/static/wood_ao.jpg",
        aoMapIntensity=1.0,
    ),
    key="wood-box",
)

Texture Properties¶

  • map: Base color texture (diffuse/albedo)

  • normalMap: Surface detail (RGB = surface normal XYZ)

  • roughnessMap: Grayscale roughness variation

  • metalnessMap: Grayscale metalness variation

  • aoMap: Ambient occlusion (darkens crevices)

  • emissiveMap: Self-illumination pattern

  • mapRepeat: Tile texture [u, v] times

Performance Tips¶

  1. Choose appropriate material complexity:

    • Use simple materials (basic, lambert, phong) for most objects - they’re faster and easier to use

    • Use standard for main objects that need photorealistic rendering

    • Use physical sparingly, only for special effects (glass, transmission)

  2. Optimize textures:

    • Use power-of-two dimensions (512, 1024, 2048)

    • Compress images (JPEG for color, PNG for transparency)

    • Don’t use textures larger than needed

  3. Reuse materials:

    • Objects with identical materials are batched together

    • Define common materials once and reuse

Next Steps¶

Now that you understand materials and textures:

  • Learn about Camera Control to view your scenes from different angles

  • Add Lights to see how they interact with different material types

  • Explore advanced rendering with Render Modes