Help with PBR shader

Hi, I’m trying to implement PBR (physically based rendering) into my game, but I can’t access mipmap levels from a cubemap, I’m using .dds file format with custom mipmap levels.

After doing some research I found that this function textureCubeLod(samplerCube s, vec3 coord , float lod) is the way to access mipmaps, I tried to change the lod float but it does nothing, is the same as using regular textureCube function.

Any clue what could be wrong? or is there any other way to access mipmap levels from a cubemap?

It could be that the cubemap’s texture filters are not set correctly to allow for mipmaps. This would be something that would take some effort to work around, as you would need to use something like PyOpenGL to load the cubemap yourself and get it to your shader (probably by loading the shader yourself).

Out of curiosity, are you using the cubemaps for image based lighting? And how are you generating the mipmaps, from my understanding this usually requires a more specific tool that can actually handle a cubemap with out creating visible seams.

Edit: Took a quick look at the source code, looks like my original guess may be correct. I can look into a possible patch tomorrow (I need some sleep before I trust myself with graphics code).

I’m generating mipmaps using ModifiedCubeMapGen-1_66 as described here

But basically my workflow is to render a panoramic equirectangular image out of cycles(.hdr), then using the free version of HDRShop to convert the image to a vertical cross cubemap for the PBR stuff and another conversion to a Light Probe(Angular Map) in .float format for IBL and nine coeff extraction using prefilter.c

The shader is almost completed, normal maps and IBL are working now, for reflections I’m using BPCEM the only thing missing is the mipmap access for use with a gloss map, another little problem is that I’m trying to make work a simple diffuse reflection shader from this tutorial to use it in combination with my IBL shader, but for some reason it’s rendered completely black.

I’m attaching a test .dds cubemap with 3 mipmap levels, if you manage to make it work please let me know and thank you very much for your help.

cubeMap.zip (34.5 KB)

I’m writing here for a similar behavior related also to simple texture. Attached there is a blend file with a custom GLSL shader using a textureLod to retrieve the sample at a specific mipmap level of a DDS texture. Launching the external player nothing happens while using the internal player the result is correct :confused:. Is there something I’m missing?

mipmap.zip (385 KB)

Same thing happened to me!

My workaround was to create a texture atlas with all the mipmap levels and then do an UV offset for each mipmap level. Here’s an example.


If you can use a (slightly) modified UV layout, you could put the same amount of data in half the texture space, not sure if that’s an issue for you but I’m anal enough that it bothers me when I see wasted space in a UV map.

I can see you played Tetris :smiley: I made it that way because of performance for calculate the mipmap coordinates with a division by two, but now looking at your alignment, it seems that it could work the same way, I’ll give it a try. Thank you!

Great solution!
Ok I need to put my hands on tetris (again) :smiley: Thank you!

Aryok, I’m trying to use your method but I see some seams along face borders (even from level 0). With RAS_MIPMAP_NONE I can partially solve the problem but they are still there. Are you weighting the texels near the edge? Actually I’m following the classic algorithm:
1 - choose the absolute value of biggest component
2 - normalize the other two components and map them to [0,1]
3 - choose positive or negative direction depending on sign of biggest component
(4 - make some UV computation)


What result gives you a bias of -10? eg. texture2d(sampler, texcoord, -10.0)

Sorry for the late reply… Thanks, adding a bias of -10.0 partially solves the problem, in fact if i don’t use the MIPMAP generation button (under the texture in Blender-Render mode) and I add the bias, this succeeds to “hidden” the seams. Unfortunately incrementing the LOD the seams begin to appear again.
on the other side using the MIPMAP generation (so enabling the linear filtering on the texture) the seams are really visible, especially in higher LOD values as the interpolation between edge pixels (that must point to the right side of cube during filtering) is much more relevant. Now I’m trying to code this behavior by my hands…



Aryok I’m seeing now your file… I will try to understand your solution for cubeMap. Thank you! Amazing work!

In the cubeRot function I passed a seam variable which fixes the seam for an specific mip level, just look at mipLevels array, the last two values for every element holds the seam for “R” and “R2” and lines 280-281 is where I used it. Good luck!