Normal Maps -> MipMapping

Hi,

I guess I know the answer to my question, but I would like to hear it from an advanced OGL coder .

If I use GL_LINEAR_MIPMAP_LINEAR for a Normalmap, that I use for DOT-3 Lighting, the generated Mipmaps (via GL_SGIS_generate_mipmap) will contain denormalized normals, or?

I would have to implement a function, that creates the Mipmaps and correctly normalizes the Normals in the Normalmap, right?

Regards,
Diapolo

Yep, it’s more correct if you renormalize each pixel in the mipmaps of your normalmap. This is something that most minification filters won’t do for you.

You’ll also lose normalization when doing linear interpolation (both within a single level and between mipmaps) so you may have to renormalize with a cubemap or something at the end anyway.

– Zeno

yes u will need to regenerate the renormalized normals yourself for the smaller mipmaps SGIS_mipmap or gluBuodmipmaps DONT do it.
also u might wanna rescale the heights by 2 for each smaller miopmap

Thanks for your replies .

Could denormalized Normals in the Mipmap of a Normalmap lead to color banding effects during Dot-3 Lighting?

Diapolo

Btw.: I was thinking about a good way to do texture loading, but I´m not sure how to do it good. I created a C++ class, that receives all needed parameters via the constructor and then loads the texture into OGL. You can query for the texture ID via an method of that class, but I´m absolutely not satisfied with that approach (needs global variables). I would like to be more “modular”. Any hints for me ?

Originally posted by Diapolo:

Btw.: I was thinking about a good way to do texture loading, but I´m not sure how to do it good. I created a C++ class, that receives all needed parameters via the constructor and then loads the texture into OGL. You can query for the texture ID via an method of that class, but I´m absolutely not satisfied with that approach (needs global variables). I would like to be more “modular”. Any hints for me ?

Think about interfaces. Have a abstract base Texture class that defines an interface. Then derive Cubemap, Mipmap, NormalMap, Diffusemap, etc classes from your Texture class.
Next, have an abstract TextureFactory class and then derive classes for building textures on top of that.

I should explain a bit further .

The class I have receives MANY parameters, Path, Texture size, Texture Type, Filtering Mode, Wrapping Mode, Texture Format and so on.
The class can load compressed DDS files, RAW files (with runtime compression) or create a normalisation cube map (I have 3 different functions in the class for those 3 things).
One Texture ID is generated for each Object of that class and this one can be queried via a method.

The problem now is, that I need these texture IDs in other classes, too.

I had C in school for 2 years, but we only did the basics of C++ during the last 6 months .

PK, you are talking about interfaces and that stuff, perhaps you could give a simple example with the help of the class I have (what you would change and that stuff).

I need no code only a “kick” into the right direction … let´s say a “C++ design lesson” .

Diapolo

If you plan on using GL_ARB_fragment_program you can normalize it after filtering like this:

DP3 temp, bump, bump; # Post-filter normalisation of bumpmap
RSQ invLen, temp.x;
MUL bump, bump, invLen;

This is what I do in my Phong demo. I initially thought it would hardly affect the look, but it does wonders for closeups.

Wouldn’t that save a register if you did this?

DP3 bump.w, bump, bump
RSQ bump.w, bump.w
MUL bump, bump, bump.w

