1

i have an output date like this:

geom[0] = {

texturesindexT: new Int16Array([0,1,2,3]),
texturesindexS: new Int16Array([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,...]),

materialsindexT: new Int16Array([-1,-1,-1,-1]),
materialsindexS: new Int16Array([-1,0,1,2,3,4,5,0,6,2,7,8,-1,0,...]),

startIndicesT: new Uint32Array([0,288,606,897,1380]),
startIndicesS: new Uint32Array([1380,1431,1479,1485,1497,1515,1659,...]),

m_indices: new Uint16Array([0,1,2,3,0,2,4,2,5,4,6,2,7,3,2,8,9,10,...]),

m_vertices: new Float32Array([-81.93996,25.7185,-85.53822,-81.93996,...]),

m_normals: new Float32Array([-0.004215205,0.9999894,-0.001817489,-0.004215205,...]),

m_texCoords: new Float32Array([0,0.04391319,0,0.2671326,0.009521127,0.03514284,...]),

}

var textures = new Array("-1_-1/t0.jpg","-1_-1/t1.jpg","-1_-1/t2.jpg",...);

The Data is in order for an Index, Vertex and Normal-Buffer but sections have to be rendered with other Textures and Maretials.

I have tried to make a THREE.Geometry out of the indices, vertices and texCoords/UVCoords but that didn't work.

Now i am trying use a THREE.BufferGeometry() and this work BUT i need to render index 0 to 287 with Texture "textures[0]" and index 288 to 605 with "textures[1]" and so on.

My first attempt was to make a BufferGeometry for each part with index 288 to 605 , but since the Indices are in order for the hole model, i have to put the complete vertices, normales and UVCoords in the Buffer for just a couple of faces.

Is there a way to render sections of the BufferGeometry with other Textures or to set the Texture Index for each Face?

Or is it possible to create a Material, that renders the first X faces with Texture A and the next with Texture B???

Wilt
  • 41,477
  • 12
  • 152
  • 203
user2304379
  • 59
  • 1
  • 8

2 Answers2

1

If you want to use two different textures with a single BufferGeometry, you can use this pattern, which sets drawcalls:

var geometry1 = new THREE.BufferGeometry();
// ...and set the data...
var geometry2 = geometry1.clone();

// set drawcalls
geometry1.offsets = geometry1.drawcalls = []; // currently required
geometry1.addDrawCall( start1, count1, 0 );

geometry2.offsets = geometry2.drawcalls = []; // currently required
geometry2.addDrawCall( start2, count2, 0 );

var material1 = new THREE.MeshPhongMaterial( { map: map1 } );
var material2 = new THREE.MeshPhongMaterial( { map: map2 } );

var mesh1 = new THREE.Mesh( geometry1, material1 );
var mesh2 = new THREE.Mesh( geometry2, material2 );

three.js r.70

WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • The problem with this approach is, that i have 2 vertex buffers with the exact same data. 10011 vertices and the Geometry has 60+ Parts... so i have 60 vertex buffers with 10011 vertices. AND i want to draw 40 or more of this Geometrys. – user2304379 Feb 22 '15 at 09:11
  • 1. This is the best you can do given the constraints you proposed. You can type `renderer.info()` into the console for insight. 2. Can you create one large texture and modify your UVs, instead? 3. Or create a custom `ShaderMaterial`. – WestLangley Feb 22 '15 at 17:15
  • A custom ShaderMaterial sounds nice... any Idea how i can do that? – user2304379 Feb 22 '15 at 19:38
  • The fiddle in [this post](http://stackoverflow.com/questions/16781064/three-js-multiple-materials-on-object-loaded-via-objmtlloader/16781472#16781472) contains a simple `ShaderMaterial` -- just to get you started. Personally, I'd take my second suggestion above and run with it. – WestLangley Feb 22 '15 at 20:39
  • I down't want to change the original data and the Shader Idea supports this. So i understand the general idea of Shaders but is it possible to get some kind of Index/face ID in the vertex or fragment Shader? – user2304379 Feb 23 '15 at 09:38
1

You can create two geometries with same vertex buffers and different indexes:

var position = new THREE.BufferAttribute(positionArray, 3);
var normal = new THREE.BufferAttribute(normalArray, 3);
var uv = new THREE.BufferAttribute(uvArray, 2);

var indices1 = new THREE.BufferAttribute(indexArray1, 1);
var geometry1 = new THREE.BufferGeometry();
geometry1.addAttribute('position', position);
geometry1.addAttribute('normal', normal);
geometry1.addAttribute('uv', uv);
geometry1.addAttribute('index', indices1);

var indices2 = new THREE.BufferAttribute(indexArray2, 1);
var geometry2 = new THREE.BufferGeometry();
geometry2.addAttribute('position', position);
geometry2.addAttribute('normal', normal);
geometry2.addAttribute('uv', uv);
geometry2.addAttribute('index', indices2);

and then create 2 meshes with different materials as you normally would. As far as I understand, this will re-use same data in both meshes.

makc
  • 1,050
  • 1
  • 9
  • 20
  • i have tried this and it has the same problem as WestLangleys approach. 2 Identical vertex / normal buffers with vertices and normals i down't need. Some solution would be to slice the vertices with the correct indices, but i downt know how to do this. – user2304379 Feb 22 '15 at 09:17
  • they are not identical, they are same. it is literally same object, and three.js will call _gl.createBuffer() only once per this object. – makc Feb 22 '15 at 09:53