Materials and Textures

Materials define the visual appearance of meshes, controlling properties like color, reflectivity, and texture. Babylon.js offers a comprehensive material system that supports everything from simple colored surfaces to physically-based rendering.

The StandardMaterial is a versatile, performance-focused material for basic rendering needs:

// Create a standard material
const material = new BABYLON.StandardMaterial("material", scene);

// Basic color properties
material.diffuseColor = new BABYLON.Color3(1, 0, 0);    // Red diffuse (main color)
material.specularColor = new BABYLON.Color3(1, 1, 1);   // White specular (highlights)
material.emissiveColor = new BABYLON.Color3(0, 0, 0.2); // Slight blue emission
material.ambientColor = new BABYLON.Color3(0.1, 0.1, 0.1); // Ambient lighting contribution

// Shininess and specularity
material.specularPower = 32; // Sharpness of specular highlights (higher = sharper)

// Transparency
material.alpha = 0.8; // 80% opaque

// Apply material to a mesh
sphere.material = material;

Physically Based Rendering (PBR) materials create realistic surfaces following physical principles of light interaction:

// Create a PBR material
const pbr = new BABYLON.PBRMaterial("pbr", scene);

// Base properties
pbr.albedoColor = new BABYLON.Color3(0.5, 0.5, 0.5); // Base color (like diffuse)
pbr.metallic = 0.7;  // 0 = dielectric (plastic), 1 = metal
pbr.roughness = 0.2; // 0 = smooth, 1 = rough

// Optional properties
pbr.subSurface.isTranslucencyEnabled = true;  // Enable subsurface scattering
pbr.subSurface.translucencyIntensity = 0.8;   // Intensity of scattering

// Apply material
sphere.material = pbr;

Here are examples of creating realistic materials with PBR:

// Create a material that looks like gold
const gold = new BABYLON.PBRMaterial("gold", scene);
gold.albedoColor = new BABYLON.Color3(1.0, 0.766, 0.336);
gold.metallic = 1.0;  // Fully metallic
gold.roughness = 0.1; // Fairly smooth
gold.environmentIntensity = 0.8; // Strength of reflections

// Create a glass material
const glass = new BABYLON.PBRMaterial("glass", scene);
glass.albedoColor = new BABYLON.Color3(0.85, 0.85, 0.9);
glass.alpha = 0.2; // Mostly transparent
glass.metallic = 0.0; // Not metallic
glass.roughness = 0.0; // Very smooth
glass.environmentIntensity = 0.9; // Strong reflections
glass.indexOfRefraction = 1.5; // Like real glass
glass.subSurface.isRefractionEnabled = true; // Enable refraction

Textures add detailed surface information to materials:

// Load a basic texture
const diffuseTexture = new BABYLON.Texture("textures/wood.jpg", scene);
material.diffuseTexture = diffuseTexture;

// Configure texture properties
diffuseTexture.uScale = 2; // Repeat texture horizontally 2 times
diffuseTexture.vScale = 2; // Repeat texture vertically 2 times
diffuseTexture.wrapU = BABYLON.Texture.MIRROR_ADDRESSMODE; // Mirror wrapping horizontally
diffuseTexture.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;  // Clamp edges vertically

Add additional texture maps for detailed surface information:

// Add additional texture maps
material.bumpTexture = new BABYLON.Texture("textures/woodNormal.png", scene); // Normal map
material.ambientTexture = new BABYLON.Texture("textures/woodAO.jpg", scene);  // Ambient occlusion
material.specularTexture = new BABYLON.Texture("textures/woodSpecular.jpg", scene); // Specular map

// Adjust normal map intensity
material.bumpTexture.level = 1.5; // Intensity of normal mapping

Using textures with PBR materials for realistic rendering:

// Using textures with PBR materials
pbr.albedoTexture = new BABYLON.Texture("textures/metal/albedo.png", scene);
pbr.metallicTexture = new BABYLON.Texture("textures/metal/metallic.png", scene);
pbr.roughnessTexture = new BABYLON.Texture("textures/metal/roughness.png", scene);
pbr.normalTexture = new BABYLON.Texture("textures/metal/normal.png", scene);
pbr.ambientOcclusionTexture = new BABYLON.Texture("textures/metal/ao.png", scene);

// Using a single channel from a texture
pbr.useRoughnessFromMetallicTextureAlpha = false;
pbr.useRoughnessFromMetallicTextureGreen = true; // Use green channel for roughness
pbr.useMetallicFromMetallicTextureBlue = true;   // Use blue channel for metallic

