BabylonJS - Dynamic Texture
Babylon.js - Dynamic Texture
Section titled “Babylon.js - Dynamic Texture”DynamicTexture is a special type of texture in Babylon.js that allows you to draw on it using the standard HTML5 2D Canvas API. This is incredibly useful for generating textures on the fly, such as displaying text, drawing shapes, rendering UI elements, or creating procedural patterns directly onto a material.
Think of it as having a hidden 2D canvas associated with your texture. You can get the drawing context of this canvas, use familiar methods like fillText, strokeRect, beginPath, bezierCurveTo, drawImage, etc., and then update the texture to reflect your drawings on the 3D mesh.
Creating a Dynamic Texture
Section titled “Creating a Dynamic Texture”You create a DynamicTexture by providing a name, options defining its size (width and height), the scene, and optionally whether mipmaps should be generated.
import * as BABYLON from '@babylonjs/core';
// Assuming 'scene' is definedconst textureWidth = 512;const textureHeight = 256;const generateMipMaps = true;
const myDynamicTexture = new BABYLON.DynamicTexture( "dynamicTex", { width: textureWidth, height: textureHeight }, // Can also pass just size: 512 scene, generateMipMaps);Drawing Text
Section titled “Drawing Text”DynamicTexture provides a convenient drawText method for quickly rendering text onto the texture.
const text = "Hello Babylon!";const x = 50; // X position on the texture canvasconst y = 100; // Y position on the texture canvasconst font = "bold 44px Arial"; // CSS font stringconst color = "white"; // Text colorconst canvasColor = "blue"; // Background color for the text area (can be 'transparent')const invertY = true; // If true, Y is distance from top; if false, from bottomconst update = true; // If true, update the texture immediately
myDynamicTexture.drawText(text, x, y, font, color, canvasColor, invertY, update);Using the Canvas Context
Section titled “Using the Canvas Context”For more complex drawing, you can get the 2D rendering context of the texture’s underlying canvas using getContext(). This gives you access to the full HTML5 Canvas API.
// Get the 2D contextconst ctx = myDynamicTexture.getContext();
// Now use standard canvas methodsctx.fillStyle = "green";ctx.fillRect(10, 10, 100, 50);
ctx.strokeStyle = "yellow";ctx.lineWidth = 4;ctx.strokeRect(120, 10, 80, 80);
ctx.beginPath();ctx.moveTo(250, 30);ctx.lineTo(350, 130);ctx.lineTo(250, 130);ctx.closePath();ctx.fillStyle = "rgba(255, 0, 0, 0.7)"; // Red with transparencyctx.fill();ctx.stroke();
// IMPORTANT: After drawing with the context, you MUST call update()// for the changes to appear on the 3D model.myDynamicTexture.update();Applying the Texture
Section titled “Applying the Texture”Once created and drawn upon, you apply the DynamicTexture to a material just like any other texture (e.g., as a diffuseTexture).
// Assuming 'mesh' is definedconst material = new BABYLON.StandardMaterial("dynamicMat", scene);material.diffuseTexture = myDynamicTexture;mesh.material = material;Demo: Text on a Box
Section titled “Demo: Text on a Box”<!DOCTYPE html><html><head> <meta charset="utf-8"/> <title>Babylon.js - Dynamic Texture Text</title> <script src="https://cdn.babylonjs.com/babylon.js"></script> <style> html, body { overflow: hidden; width: 100%; height: 100%; margin: 0; padding: 0; } #renderCanvas { width: 100%; height: 100%; touch-action: none; } </style></head><body> <canvas id="renderCanvas"></canvas> <script type="text/javascript"> const canvas = document.getElementById("renderCanvas"); const engine = new BABYLON.Engine(canvas, true);
const createScene = function () { const scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color4(0.3, 0.3, 0.3, 1.0);
const camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 2, Math.PI / 2.5, 10, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas, true);
const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene); light.intensity = 0.9;
const box = BABYLON.MeshBuilder.CreateBox("box", { size: 3 }, scene);
// Create Dynamic Texture const dynamicTexture = new BABYLON.DynamicTexture("dynamic texture", { width: 512, height: 256 }, scene, true);
// Apply texture to material const material = new BABYLON.StandardMaterial("Mat", scene); material.diffuseTexture = dynamicTexture; box.material = material;
// Draw text onto the texture const font = "bold 70px Arial"; dynamicTexture.drawText("Box Text", 80, 135, font, "green", "white", true, true); // Draw text requires an update, but the last param 'true' handles it here. // If drawing with context, call dynamicTexture.update() afterwards.
return scene; };
const scene = createScene(); engine.runRenderLoop(function () { scene.render(); }); window.addEventListener("resize", function () { engine.resize(); }); </script></body></html>Output Description (Text Demo)
Section titled “Output Description (Text Demo)”This demo shows a simple cube rotating in the center. The cube’s surface is textured with a dynamically generated image: a white background with the text “Box Text” drawn in bold green Arial font.
Demo: Canvas Drawing on Ground
Section titled “Demo: Canvas Drawing on Ground”<!DOCTYPE html><html><head> <meta charset="utf-8"/> <title>Babylon.js - Dynamic Texture Canvas Drawing</title> <script src="https://cdn.babylonjs.com/babylon.js"></script> <style> html, body { overflow: hidden; width: 100%; height: 100%; margin: 0; padding: 0; } #renderCanvas { width: 100%; height: 100%; touch-action: none; } </style></head><body> <canvas id="renderCanvas"></canvas> <script type="text/javascript"> const canvas = document.getElementById("renderCanvas"); const engine = new BABYLON.Engine(canvas, true);
const createScene = function () { const scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color4(0.1, 0.2, 0.3, 1.0);
const camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 4, 25, BABYLON.Vector3.Zero(), scene); camera.attachControl(canvas, true);
const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene); light.intensity = 0.8;
const ground = BABYLON.MeshBuilder.CreateGround("ground", { width: 15, height: 15 }, scene);
// Create Dynamic Texture (square) const dynamicTexture = new BABYLON.DynamicTexture("dynamic texture", 512, scene, true);
// Apply texture to ground material const material = new BABYLON.StandardMaterial("Mat", scene); material.diffuseTexture = dynamicTexture; ground.material = material;
// Get context and draw using Canvas API const ctx = dynamicTexture.getContext();
// Clear background (optional) ctx.fillStyle = "#4488AA"; // Bluish background ctx.fillRect(0, 0, 512, 512);
// Draw a bezier curve (e.g., a heart shape) ctx.beginPath(); ctx.moveTo(256, 150); // Start point slightly offset from center top ctx.bezierCurveTo(256, 130, 230, 100, 190, 100); // Left top curve ctx.bezierCurveTo(120, 100, 120, 180, 120, 180); // Left side curve ctx.bezierCurveTo(120, 250, 190, 310, 256, 350); // Bottom point curve ctx.bezierCurveTo(322, 310, 392, 250, 392, 180); // Right side curve ctx.bezierCurveTo(392, 180, 392, 100, 332, 100); // Right top curve ctx.bezierCurveTo(290, 100, 256, 130, 256, 150); // Connect back near start ctx.closePath();
ctx.fillStyle = "red"; ctx.fill(); ctx.strokeStyle = "darkred"; ctx.lineWidth = 5; ctx.stroke();
// Update the texture to show the drawing dynamicTexture.update();
return scene; };
const scene = createScene(); engine.runRenderLoop(function () { scene.render(); }); window.addEventListener("resize", function () { engine.resize(); }); </script></body></html>Output Description (Canvas Drawing Demo)
Section titled “Output Description (Canvas Drawing Demo)”This example displays a ground plane. The texture applied to the ground is generated dynamically. It shows a bluish background with a large red heart shape (drawn using bezier curves via the canvas context) in the center.
Performance Considerations
Section titled “Performance Considerations”Updating a DynamicTexture, especially a large one, frequently (e.g., every frame) can impact performance as it involves CPU-side drawing and GPU texture uploads. Use it judiciously for elements that don’t change constantly or optimize the update frequency. For highly dynamic text or UI, consider using the Babylon.js GUI system, which is often more performant.