Google-apps
Hoofdmenu

Post a Comment On: C0DE517E

"Mipmaps, generation and level selection"

10 Comments -

1 – 10 of 10
Blogger Nick said...

Also with normal maps, I've read of storing a spec value in the alpha channel that gets much lower in your mipmaps.

This way the high frequency details that cannot be represented in the smaller mipmaps more correctly appear as "soft".

Unfortunately I don't know where to find the paper/presentation/slides offhand. This was the nvidia presentation where there was also the recommendation that if you know the destination resolution and target geometry you can tweak the color of your mipmaps to do fog, the example is green "fog" looking down a brown sewer pipe.

May 2, 2008 at 10:03 PM

Anonymous Anonymous said...

Nick, you're not referring to the "Toksvig factor" paper, are you?

May 3, 2008 at 2:05 AM

Anonymous Anonymous said...

Hi !

I agree, mipmaps is certainly one of the easiest idea in computer graphics, but much more complicated. As you seem to be a "mipmap guru", I would like to ask you some questions, as neither at GameDev nor GPGPU they achieved to answer me yet.

I'm trying to implement a paper about illumination that makes heavy use of mipmaps. Until now, I've only used them for simple texture use (generate mipmaps, and let's OpenGL do the rest).

But here, it's much more complicated. Here is the idea : I have to render into several textures normals, positions, intensities from the light point of view, and an additionnal parameter : a validity parameter (1 means valid, and 0 invalid) that is stored into an alpha cannal (the paper says it is better to store it in an alpha value rather than a A8 texture). So the intensity will be stored, for instance, in the alpha cannal of the intensity texture (which is R16G16B16A16F).

The level 0 (ie. base level) has validity 1 for EACH of the pixels. And then comes the problem. The paper says that I have to generate each sublevels with hardware accelerated generation of mipmaps, which is quite easy, and then add the validity parameter in the fragment shader in a bottom-up algorithm.

I haven't found a lot of things about that on the Internet, but as I can't add value to a uniform texture, I decided to create my own mipmaps on the GPU, but I really don't know if I do right :

1) I bind each base level as a uniform sampler2D.
2) I attach the next levels as several render targets and then perform MRT. Then, in the fragment shader, I store into each texture (ie. next level) the average of the four fragments, and I compute the validity in the same fragment shader.

The validity is quite simple to compute : for instance, I compute the average value of the four sub-pixels positions, and compare each of those pixels with the average value, and if one of them is superior to a threshold, it is invalid, otherwise it's valid.

By doing this, I think I can generate my mipmaps efficiently AND store in the same passes the validity (one pass for generating one level).

Here is a snippet of the fragment shader for one texture : (I put it on MegaUpload) : http://www.megaupload.com/fr/?d=QWU3PEZC

But I really don't know if I do it well, or if there are better ways to do that, since efficiency is really important, that I have to generate those mipmaps each frames, and that I have not only one, but three textures to generate (Positions, Intensity, Normals).

Thanks for you help and sorry for the English and the very long post !

May 3, 2008 at 8:15 AM

Blogger DEADC0DE said...

Unfortunately I haven't really understood the algorithm you're trying to implement.

If you give me a link to the paper, maybe I can tell you something more.

What I can say for sure is that "I attach the next levels as several render targets and then perform MRT" makes no sense, you can't MRT on mipmap levels as MRT targets have to be all of the same size.

The usual way to generate mipmaps on the GPU is to bind a level as a sampler and the next one as the rendertarget, until you have processed all the levels. It's useful when you don't have automatic mipmap creation or when for example, you have to create mipmaps of shadowmaps (that require a min or max filtering, not average).

May 3, 2008 at 11:13 AM

Anonymous Anonymous said...

Hi,

Sorry for not having been clear !

"The usual way to generate mipmaps on the GPU is to bind a level as a sampler and the next one as the rendertarget, until you have processed all the levels."

This is what I wanted to say :). When I told about MRT, it was because I created several textures at once (I had three textures, so I bind texture1 with GL_TEXTURE0, texture2 and texture3, and then do MRT with gl_FragData[0] being the next level of texture one, gl_FragData[1] the next level of texture two...

Here is the algorithm : it's a new algorithm for real time indirect illumination and it is, I have to say, really clever. I understand it really well, but I have difficulties in implementing it... : http://ki-h.com/archive/KiH-VC08-LP.pdf

In fact, I read it again, and in fact it says : "You can store this value in an A8 texture" (read 3.2).

I think it will be simpler to :

1) Create three buffers R16G16B16 (base level).
2) Do hardware accelerated mipmaps
3) Then fill an A8 texture with validity... It will be a lot of texture fetches :D.

Next step will be to understand how to access to mipmap levels correctly inside the fragment shader. There isn't much about that on the Internet :/

May 3, 2008 at 12:10 PM

Blogger DEADC0DE said...

I'll read the paper when I have the time, now I'm busy building my furniture (IKEA stuff).

For accessing a given lod level, if you need it to be per-pixel you have to use tex2dlod, that depending on your hardware can have a performance penality (some GPUs implement it by emitting 1-pixel quads with ad-hoc generated gradients to match the lod). If you need to force a mipmap level per object instead, you can set the min-max mipmaps in the sampler state.

May 3, 2008 at 1:51 PM

Anonymous Anonymous said...

Thank you ;).

Good luck with your IKEA furniture :).

May 3, 2008 at 2:31 PM

Anonymous Anonymous said...

Hi again :)

I think I do it correctly this time ! So, what I did is :

1) Generating my textures, and generating hardware-accelerating mipmap, so this is very fast.
2) Next, I fill a validity texture with that shader : http://www.megaupload.com/fr/?d=1NFERP2M

For now, I use an RGBA16F texture because I can render it directly, but next an A8 texture will be sufficient because I ahve only one value to store (0 or 1).

I draw each validity texture and it seems quite coherent : low level are more white (because more valid), while high level are nearly all black. I think I've used correctly texture fetches with mipmap :) (the third parameter in texture2D is the mipmap level).

May 4, 2008 at 1:06 PM

Blogger DEADC0DE said...

ah ye, sorry I told you the HLSL way of doing things I really hate OpenGL shading language, under OpenGL I use Nvidia CG, that's waaay better in my opinion.

May 5, 2008 at 11:22 AM

Anonymous Anonymous said...

I prefer GLSlang, because it integrates really easily with OpenGL :).

Now I try to traverse the mipmap tree, much more difficult :/

May 5, 2008 at 12:18 PM

You can use some HTML tags, such as <b>, <i>, <a>

Comment moderation has been enabled. All comments must be approved by the blog author.

You will be asked to sign in after submitting your comment.
Please prove you're not a robot