Add environment reflections to materials:

// Environment mapping for reflections
const envTexture = new BABYLON.CubeTexture("textures/environment/skybox", scene);
pbr.environmentTexture = envTexture;

Generate textures programmatically:

// Create a wood procedural texture
const woodTexture = new BABYLON.WoodProceduralTexture("woodTex", 512, scene);
woodTexture.ampScale = 100.0;
woodTexture.woodColor = new BABYLON.Color3(0.49, 0.25, 0.08);
material.diffuseTexture = woodTexture;

Create custom procedural textures with shaders:

// Create a custom procedural texture with a fragment shader
const customProceduralTexture = new BABYLON.ProceduralTexture(
    "customTex", 
    512, // Size
    "customShader", // Shader name
    scene,
    null,
    true, // Generate mipmaps
    true  // Is fragment only
);

// Set shader parameters
customProceduralTexture.setFloat("time", 0);
customProceduralTexture.setVector2("resolution", new BABYLON.Vector2(512, 512));

// Update time in the render loop
scene.onBeforeRenderObservable.add(() => {
    customProceduralTexture.setFloat("time", performance.now() / 1000);
});

Efficiently manage multiple materials:

// Clone a material
const material2 = material.clone("material2");
material2.diffuseColor = new BABYLON.Color3(0, 1, 0); // Change color to green

// Create material instances (shares resources but allows property overrides)
const materialInstance = material.instantiateForInstance();
materialInstance.diffuseColor = new BABYLON.Color3(0, 0, 1); // Blue variant

Create special visual effects with materials:

// Fresnel effect (edge glow)
material.diffuseFresnelParameters = new BABYLON.FresnelParameters();
material.diffuseFresnelParameters.leftColor = BABYLON.Color3.White();
material.diffuseFresnelParameters.rightColor = BABYLON.Color3.Blue();
material.diffuseFresnelParameters.power = 2;
material.diffuseFresnelParameters.bias = 0.1;

// Emissive Fresnel (good for energy shields or holograms)
material.emissiveFresnelParameters = new BABYLON.FresnelParameters();
material.emissiveFresnelParameters.leftColor = BABYLON.Color3.Black();
material.emissiveFresnelParameters.rightColor = BABYLON.Color3.Green();
material.emissiveFresnelParameters.power = 4;
material.emissiveFresnelParameters.bias = 0.5;
// Back face culling (don't render backside of mesh)
material.backFaceCulling = true;

// Two-sided material
material.backFaceCulling = false;
material.twoSidedLighting = true;

// Disable lighting calculation (useful for UI elements)
material.disableLighting = true;

Babylon.js 7 includes pre-built materials for common effects:

// Import the materials library
// In HTML: <script src="https://cdn.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
// Or in modules: import { GradientMaterial } from 'babylonjs-materials';

// Gradient material
const gradientMaterial = new BABYLON.GradientMaterial("gradient", scene);
gradientMaterial.topColor = BABYLON.Color3.Blue();
gradientMaterial.bottomColor = BABYLON.Color3.White();
gradientMaterial.offset = 0.5;
// Fire material
const fireMaterial = new BABYLON.FireMaterial("fire", scene);
fireMaterial.diffuseTexture = new BABYLON.Texture("textures/fire.png", scene);
fireMaterial.distortionTexture = new BABYLON.Texture("textures/distortion.png", scene);
fireMaterial.speed = 5.0;
// Cell (toon) shading material
const cellMaterial = new BABYLON.CellMaterial("cell", scene);
cellMaterial.diffuseColor = new BABYLON.Color3(0.8, 0.4, 0.4);
cellMaterial.computeHighLevel = true;
cellMaterial.diffuseTexture = new BABYLON.Texture("textures/amiga.jpg", scene);

Babylon.js 7 includes an enhanced Node Material Editor for visual material creation:

// Load a material created in the Node Material Editor
BABYLON.NodeMaterial.ParseFromFileAsync("", "materials/custom.json", scene).then(nodeMaterial => {
    sphere.material = nodeMaterial;
    
    // Access and animate material properties
    const timeBlock = nodeMaterial.getBlockByName("Time");
    scene.onBeforeRenderObservable.add(() => {
        timeBlock.value = performance.now() / 1000;
    });
});

These material capabilities in Babylon.js 7 provide extensive control over visual appearance, from basic colored surfaces to complex physically-based materials with realistic light interaction.