Jump to content
  • Advertisement
Sign in to follow this  
lipsryme

Forward+ Rendering - best way to updating light buffer ?

This topic is 1329 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

I've got a prototype implementation of it working with point lights at the moment based on the most recent AMD SDK sample. Problem is their implementation uses a statically allocated array of XMFLOAT4 light data containing Position(Center) and Radius that they use to create an ID3D11Buffer once.

Now of course I want to be able to instantiate point lights in my scene on a button press (also being able to remove them again) so I was wondering what you guys think the best approach to creating/updating this buffer during runtime would be ? I guess what I should do here is have some kind of dirty flag that is set when instantiating/removing or changing a light's position/radius, right ? But I still don't really know how to update the ID3D11Buffer...I would guess releasing/recreating it would not be a good idea (which is what I'm doing right now in my prototype only when a light is added).

But even then wouldn't that be expansive to update the entire buffer if one or several lights just changed position (even more so what if they keep moving all the time I would have to update it all the time).

Edited by lipsryme

Share this post


Link to post
Share on other sites
Advertisement

I would guess releasing/recreating it would not be a good idea

 

You guessed right!

 

Simply create a ID3D11Buffer with D3D11_USAGE_DYNAMIC flag , large enough to hold the data of the maximum number of lights you'll need (512, 1024, 2048?), and update it using MAP_DISCARD every frame (or using a dirty flag when the lights change).

And pass the number of active lights in a cbuffer to the shader.

 

Since you're probably updating the light buffer once per frame this shouldn't be a bottleneck.

 

If you really need a more dynamic max number of lights try to reduce the number of times you release/create a buffer by doubling/halving it's size every time you resize it or something like that.

Edited by TiagoCosta

Share this post


Link to post
Share on other sites

Ah so I can just basically do the same as with constant buffers ! smile.png

Having some issues copying the data due to heap corruption but that might be related to something else.

Is this the correct way of doing it ?

 

Update: yep that heap corruption was something else. Seems to be working now smile.png

if (!pointLights_center_and_radius.empty())
{
	this->numActiveLights = static_cast<unsigned int>(pointLights_center_and_radius.size());
	D3D11_MAPPED_SUBRESOURCE pointLightResource = {};
	if (SUCCEEDED(this->context->Map(this->pointLightBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &pointLightResource)))
	{
		DirectX::XMFLOAT4 *pData = (DirectX::XMFLOAT4*)pointLightResource.pData;
		memcpy(pData, &pointLights_center_and_radius[0], sizeof(DirectX::XMFLOAT4) * numActiveLights);
		this->context->Unmap(this->pointLightBuffer, 0);
	}
}
Edited by lipsryme

Share this post


Link to post
Share on other sites

But even then wouldn't that be expansive to update the entire buffer if one or several lights just changed position (even more so what if they keep moving all the time I would have to update it all the time).

how big is the light constant buffer, 16kb? that's not problematic compared to all the other data you probably upload.

for very dynamic resources, it's best to use a staging buffer pool and over-allocate your rendering resources. thus you'd allocate 16kb of light constantbuffer even for just 1 lightsource, but update it by updating a small staging buffer and copy it to the big constant buffer.

usually you don't have access directly to VMem, what happens is that resources are mirrored in memory, if you update those, the driver copies them to VMEM. if you use a staging texture, you basically emulate that, paying with some cpu cost (as you need to invoke copysubresource) and getting paid back with some gpu/pcie reward.

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!