Jump to content
  • Advertisement
Sign in to follow this  
Solid_Spy

OpenGL Packing more than four pixel elements into OpenGL Texture

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

Hello, I have been working on SH Irradiance map rendering, and I have been using a GLSL pixel shader to render SH irradiance to 2D irradiance maps for my static objects. I already have it working with 9 3D textures so far for the first 9 SH functions.

In my GLSL shader, I have to send in 9 SH Coefficient 3D Texures that use RGBA8 as a pixel format. RGB being used for the coefficients for red, green, and blue, and the A for checking if the voxel is in use (for the 3D texture solidification shader to prevent bleeding).

My problem is, I want to knock this number of textures down to something like 4 or 5. Getting even lower would be a godsend. This is because I eventually plan on adding more SH Coefficient 3D Textures for other parts of the game map (such as inside rooms, as opposed to the outside), to circumvent irradiance probe bleeding between rooms separated by walls. I don't want to reach the 32 texture limit too soon. Also, I figure that it would be a LOT faster.

Is there a way I could, say, store 2 sets of SH Coefficients for 2 SH functions inside a texture with RGBA16 pixels? If so, how would I extract them from inside GLSL? Let me know if you have any suggestions ^^.

Edited by Solid_Spy

Share this post


Link to post
Share on other sites
Advertisement

There is no 32 texture limit.  True, there are only GLenums up to GL_TEXTURE31, but for textures higher than that you can just use GL_TEXTURE0 + num.

Share this post


Link to post
Share on other sites

Two ideas come to mind:

Use Spherical Gaussians instead of Spherical Harmonics. You can knock your textures down to 5 textures and still have some pretty acceptable results.

Use deferred shading and your texture limit concerns disappear entirely.

You can definitely store 2 sets of data inside a single texture by packing the data. However, you'll lose all ability to interpolate your results, and with 3D textures that I imagine are somewhat coarse, interpolation is not something you'll want to lose.

Edited by Styves

Share this post


Link to post
Share on other sites
48 minutes ago, Styves said:

Use Spherical Gaussians instead of Spherical Harmonics. You can knock your textures down to 5 textures and still have some pretty acceptable results.

I would love to learn how to use spherical gaussians, but unfortunately I can't find much info or any tutorials on the subject. The only info I could find were calc and theory based dissertations sadly. Do you know where I can find any practical information on the subject?

 

Quote

Use deferred shading and your texture limit concerns disappear entirely.

Do you mean using only 9 SH textures for one texture atlas, then another 9 for another, and then combine both textures using deferred rendering? That I can do.

 

Quote

You can definitely store 2 sets of data inside a single texture by packing the data. However, you'll lose all ability to interpolate your results, and with 3D textures that I imagine are somewhat coarse, interpolation is not something you'll want to lose.

Ah, that blows :(.

Edited by Solid_Spy

Share this post


Link to post
Share on other sites
1 hour ago, mhagain said:

There is no 32 texture limit.  True, there are only GLenums up to GL_TEXTURE31, but for textures higher than that you can just use GL_TEXTURE0 + num.

Really? I hear that a lot of graphics cards in the last 5 years can only hold up to 32 textures per shader execution. My card is about a year old, so I assume I cannot hold more than 32. Though I could be wrong. I'll look into that.

Edited by Solid_Spy

Share this post


Link to post
Share on other sites

 

On 7/22/2017 at 0:09 AM, Solid_Spy said:

I would love to learn how to use spherical gaussians, but unfortunately I can't find much info or any tutorials on the subject. The only info I could find were calc and theory based dissertations sadly. Do you know where I can find any practical information on the subject?

MJP made a real nice post about this and also wrote a sample demo for people to try. Should be enough to get you going.

On 7/22/2017 at 0:09 AM, Solid_Spy said:

Do you mean using only 9 SH textures for one texture atlas, then another 9 for another, and then combine both textures using deferred rendering? That I can do.

Each of your 3D textures likely has a world bounds, so you can render this bounds as a deferred volume (box, whatever) and apply it to the screen using deferred shading, adding up all the results of your 3D volumes (or using blending so that they overwrite what's below). This way none of your geometry shaders need to know about which volumes affect them, you don't need to scan for volumes that the object needs to be lit by, and you don't have to worry about excessive overdraw (where a light might relight the same pixel many times).

If you don't have a deferred shading pipeline in your engine or aren't sure how to add one, then you can also do an old-school forward shading pipeline where you render the geometry several times with additive blending over a base (which has ambient + sunlight/global lighting) using a new set of volume textures in each pass. Heavier on geometry load if you have heavy scenes but simple to implement (just iterate over your geometry draw for every N lights/volumes and set the appropriate data and blend state).

However if you can keep your texture count within whatever limit you set (either from hardware or a decision on your part) you can just use the single pass. I assume each object likely won't have more than 1-3 volumes affecting it, so if that assumption is correct and you've got a 32-texture limit, you should be able to handle several volumes. Even with 9 textures per volume that's 3 volumes per object + 5 textures for other stuff (diffuse, spec/gloss/roughness, normals, emissive - all of which can be combined in certain ways to reduce the number of samples and textures you actually need, the above can be combined down to 2 textures if you know what you're doing). I think in this case you should be just fine.

Cutting down to 5-gaussian SG lighting gives you more volumes and textures.

Edited by Styves

Share this post


Link to post
Share on other sites
On 22/07/2017 at 0:32 AM, Solid_Spy said:

Really? I hear that a lot of graphics cards in the last 5 years can only hold up to 32 textures per shader execution. My card is about a year old, so I assume I cannot hold more than 32. Though I could be wrong. I'll look into that.

Check GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS  for the vertex shader and GL_MAX_TEXTURE_IMAGE_UNITS  for the fragment shader.

Share this post


Link to post
Share on other sites

Your hardware's shader model may have a limit on the number of textures that can be accessed in a single PASS, but most (modern) scenes require multiple passes. If you're changing geometry and texture at the same time, there's really not much overhead to draw stuff using multiple passes - however I wonder why you need so many textures, have you considered using a texture atlas / megatexture approach?

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!