Jump to content
  • Advertisement
Sign in to follow this  
Pilpel

Render queues - why are they needed?

This topic is 901 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Can someone explain to me why everyone uses render queues? In Horde3D they look as follows

struct RenderQueueItem
{
	SceneNode  *node;
	int        type;  // Type is stored explicitly for better cache efficiency when iterating over list
	float      sortKey;

	RenderQueueItem() {}
	RenderQueueItem( int type, float sortKey, SceneNode *node )
		: node( node ), type( type ), sortKey( sortKey ) {}
};

typedef std::vector< RenderQueueItem > RenderQueue;

1. I know translucent objects need to be sorted, but why would I sort opaque objects? The Z buffer already does it, isn't that so?

2. Instead of pushing items to the render queue and then examine them, what's wrong with the following approach?

void SceneManager::draw()
{
	//culling
	...

	//draw light scenes
	_lightShader.use();
	for (size_t i = 0; i < _lightSceneNodes.size(); i++) {
		SceneNode *node = _lightSceneNodes[i];
		renderer->drawSceneNode(node);
	}
	_lightShader.unuse();

	//draw static meshes
	_staticMeshShader.use();
	for (size_t i = 0; i < _staticMeshesSceneNodes.size(); i++) {
		SceneNode *node = _staticMeshesSceneNodes[i];
		renderer->drawSceneNode(node); //draw all meshes of a scene node
	}
	_staticMeshShader.unuse();

	//draw animated meshes
	_animatedMeshShader.use();
	_animationController.updateAllAnimations();
	for (size_t i = 0; i < _animatedMeshesSceneNodes.size(); i++) {
		SceneNode *node = _staticMeshesSceneNodes[i];
		renderer->drawSceneNode(node);
	}
	_animatedMeshShader.unuse();
} 

Edit:

That being said, I'm spending most of my time trying (failing) to grasp the whole concept of a proper scene management system.

I read "The Rendering Engine" chapter in the book Game Engine Architecture but it mainly explains low-level stuff like what data is sent to the gpu and how it renders objects.

So all I'm left with is examining other frameworks with no luck. Any good learning source on this subject will be highly appreciated!

Edited by Pilpel

Share this post


Link to post
Share on other sites
Advertisement

Sorting non transparent meshes is mostly done for performance reasons.

Front to back sorting allows early z-discard. Objects in the back don't need to have their expensive shaders run if they are occluded by nearby objects.

Sorting by material minimizes state changes that can be expensive on many systems.

 

Also a render queue simplifies the rendering system and decouples it from the rest of the engine.

Edited by Madhed

Share this post


Link to post
Share on other sites

Sorting non transparent meshes is mostly done for performance reasons.

Front to back sorting allows early z-discard. Objects in the back don't need to have their expensive shaders run if they are occluded by nearby objects.

You mean if I sort opaque objects, I can then render these objects safely without glEnable(GL_DEPTH_TEST) ?

Share this post


Link to post
Share on other sites
Renderqueues doesnt really have anything to do with sorting geometry.

An item in a renderqueue is just an instruction to the gpu to do something.

See them as renderpasses, the example is just a renderpass for geometry that support sorting for those cases when it is needed.

Since you have to "do something" in a particular order to get the result you want, a queue is a sensible data structure.

Also, since the gpu is asynchronous to the cpu giving it instructions, it again makes sense to push the instructions on a queue, for the gpu to consume.

Even with your other proposed model (similar to how opengl works) you'd have to build some queue or commandlist internally to send instructions to the gpu

Share this post


Link to post
Share on other sites
You mean if I sort opaque objects, I can then render these objects safely without glEnable(GL_DEPTH_TEST) ?

If you sort them by depth (in camera space), then yes, assuming that there are no intersections. However, opaque objects are usually sorted by their shader programs, textures, etc., because switching them forth and back is expensive.

Edited by haegarr

Share this post


Link to post
Share on other sites

Renderqueues doesnt really have anything to do with sorting geometry.

An item in a renderqueue is just an instruction to the gpu to do something.

An item in a render queue represents a draw call, and in this sense is related to sorting geometry (but draw calls can be more than just geometry).
A command queue is “just an instruction”. Render queues order draw calls, then command queues/command lists can be build from the ordered draw calls.

Can someone explain to me why everyone uses render queues?

To sort draw calls for optimal performance or results.
Translucent objects must be sorted back-to-front for correctness, whereas opaque objects should be sorted by material to reduce state changes, since swapping shaders, textures, and vertex buffers is expensive.

1. I know translucent objects need to be sorted, but why would I sort opaque objects? The Z buffer already does it, isn't that so?

When the material is the same, sort opaque objects front-to-back to reduce overdraw (take advantage of early Z).

2. Instead of pushing items to the render queue and then examine them, what's wrong with the following approach?

It hard-codes the order of draws in an illogical and arbitrary way. It makes no attempt to draw objects in a logical order where GPU state changes (shader, texture, vertex buffer, index buffer, etc.) are minimized and such that near objects are drawn first to reduce overhead.


L. Spiro

Share this post


Link to post
Share on other sites

An item in a render queue represents a draw call, and in this sense is related to sorting geometry (but draw calls can be more than just geometry).

 

The fact that a "draw call" can be more then just geometry is the reason I said that render queues aren't really about sorting geometry.

It's about ordering draw calls. 

 

As I see it, the render queue is more about ordering drawcalls to get the correct result, and in a way that closely relates to how the gpu works, not about performance.

Just happens that since it is closer to how the gpu works, it gets more intuitive to order your stuff in a performant way.

 

Well.. I guess I'm just splitting hairs...

Edited by Olof Hedman

Share this post


Link to post
Share on other sites

To sort draw calls for optimal performance or results.

Translucent objects must be sorted back-to-front for correctness, whereas opaque objects should be sorted by material to reduce state changes, since swapping shaders, textures, and vertex buffers is expensive.

Even vertex buffers need to be sorted? How can I do that? Each standard model I have has 10~ VBOs.

Also, what a render queue may look like? They say I should store all this info (shader id, texture id, depth (which is the length from the camera to the center of the object, right?)) in a single variable (8 bytes). How do I sort by these elements? I never played with bits that much! wacko.png

Edited by Pilpel

Share this post


Link to post
Share on other sites

Thanks for the explanation Sean!

Do you know where I can learn about these stuff? (Articles / open source frameworks / anything!)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!