问题
I'm trying to set per-face UV indices in a BufferGeometry.
I'm starting with a Geometry. Each face of my geometry has a face.materialIndex
corresponding to a UV index. I'm trying to convert this to a BufferGeometry, and then map over the face.materialIndex
to the BufferGeometry
.
Here's what I have so far:
// Convert geometry > buffergeometry
const bufGeo = new BufferGeometry().fromGeometry( geometry );
// Get an array of all the original geometry's indices...
const faceIndices = geometry.faces.map( face => face.materialIndex );
// Build a new array with the indices...
const indices = new Uint16Array( faceIndices );
// Apply to the BufferGeometry
bufGeo.setIndex( new BufferAttribute( indices, 1 ) );
Right now this appears to clobber my mesh and make it not draw at all. What am I doing wrong?
By the way, under the hood, when a Geometry is converted to a BufferGeometry, Three.js puts it in an intermediary format first called a DirectGeometry
. This used to copy over indices, but it was removed for reasons unknown in this commit by Mr Doob. Right now Three appears to discard indices entirely in a Geo > BufGeo conversion.
I have also tried using the code from that commit (modified to use setIndex):
const indices = new Uint16Array( faceIndices.length * 3 );
bufGeo.addAttribute( 'index', new BufferAttribute( indices, 1 ).copyIndicesArray( faceIndices ) );
But I have the same problem. The resulting mesh is clobbered.
回答1:
The setIndex
function is used to specify triangle indices that reference the vertex attribute buffers on the BufferGeometry. In your example you're setting the the triangle index array to an array generated from the materialIndex
of each face.
The materialIndex corresponds to a material to render that triangle with from an array of materials, not a UV index. From the Face3 documentation:
materialIndex — (optional) which index of an array of materials to associate with the face.
It's very possible that that materialIndex
is zero for every face unless you've done something to change it, which would explain why your model stops drawing (the vertices on the faces are all the same one).
This line is your problem:
// Get an array of all the original geometry's indices...
const faceIndices = geometry.faces.map( face => face.materialIndex );
It might also be important to note that you'll be getting 1/3 as many array elements as you need for an attribute by generating an array this way, because there are 3 vertices per face.
Possible Solutions
If you're looking to render each face with a different material, as the
materialIndex
corresponds to, then I would look into groups for BufferGeometryIf you want to actually generate custom UV coordinates for a BufferGeometry, I would look into BufferAttributes and the BufferGeometry.addAttribute function to add the new UV attribute.
Hope that helps!
来源:https://stackoverflow.com/questions/45123977/three-js-correct-way-to-setindex-indices-for-buffergeometry