I’m not sure the assembler could actually take that register out, as you end up with a different result in val.w at the end. And temp registers may be scarce. (Or not :slight_smile:

Yeah, it would

That’s pretty much the only thing I ever use .w for is normalizing (and boy do I use that a lot! ).

Though if you store a specular exponent map in the normal map’s alpha, then it would destroy that…

Originally posted by Diapolo:
[b]
I need no code only a “kick” into the right direction … let´s say a “C++ design lesson” .

Diapolo[/b]

class CTexture
{
public:

// a bunch of functions

protected:
std::string filename;
unsigned id;
};

class CCubemap : public CTexture
{
public:

// other functions you would need for a
// cubemap

protected:
// attributes of your cubemap
};

class CTextureFactory
{
public:
virtual CTexture* Load(std::string filename, WrapMode m);

protected:

};

class CCubemapFactory : public CTextureFactory
{
public:
CCubemap* Load(std::string filename, WrapMode m);

protected:
};

Alright so the CTexture and CTextureFactory classes aren’t abstract interfaces, but the above should get you started.

OK, thanks for your example.

You think I should build a base texture class, then build classes for different textures (2D, 3D, CubeMap and so on) on top of that base class?
Via class CCubemap : public CTexture, I can use the attributes and methods of the CTexture class in the CCubemap class (we didn´t do that stuff in school)?

But I wonder how I could access the texture IDs in other classes, that need textures as well (I can think of some bad solutions, but not a really good one g)?

And what about that keyword virtual, I´ve never used that stuff before .

Seems like many beginner questions, sorry for that .

Regards,
Diapolo

[This message has been edited by Diapolo (edited 11-13-2002).]


You think I should build a base texture class, then build classes for different textures (2D, 3D, CubeMap and so on) on top of that base class?

Good design is in the eye of the beholder. But that has worked for me so far. Don’t be afraid to write a bunch of code and then refactor a month or two down the road.


Via class CCubemap : public CTexture, I can use the attributes and methods of the CTexture class in the CCubemap class (we didn´t do that stuff in school)?

CCubemap inherits the attributes and functions of CTexture.

class CMesh
{
public:

protected:
CTexture mDiffusemap;
};

Is that what you mean? That’s kind of the naive solution. What you’ll probably want to do is code up a Texture Manager class that hands out Handles to textures so that different meshes can share textures.


And what about that keyword virtual, I´ve never used that stuff before .

The virtual keyword says, “I may be redefined by a derived class”.
Technically speaking, it activates late-binding. So the program decides at runtime if you need to call CTextureFactory::Load or CCubemapFactory::Load.

[This message has been edited by PK (edited 11-13-2002).]

Thank you very much .

I will look into that whole stuff and then think about a good solution, that fits my needs.

Diapolo

Bah, that “factory” and “design patterns” stuff was just made up to make our lives more complicated…

  • Matt

I’ve found implementation inheritance to be mostly unhelpful, whereas abstract superclasses (used as interfaces) help a lot in designing a usable abstraction layer.

If the operations on a texture are, say, “bind()” and “loadFromFile()”, then you’d probably want to define that as an interface using pure virtuals in your ITexture class, and then have your factory instantiate a CCubeMapTexture or CMipMappedTexture or CLookupFloatTexture depending on what the user asks of it. Each of those would derive from the abstract interface, and concretely implement those functions, in addition to whatever support the factory needs to configure them and set them operating.

Originally posted by mcraighead:
[b]Bah, that “factory” and “design patterns” stuff was just made up to make our lives more complicated…

  • Matt[/b]

Don´t say that Matt .
Quite a few NV demos use so many libs and structures and all that stuff, that I´m really unable to read / understand them.
If I want to learn basics, most of them are written way to complicated.

Diapolo

And what about templates? You can pass as an argument a set of options (number of dims, internal format, target). In that way class will be very efficent. For example:

template<DWORD num_dims, DWORD target>
class texture {
public:
void set_wrap_mode (GLenum mode) {
glTexParameteri (target, GL_TEXTURE_WRAP_S, mode);
if (num_dims >= 2)
glTex… (…GL_T…);
// and so on for GL_R and GL_Q

}
};

Compiler should optimize this class such as unneeded instructions will be omitted because branches can be evaluated at runtime.

What do you think about this concept?

sorry guys, but i just can’t help thinking you’re over-asbtracting things here a tad - you’re talking about a really self-contained object with minimal maintance load: textures. they’re used by other code, really, since they do little other than wrap low-level operations. so i’d say protocol/asbtract base classes are ok, but inheritance imposes a whole new management you might not be aware of: for example, what if you want one unique object instead of per-derived-class duplicates? inheriting base classes virtually doesn’t work as it should (as msdn says) on visual c++ 6 sp5…

my point is: for a low level object like texture wrapper, all you need is decent accessor methods: set/get blah. you can create one abstract class and then derive specialised versions to match the gl texture state, then create an interface class to do all the middle work for you.

on top of all this, the performance hit for late binding (invoking a virtual method that’s not pure virtual, like void foo() == 0; ) can be surprisingly high under some circumstances, so you don’t wan’t a possible performance hit on the renderer’s inner loop. search msdn, there’s info on this by a guy who’s worked on the compiler, sorry i can’t remember the article title, it’s about achieving good optimisation in vc6 and what sort of code it the ms compiler generates…

>>Quite a few NV demos use so many libs and structures and all that stuff, that I´m really unable to read / understand them.<<

let alone compile them without first spending a hour first farting around.

Originally posted by mattc:
for example, what if you want one unique object instead of per-derived-class duplicates?

I’m not sure what you’re trying to say here.


inheriting base classes virtually doesn’t work as it should (as msdn says) on visual c++ 6 sp5…

A lot of stuff doesn’t work as it should when your using vc++. It’s just stuff you have to be familliar with when working with a compiler.


on top of all this, the performance hit for late binding (invoking a virtual method that’s not pure virtual, like void foo() == 0; ) can be surprisingly high under some circumstances, so you don’t wan’t a possible performance hit on the renderer’s inner loop.

Well, you usually want to cache stuff in local variables before you hit your inner loop. Sometimes this is not possible. I’m not sure how looking up a vtable pointer will be slower than getting a member variable that is an enum and then calling a function based on this variable.

Using inheritence, the correct function is looked up implicitly. While using enums, the correct function is looked up explicitly.