Instance of license plate / tiling a texture for a glsl shader

Now I have a car model, I know instance car is very simple now, but the problem is that the number combination of each car is different, which makes me very distressed. I tried to draw the number combination elf to the designated location, but ultimately failed. I don’t know if I can use shader to dynamically combine 0-9 maps into my car. Maybe there are other good plans? Please help me. Thank you very much.

I’m sorry I didn’t describe it clearly.
As the picture shows, each box represents a car. The problem is how I dynamically change the number combination through the GPU instance.

function createGlpyhSheet() {
		var lettersPerSide = 16;
    var fontSize = 64;
    var canvas = document.createElement('canvas');
    canvas.width = canvas.height = fontSize * lettersPerSide;
    var ctx = canvas.getContext('2d');
    ctx.fillStyle = '#ffffff';
    ctx.font = fontSize + 'px Monospace';

    var str = "0123456789";
    for (var i = 0; i < str.length; i++) {
        ctx.fillText(str[i], i * fontSize, -(8 / 32) * fontSize + fontSize);

    var tex = new THREE.Texture(canvas);
    tex.flipY = true;
    tex.needsUpdate = true;

    return tex;

var geometry = new THREE.InstancedBufferGeometry().copy(new THREE.BoxBufferGeometry(1, 1, 1));
            var offsets = [];
            var orientations = [];
            var numbers = [];
            for (var i = 0; i < 10; i++) {
                offsets.push(0, 0, i * 2);
                orientations.push(0, 0, 0, 1);
                var num="";
                for(var k=0;k<4;k++){
                numbers.push(num);//I want to pass the combination of numbers into GPU here. What should I do?
            var offsetAttribute = new THREE.InstancedBufferAttribute(new Float32Array(offsets), 3);
            var orientationAttribute = new THREE.InstancedBufferAttribute(new Float32Array(orientations), 4);
            var numberAttribute = new THREE.InstancedBufferAttribute(new Float32Array(numbers), 1);
            geometry.addAttribute('offset', offsetAttribute);
            geometry.addAttribute('orientation', orientationAttribute);
            geometry.addAttribute('numbers', numberAttribute);
            var material = new THREE.RawShaderMaterial({
                uniforms: {
                    map: { value: createGlpyhSheet()  }//Here is a combination map of 0-9 digits.
                vertexShader: document.getElementById('vertexShader').textContent,
                fragmentShader: document.getElementById('fragmentShader').textContent
            material.transparent = true;
            var mesh = new THREE.Mesh(geometry, material);

Sorry, I tried to add tests to jsfiddle, but the code didn’t work correctly.

Use an additional instanced attribute with length of item of 5 (as I can see it at your examples). Then use the data from the fields of this attribute for shift of texture coordinates.

My initial idea is to pass it to shader for UV migration, but I’m still learning glsl programming. I wonder if you can provide a small example. Thank you again for your reply.

I’ve just thought about it a bit properly. There’s no vec5 type in shaders. So the solution will be slightly different. I’m working on it (I hope I’ll make it tonight :slight_smile: )

Pheww… :sweat_smile: Seems it’s working. There are 5 instanced planes (of THREE.PlaneBufferGeometry()) with 5 additional instanced attributes, that contains data for 5-digit numbers. The plane in the center has changing digits.

This is just an example, not the ultimate solution. So I’m really curious if this approach is correct, and waiting for criticism from the community about how to do it in better, correct and efficient way :slight_smile:

1 Like

Beautiful. It looks like a good idea. Thank you.