-
Notifications
You must be signed in to change notification settings - Fork 250
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
Combine primitives #162
Combine primitives #162
Conversation
|
||
var AccessorReader = require('./AccessorReader'); | ||
var readAccessor = require('./readAccessor'); | ||
var writeAccessor = require('./writeAccessor'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same note about include order from the other PR.
Looks great! I did some simple testing and it seems to work well. |
@lasalvavida can you verify that it makes sense for the buggy model to have 95 fewer meshes, but only 37 fewer draw calls? |
var readAccessor = require('./readAccessor'); | ||
var writeAccessor = require('./writeAccessor'); | ||
|
||
module.exports = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lilleyse @lasalvavida can you two please review the design of this class? I don't think it is needed. Some functions could be private in the files they are used in; others could be standalone functions.
Let me know if you need help.
@pjcozzi Master currently bloats the number of meshes in cases where two meshes that are in node endpoints that can't be combined contain identical primitives. That is what drives up the draw call count. The output with this PR removes that bloating by recombining meshes after primitives get combined. The primitives are consolidated to fewer mesh endpoints, but there is still the same number of primitives. tl;dr It has the same number of draw calls as the version in the sampleModels, the current output of master is adding more unnecessary draw calls. |
Gotcha. |
…ne into combine-primitives
@lasalvavida Is there more to do for this? The latest merge commit has a few issues. |
There was a bad merge; it still needs tests. I'll add those now. |
@lilleyse This is updated and ready for a look |
…f-pipeline into combine-primitives
I have removed the second |
@lilleyse will you be able to review this soon? We have a lot of open PRs in this branch and I would like to get them merged. |
Yes I will review this today. |
MergeDuplicateProperties.mergeAccessors(gltfWithExtras); | ||
removeDuplicatePrimitives(gltfWithExtras); | ||
combinePrimitives(gltfWithExtras); | ||
combineMeshes(gltfWithExtras); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we talked offline about this a while ago, but I forget the conversation...
If possible we should try to avoid the second cleanup, and ideally our stages shouldn't be producing unoptimized gltf's. Sorry if I forgot the reason behind this.
} | ||
|
||
function transformPrimitives(gltf, primitives, transform) { | ||
var inverseTranspose = new Matrix4(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't you just do a simple loop over the position and normal arrays, transforming each set of 3 values with the transform and then writing back into the buffer. I don't see the need for involving indices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, you cannot. Primitives may share large attribute accessors of which they only index into a portion. Those primitives in turn may have different transforms. We cannot assume that a primitive uses its entire accessor, we must only transform the positions and normals that it uses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, this should use AccessorReader
instead of readAccessor
. I will make that change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right, thanks for the correction.
function generateIndices(v, k) { | ||
void(v); // v is an unused parameter | ||
return k; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If still needed, just put this code in transformPrimitives
.
if (primitivesShareAttributeAccessor(primitive, comparePrimitive)) { | ||
if (primitivesHaveOverlappingIndexAccessors(gltf, primitive, comparePrimitive)) { | ||
if (PrimitiveHelpers.primitivesShareAttributeAccessor(primitive, comparePrimitive)) { | ||
if (PrimitiveHelpers.primitivesHaveOverlappingIndexAccessors(gltf, primitive, comparePrimitive)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create a function for this in PrimitiveHelpers
that is called here and inside markPrimitiveConflicts
.
var primitives = mesh.primitives; | ||
if (defined(primitives)) { | ||
mesh.primitives = combineMeshPrimitives(gltf, meshId, primitives); | ||
PrimitiveHelpers.markPrimitiveConflicts(gltf, PrimitiveHelpers.getAllPrimitives(gltf)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a little awkward to save the conflicts in the pipeline object. If possible try to keep it in here.
Thanks for the update @lasalvavida |
I'm having issues converting this model: |
…f-pipeline into combine-primitives
… this was first written
This is mostly done now. I'm still getting slightly smaller models if I run them through the pipeline twice, and I'm still trying to pinpoint exactly why. |
This is ready for review. Referring to my original benchmarks the stats are now:
|
} | ||
var semantics = getPrimitiveAttributeSemantics(primitive, semantic); | ||
if (semantics.length <= 0) { | ||
primitive.attributes[semantic] = createAccessor(gltf, packedLength, 'VEC3', WebGLConstants.FLOAT, WebGLConstants.ARRAY_BUFFER); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is hardcoding VEC3
a problem for texture coordinates?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, you're right
This is really close. Every model I've tested works fine. Those numbers are nice! |
Updated |
Nice, I'm glad to finally get this in! Also because of adjustments here the pipeline just runs a lot faster. |
This is worth an initial look and some testing while I add tests for everything.
This pull request contains a few things:
removeDuplicatePrimitives.removePrimitivesFromMesh
Some preliminary testing with the buggy model: