1

I am currently playing with ThreeJS decals. I have been able to put a beautiful stain on my sphere.

Here is the piece of code I use to "apply" the decal on my sphere. (I have some custom classes, but don't worry about this.

// Create sphere
var mainMesh = new THREE.Mesh(
    new THREE.SphereGeometry(7, 16, 16),
    new THREE.MeshBasicMaterial({ color: 0x00a1fd })
);

// Declare decal material
var decalMaterial = new THREE.MeshPhongMaterial({
    color               : 0xff0000,    
    specular            : 0x444444,
    map                 : TextureLoader.instance.getTexture('http://threejs.org/examples/textures/decal/decal-diffuse.png'),
    normalMap           : TextureLoader.instance.getTexture('http://threejs.org/examples/textures/decal/decal-normal.jpg'),
    normalScale         : new THREE.Vector2( 1, 1 ),
    shininess           : 30,
    transparent         : true,
    depthTest           : true,
    depthWrite          : false,
    polygonOffset       : true,
    polygonOffsetFactor : -4,
    wireframe           : false
});

// Create decal itself
var decal = new THREE.Mesh(
    new THREE.DecalGeometry(
        mainMesh,
        new THREE.Vector3(0, 2.5, 3),
        new THREE.Vector3(0, 0, 0),
        new THREE.Vector3(8, 8, 8),
        new THREE.Vector3(1, 1, 1)
    ),
    decalMaterial.clone()
);

// Add mesh + decal + helpers
scene.add(
    mainMesh,
    new THREE.HemisphereLight(0xffffff, 0, 1),
    decal,
    new THREE.WireframeHelper(decal, 0xffff00)
);

decal.add(new THREE.BoxHelper(decal, 0xffff00));

Now, I woud like to move this stain on my sphere, and thus, update the geometry of my decal.

Unfortunately, when I call decal.geometry.computeDecal(), the mesh of the decal does not update. I can't find any solution about this.

    function moveDecal()
    {
        decal.translateX(1);
        decal.geometry.computeDecal();
    };

According to the DecalGeometry class, the function computeDecal already set to true various members required to update vertices, colors, UVs, ....

    this.computeDecal = function() {
        // [...]
        this.verticesNeedUpdate     = true;
        this.elementsNeedUpdate     = true;
        this.morphTargetsNeedUpdate = true;
        this.uvsNeedUpdate          = true;
        this.normalsNeedUpdate      = true;
        this.colorsNeedUpdate       = true;
     };

Thank you for your help ! :D

PS : ThreeJS r80

Hellium
  • 7,206
  • 2
  • 19
  • 49

1 Answers1

1

You are trying to update vertices of your geometry.

You can change the value of a vertex componnent,

geometry.vertices[ 0 ].x += 1;

but you can't add new veritices

geometry.vertices.push( new THREE.Vector3( x, y, z ) ); // not allowed

or assign a new vertex array

geometry.vertices = new_array; // not allowed

after the geometry has been rendered at least once.

Similalry, for other attributes, such as UVs.

For more info, see this answer: verticesNeedUpdate in Three.js.

three.js r.80

Community
  • 1
  • 1
WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • 1
    Mmmh, so you mean I have no choice but to replace my decal with a new one each time I want to move it ? – Hellium Sep 22 '16 at 07:22
  • @WestLangley what does "you can't" mean in this context? Do you mean Three.js just won't update those values internally? If so, do you know why the library doesn't throw a warning or error when users try to update an immutable property? – duhaime Nov 24 '17 at 19:20