Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

DX11 Instancing - Only render certain instances

  • You cannot reply to this topic
2 replies to this topic

#1 Migi0027   Members   -  Reputation: 249

Like
0Likes
Like

Posted 20 March 2013 - 05:43 PM

Hi guys!

So, imagine you have a scene with 1000 trees and your rendering it with instancing, quite a lot, and you wan't to implement a lod system. Now your lod system is actually done, but now how do you change the buffers for that tree (the one too far away).

Illustration (real):
2uqd6px.png

Now as you see I have quite a lot of trees there, but now I only wan't some of those trees from my instanced buffer to be rendered. As I understand you have to update the buffer, but wouldn't that be quite heavy, or do I have to split up the instanced buffer into chunks, and update those? Right below I'm gonna show you how I handle my rendering.

Rendering:

UberBuffer._instance = true;
UberShader.SendObjectBuffer(ObjectBuffer, devcon);
UberShader.SendUberBuffer(UberBuffer, devcon);
InstancedMesh[i]->SendInstancedData(ObjectBuffer, Camera, Bufferphase, devcon); // doesn't really matter for now, but if you wan't it, say it :)

bool changed = false;

for (int lod = -1; lod < InstancedMesh[i]->Lods.GetCount(); lod++) // we start from -1 as some meshes don't have lods, so we actually trick it!
{
	if (changed)
	{
		InstancedMesh[i]->SendBuffers(devcon, dev, Camera, ObjectBuffer, Bufferphase);
		changed = false;
	}

	if (lod > -1) // is this a lod?
	{
		for (int instance = 0; instance < InstancedMesh[i]->instanceCount; instance++)
		{
			if (sqrtf(D3DXVec3Dot(&*Camera->GetPostion(), &InstancedMesh[i]->instances[instance].pos)) >= InstancedMesh[i]->Lods.GetComputedADistance(lod)) // distance...
			{
				InstancedMesh[i]->Lods.GetComputedLod(lod)->SendVIBuffers(devcon, dev, Bufferphase); // new vertex buffer
				changed = true;

				// DO SOME STUFF HERE
			}
		}
	}

	UberShader.SendConstantBuffers(devcon);
	UberShader.Render(devcon, Bufferphase, true, InstancedMesh[i]->instanceCount); // Render Instanced, one line of code: devcon->DrawInstanced(Bufferphase.IndexCount, instanceCount, 0, 0);

	for (int inSM = 0; inSM < (InstancedMesh[i]->SubMeshes.size()); inSM++) // Sub meshes, doesn't really matter so much for now, I'll take care of those.
	{
		InstancedMesh[i]->SendSubBuffers(devcon, dev, Camera, ObjectBuffer, Bufferphase, inSM);
		UberShader.Render(devcon, Bufferphase, true, InstancedMesh[i]->instanceCount);
	}
} 

 

 

Now for each Lod i check all the instances for the distance, and if the distance is larger, then apply the different vertex buffer. But somehow I only need to apply this vertex buffer to the instances affected by it!

 

Now how is this possible? blink.png


My Blog - Cuboid Zone , a graphical framework.


Ad:

#2 Jason Z   GDNet+   -  Reputation: 2368

Like
0Likes
Like

Posted 20 March 2013 - 06:20 PM

I would try to just use two different vertex buffers, and you can stick with a single instance buffer.  The trick is to reshuffle your instance data to have all of the high LOD instances in a continuous block, while the lower LOD instances should be in a separate block (you could just as easily implement this with two instance buffers I guess...).  This takes two draw calls, but that isn't a big deal.

 

This would require modifying the data in the buffers, but it would only be necessary once in a while when the view is significantly moved.  If you store your instances in an intelligent order (like in a quadtree fashion) then moving the data around should be minimally intrusive and will let you quickly get through the update.


Jason Zink :: DirectX MVP
Check out our (now available) D3D11 book: Practical Rendering and Computation with Direct3D 11
Check out my Direct3D 11 engine on CodePlex: Hieroglyph 3
Check out our free online D3D10 book: Programming Vertex, Geometry, and Pixel Shaders
Lunar Rift :: Dual-Paraboloid Mapping Article :: Parallax Occlusion Mapping Article :: Fast Silhouettes Article

#3 Migi0027   Members   -  Reputation: 249

Like
0Likes
Like

Posted 22 March 2013 - 03:20 PM

Alright got it working, thanks for pointing the way!


My Blog - Cuboid Zone , a graphical framework.






PARTNERS