Skip to content

Conversation

@mvaligursky
Copy link
Contributor

No description provided.

- fixes related to device.draw trying to render without instancing when single instance is requested, and also handling of 0 instancing by skipping rendering
- hardware-instancing.html - simple engine test to render few cubes using instancing
@mvaligursky mvaligursky requested a review from a team February 5, 2020 09:37
@mvaligursky
Copy link
Contributor Author

I have more complex Editor sample for hardware instancing as well.

@mvaligursky
Copy link
Contributor Author

Note - I’ve just noticed the issue with culling - bounding box of original entity/mesh is used for culling. I need to disable culling on instanced objects.


var pos = new pc.Vec3();
var rot = new pc.Quat();
var scl = pc.Vec3.ONE.clone().scale(0.1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just do var scl = new pc.Vec3(0.1, 0.1, 0.1);. Simpler, faster, less characters! 😄

var box = new pc.Entity();
box.addComponent("model", {
material: material,
type: "box",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove trailing comma.

material.onUpdateShader = function(options) {
options.useInstancing = true;
return options;
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gotta say - this is a bit ugly from an API use perspective. For a casual reader, it's not obvious what's going on here. Is there not an option to either do:

var material = new pc.StandardMaterial();
material.instancing = true;

Or, even better, to set the useInstancing option internally since we can see the mesh instance that the material is assigned to has a pc.InstanceData object assigned to it?

* @description Returns description of vertex format which is used by {@link pc.VertexFormat} to
* construct a vertex format used for hardware geometry instancing. This represents 16 float values
* which represent a {@link pc.Mat4}
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the naming of getInstancedStreamDefaultVertexFormat is nice and clear, but overly verbose. Why don't you create an instanced vertex format (type: pc.VertexFormat) on pc.GraphicsDevice creation maybe, and make it accessible at pc.VertexFormat.defaultInstancingFormat (use Object.defineProperty with just a get function to make it read-only)? Also, notice how I'm matching defaultInstancingFormat with naming of pc.InstancingData.

}
},

setVertexBuffer: function(vb) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably recommend just having pc.InstancingData#vertexBuffer as a property (with getter/setter). Maybe then we could get rid of the update function. On a set, just also do what's in update? We'll need to also make pc.InstancingData public API.

- simplified engine interface
- disabled culling for instanced meshes
- improved documentation
var vertexBuffer = new pc.VertexBuffer(this.app.graphicsDevice, pc.VertexFormat.defaultInstancingFormat, instanceCount, pc.BUFFER_STATIC, matrices);

// initialise instancing using the vertex buffer on meshInstance of the created box
var boxMeshInst = box.model.model.meshInstances[0];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, you can access the meshInstances array on the pc.ModelComponent, so you can do the slightly simpler:

var boxMeshInst = box.model.meshInstances[0];

* Pass null to turn off hardware instancing.
*/
Object.assign(MeshInstance.prototype, {
setInstancing: function (vertexBuffer) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you define this in the previous Object.assign(MeshInstance.prototype, { block?

* @type {number}
* @description Number of instances when using hardware instancing to render the mesh.
*/
Object.defineProperty(MeshInstance.prototype, 'instancingCount', {
Copy link
Contributor

@willeastcott willeastcott Feb 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep all pc.MeshInstance API together. 😄 Move up?

@guycalledfrank
Copy link
Collaborator

Just saying - if I had time, I would implement instancing on top of Batch Groups, because it is related and also easy to grasp/use. Currently we have static (attach all meshes) and dynamic (attach and skin all meshes) batching. Now let's say we mark a group as "instanced" - engine would go over meshes, find cloned meshInstances, generate static per-instance vertex buffer, and that's it. We can also add some method to update this buffer.

@mvaligursky
Copy link
Contributor Author

agreed, it's something I'm considering adding as well. This PR is basic functionality / examples allowing users to use it themselves, and we should integrate it with batching.

Even though I'd probably like to have batching dynamic .. current one has limitations - especially if you need to preserve sorting.

@guycalledfrank
Copy link
Collaborator

guycalledfrank commented Feb 7, 2020

I tried to add completely dynamic instancing before, which would scan meshInstances to be rendered and do a single instanced draw instead - it wasn't worth it, scanning through lots of objects and updating/creating buffers at runtime was too costly. This time I'd recommend generating preferably static intstancing groups and cull them with a combined AABB.

Updating buffer data to keep correct sorting can be an option - just don't recreate buffers.


app.scene.ambientLight = new pc.Color(0.2, 0.2, 0.2);

// Create an Entity with a point light component and a sphere model component.
Copy link
Contributor

@ellthompson ellthompson Feb 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't look like there's a sphere model component used here, is this an outdated comment?

/**
* @readonly
* @name pc.GraphicsDevice#extInstancing
* @type {boolean}
Copy link
Contributor

@willeastcott willeastcott Feb 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this isn't necessarily a boolean. For WebGL 2 it's a boolean. For WebGL 1, it's an object (see MDN). This should probably be tidied up in the engine code at some point. BTW, we don't document the other pc.GraphicsDevice#extXYZ properties. Maybe we could introduce something like:

this.supportsInstancing = !!this.extInstancing;

There's already precedent for that with supportsMsaa and supportsStencil.

@mvaligursky mvaligursky merged commit 5f7c501 into master Feb 7, 2020
@mvaligursky mvaligursky deleted the mvaligursky-hardware-instancing branch February 7, 2020 17:14
@mvaligursky mvaligursky mentioned this pull request Feb 11, 2020
TheJonRobinson added a commit to Mojiworks/playcanvas-engine that referenced this pull request Feb 23, 2020
* master: (31 commits)
  WebXR Input Sources (playcanvas#1873)
  Simplified constants definition in Math classes (playcanvas#1876)
  Improve batching to handle 8-bit and 32-bit index buffers (playcanvas#1872)
  Add particle start frame example to browser
  [FIX] Update WebXR examples to use latest enums (playcanvas#1870)
  [FIX] Add XRWebGLLayer to externs for Closure compiler (playcanvas#1869)
  update paths in the particle system start frame example (playcanvas#1868)
  add a animation start frame variable to the particle system which def… (playcanvas#1864)
  point cloud example using engine directly, and custom shader changing size and color of points (playcanvas#1867)
  WebXR Support (playcanvas#1834)
  Hardware Instancing fixes / sample (playcanvas#1846) (playcanvas#1856)
  [VERSION] v1.25.0-dev
  [RELEASE] v1.24.7
  Recompiled basis, now works on IE (playcanvas#1865)
  Small mesh cleanup (playcanvas#1866)
  [FIX] Revert memory-leak change (playcanvas#1862)
  [FIX] Flag model as immutable when it's added to a ModelComponent (playcanvas#1861)
  [FIX] Fix calculation of deprecated pc.MouseEvent#wheel (playcanvas#1859)
  [DOCS] Adjust Vec3.normalize docs to reflect behavior better (playcanvas#1849)
  pc.BatchManager.markGroupDirty is now public (playcanvas#1848)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

5 participants