Adding normalmap to card from cardmaker

Hey,

is it possible to add a normal map to a card generated by the CardMaker?

I tried it this way:

....
self.normal_tex = Texture()
self.normal_tex.setup2dTexture(self.resolution[1],self.resolution[0], Texture.T_unsigned_byte, Texture.F_rgb8)
self.normal_ts = TextureStage('normalmap')
self.normal_ts.setMode(TextureStage.MNormal)
normal_buff = self.normalmap.astype(np.uint8).tobytes()
self.normal_tex.setRamImageAs(normal_buff,'RGB')
self.nodepath.setTexture(self.normal_ts,self.normal_tex)
.....

but it turns the card black, while it was perfectly fine before applying the normal map.

Have you called “setHasNormals” on the “CardMaker” object? From what I see there, CardMaker doesn’t by default generate normals, only doing so if instructed to do so via “setHasNormals”. That might be at least part of the solution.

Unfortunately, the cards generated by CardMaker do not have binormals and tangents.

@Thaumaturge I already tried that. It is interesting though, that glossmaps work without calling “setHasNormals(True)”

@rdb okay, so what would be an elegant way to make an texture viewer? I mean, a cards tangents and binormals Are not Hard to generate procedurally, but if i want to add a sphere for Example, it could be worse. I think the card maker just generates two triangles, right? Would the Resolution of a sphere be a Problem if i dont know the Resolution of the JPG the User is going to load into the program?

Should i just make my 2 or 3 shapes I want to preview my textures on in Blender to have everything needed for lighting calculation?

You could export a sphere model from Blender or take an existing sphere model and use egg-trans to generate binormals and tangents. You could do the same with a flat card.

Alternatively, for simple shapes you can determine these values algorithmically, in the shader.

The resolution of the sphere is not directly related to the resolution of the texture.

I went the way via Blender->YABEE->egg-trans.exe and it seems to work pretty fine. But the Parallaxmap seems to be a bit wierd sometimes. As sone as I dim the parallaxmap via the slider on the right, black spots appear, growing bigger with the slider going down. The spots seem to be not just black, but they seem to be somehow messing with the normals (almost as if the normals get inverted when passing some certain value)
I went via:

self.parallax_ts = TextureStage('ts')
self.parallax_ts.setMode(TextureStage.MNormalHeight)
self.parallax_tex = Texture()
self.parallax_tex.setup2dTexture(self.resolution[1],self.resolution[0], Texture.T_unsigned_byte, Texture.F_depth_component)
parallax_buff = self.parallaxmap.astype(np.uint8).tobytes()
self.parallax_tex.setRamImage(parallax_buff)

The Texturestage uses Texture.F_depth_component, since it seems the only one working correctly. I tried alpha and luminance aswell, but they seem to not add any parallax to the texture. Am I doing something wrong? The Values of the parallaxmap range from 0 to 255 unsigned integers

EDIT:
I found the Bug. This happens because I used ‘TextureStage.MNormalHeight’ instead of ‘TextureStage.MHeight’
I think panda 3D should raise an error when it expects a 4 channel buffer and just recieves 1 channel