-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
groups/drawcalls/offsets
not working for non MeshFaceMaterial
on 72dev
#7057
Comments
Sorry about that, I guess I will just use MeshFaceMaterial when I need to do so... |
Reopened. I would hope this would be fixed. |
@WestLangley Yes, I understand that but I guess it is more important to remove those legacy support. Like offsets/drawcalls/drawCalls.. so messy at the moment in the source codes. For now the simple workaround is to "follow their standards" like: mesh = new THREE.Mesh(
new THREE.PlaneBufferGeometry(100, 100),
new THREE.MeshFaceMaterial([
new THREE.MeshBasicMaterial({color: 0xff0000})
])
);
mesh.geometry.groups = [{ start: 0, count: 3, materialIndex: 0 }];
stage3d.scene.add(mesh); |
Yes, @mrdoob made a similar suggestion in #6982 (comment) when commenting on my animated line example. He also acknowledged that the workaround was "weird". I agree. |
Yeah. I'm indeed aware of this, but I just can't see a better solution... Basically, this approach aligns |
What about (at least temporarily) adding something like this } else if ( geometry.groups.length > 0 ) {
var groups = geometry.groups;
for ( var i = 0, l = groups.length; i < l; i ++ ) {
pushRenderItem( object, geometry, material, _vector3.z, groups[ i ] );
} at https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1363? That way, you don't have to wrap all your materials in |
Looks good to me! 😊 |
Meh... This broke wireframe. |
Part of the problem is that The wireframe problem is related but I hadn't noticed until now... |
What about removing var geometry = new THREE.SphereBufferGeometry();
var geometries = [
new THREE.SubGeometry( geometry, materialIndex ).setRange( start, count ),
new THREE.SubGeometry( geometry, materialIndex ).setRange( start, count )
];
var mesh = new THREE.Mesh( geometries, new THREE.MultiMaterial( [ material1, material2 ] ) ); So, instead of hiding the drawcalls/groups stuff inside buffergeometry we take it out of it and then we can reuse a single geometry across different objects type with different start/counts, etc Maybe we could even add var geometry = new THREE.SphereBufferGeometry();
var geometries = [
new THREE.BufferGeometry( geometry, materialIndex ).setRange( start, count ),
new THREE.BufferGeometry( geometry, materialIndex ).setRange( start, count )
];
var mesh = new THREE.Mesh( geometries, new THREE.MultiMaterial( [ material1, material2 ] ) ); And this... which I know @WestLangley likes. var geometry = new THREE.SphereBufferGeometry().setRange( start, count );
var mesh = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial() ); Maybe a more objectified version would be this: var geometry = new THREE.SphereBufferGeometry();
var geometries = new THREE.GroupGeometry();
geometries.add( geometry, materialIndex, start, count );
geometries.add( geometry, materialIndex, start, count );
var mesh = new THREE.Mesh( geometries, new THREE.MultiMaterial( [ material1, material2 ] ) ); Just when I thought that we were done with this... 😁 The good news is that now that |
I think this is what I'm going to implement... Defining a range to draw: var geometry = new THREE.SphereBufferGeometry();
geometry.setRange( 0, 100 ); // start, count
var mesh = new THREE.Mesh( geometries, new THREE.MeshBasicMaterial() ); When using var geometry = new THREE.SphereBufferGeometry();
geometry.addGroup( new THREE.GeometryGroup( 0, 100, 0 ) ); // start, count, materialIndex
geometry.addGroup( new THREE.GeometryGroup( 100, 100, 1 ) );
var mesh = new THREE.Mesh( geometries, new THREE.MultiMaterial( [ material1, material2 ] ) ); I think this solves all the cases I've seen people mentioning. Any better names than I'm also wondering whether we should simplify raycast() and remove all the |
Would this allow sorting by program for the draws in WebGLRenderer? |
Well, we can do that already I think. But what this allows is to be able to load an old |
I mean you'll want to sort at the sub geometry level across the scene; rather than the mesh level; otherwise you will be flip flopping programs which is the most expensive gpu state change |
Yeah, we do that already 😊 |
I like Related: I am not too sure about the May be create the |
I agree, Group/drawcalls should belong to the mesh rather than the geometry. It is more flexible to reuse the geometry data |
I have made my case multiple times before in other threads, so I will keep it short. Materials have nothing to do with geometry. It is the responsibility of the Note, we had I would also use the term |
Exactly and I agree that the |
@WestLangley Do you agree that for purposes like the |
@arose In that example, all the
It is the API that repopulates the data every frame, so I see no reason why |
@WestLangley right, data is pushed there every frame, but the number of positions drawn is also changed every frame: linesMesh.geometry.groups[ 0 ].count = numConnected * 2; So the attribute data is updated, but not the full data is drawn. This allows the variable number of connections drawn in the demo per frame. |
@arose I am aware of that. You can achieve the same even if |
@WestLangley sorry, didn't mean to imply you weren't aware of that. I guess having Some thoughts on a possible API var geometry = new THREE.SphereBufferGeometry();
var material1 = new THREE.MeshBasicMaterial();
var material2 = new THREE.MeshBasicMaterial();
// establish a one-to-one mapping between geometry and material, draw full geometry
var mesh = new THREE.Mesh( geometry, material1 );
// set a draw range, clear to remove default drawcall
mesh.clearDrawcalls();
mesh.addDrawcall( 0, 100 ); // offset, length [materialIndex defaults to zero]
// do we need something like MultiMaterial or is a simple list sufficient?
var multiMaterial = new THREE.MultiMaterial( [ material1, material2 ] );
// when given a MultiMaterial, the mesh would render nothing initially...
var mesh = new THREE.Mesh( geometry, multiMaterial );
// ... but would require adding the mappings
mesh.addDrawcall( 0, 100, 0 ); // offset, length, materialIndex
mesh.addDrawcall( 100, 100, 1 ); Here is another, more abstract approach, avoiding the notion of drawcalls altogether. var geometryView1 = new THREE.GeometryView( geometry, 0, 100 ); // geometry, offset, length
var geometryView2 = new THREE.GeometryView( geometry, 100, 100 );
var mesh1 = new THREE.Mesh( geometryView1, material1 );
var mesh2 = new THREE.Mesh( geometryView2, material2 );
geometryView1.setRange( 200, 100 ); // change the draw range
mesh2.material = material1; // change the material There could be helper function to create these meshes, put them in an enclosing |
I like this. I think something like this follows the design of the API. My problem with |
If the mesh material is not MeshFaceMaterial, it doesn't render separately with groups. Which means I can't render parts of the whole geometry.
https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1358-L1399
The text was updated successfully, but these errors were encountered: