how to use bump mapping?

Post Reply
copete23
Posts: 2
Joined: Wed Oct 21, 2009 12:49 am

how to use bump mapping?

Post by copete23 » Wed Oct 21, 2009 12:55 am

Hello, I would use bump mapping on wii, but do not know how the technique works in GX :cry: , Can anyone explain how to use bump mapping on wii?

:cry: i don`t know how do that :?:

thanks:)

Samson
Posts: 35
Joined: Mon May 19, 2008 8:05 am

Re: how to use bump mapping?

Post by Samson » Sun Oct 25, 2009 10:19 am

There are three ways to do bumpmapping on Wii:
- emboss mapping: Put a displacement map into two texture channels and use GX_TG_BUMP0 on the second texgen to distort the texture coordinates based on the light position. In the TEV subtract the second texture from the first texture.
-- pro: cheap'n'easy
-- con: only a single light source
- Object space Environment-Mapped Bumpmapping (called XYZ bumpmapping in the docs): you need a object space normal map and an environment map (only a hemisphere as seen from the camera). You need to render the lights into the environment map in a separate pass, the normal map goes into the indirect texture unit, and the environment map goes into the tev. The indirect texture matrix needs to be set up to rotate the normal into light space.
-- pro: better quality than emboss mapping, multiple light sources and even advanced lighting effects (blinn, fresnel)
-- con: more expensive than emboss lighting, lighting is relative to the environment map which should be calculated from the object centre. As a result local lights may look slightly wrong.
- Tangent space Environment-Mapped Bumpmapping (ST bumpmapping in the docs): similar to the one above you need a normal map and an environment, but the normals are in tangent space not in object space. You use a mechanism to feed the tangent space components (normal, binormal, tangent) from the TEV into the indirect texture unit, to project the bump normals from tangent space into light space. I never got that working right, but that may be incomplete documentation.
-- pro: in addition to the object space EMBM it allows deformed meshes (animated characters)
-- con: you'll burn 3 TEV stages to pass the tangent space into the indirect texture unit.

I did post a demo some time ago (http://devkitpro.org/viewtopic.php?f=7&t=165), but I can't find it right now.

copete23
Posts: 2
Joined: Wed Oct 21, 2009 12:49 am

Re: how to use bump mapping?

Post by copete23 » Mon Oct 26, 2009 1:08 am

Samson, thank you very much for answering, I have been experimenting with XYZ bumpmapped and ST bumpmapped, but do not get anything :cry:, if you find your example, or if you could show me some example here, I'd be very grateful :)

i`ll try with the displacement map.

thanks!

Samson
Posts: 35
Joined: Mon May 19, 2008 8:05 am

Re: how to use bump mapping?

Post by Samson » Wed Oct 28, 2009 11:54 pm

I re-uploaded it at http://bin.mypage.sk/FILES/bumpmap_demo.zip , but it may expire in a few days. It would be great if anyone has a chance to permanently host it.
Disclaimers:
- This was written for Game Cube, so you may need to do changes to run it on Wii. All the TEV setup should be identical.
- I just zipped up the development directory, so I can't say if this is the latest version or runs in this form at all - I used to use a laptop for GC hacking, but the display of that machine is dead.
- as I said in the post, I cheated a lot in the way as you can't rotate the model or the camera. To do this properly you'll need to build appropriate matrices.
- oh, and I didn't get the tangent space transform to work. I probably did something wrong.

DRS
Posts: 11
Joined: Fri Nov 06, 2009 1:50 pm

Re: how to use bump mapping?

Post by DRS » Fri Nov 06, 2009 3:00 pm

I'm doing actual normal mapping (not emboss bump) by adding 2D normals to 2D offsets. But even then you've got several methods to provide the data to the HW.

Assuming you have read the emboss mapping patent, the easiest and most fast method is as follows:
* Create a light bulb texture. Note that the bulb's origin is at 0,0 in the texture, so you can just take one quadrant and mirror. It is required that the bulb's radius is 1/8th of the texture size (so if you create a 64x64 texture, the bulb's radius can only be 8 pixels, which BTW results in only 8 intensity shades)
* Setup vtx desc

Code: Select all

	GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
	GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_NBT, GX_NRM_NBT3, GX_F32, 0);
	GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); // normal map
* Add normal, tangent and bitangent to vertex data (provide them as GX_Normal3f32 in your vertex data). For this example you must scale tangent and bitangent to 1/8 of the unit lenght.

Code: Select all

	GX_Position3f32(-1.0f,-1.0f, 0.0f);
	GX_Normal3f32  (   0.0f,   0.0f,  1.0f);
	GX_Normal3f32  (  0.125f,   0.0f,  0.0f);
	GX_Normal3f32  (   0.0f,  0.125f,  0.0f);
	GX_TexCoord2f32(0.0f,1.0f);
* Setup a HW light (see examples in devkitpro)
* Setup a texture coordinate that always renders to (0,0) (you can use a null texmtx)

Code: Select all

	Mtx nullMtx = 
		{{ 0.0f,  0.0f,  0.0f,  0.0f},
		 { 0.0f,  0.0f,  0.0f,  0.0f},
		 { 0.0f,  0.0f,  0.0f,  0.0f}};
	GX_LoadTexMtxImm(nullMtx, GX_TEXMTX0, GX_MTX3x4);
	GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); // normal map
	GX_SetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0); // (0,0) 
* Setup a bumped coordinate based on the (0,0) coordinate and your HW light (setup the number of texgens to the proper value!!!)

Code: Select all

	GX_SetTexCoordGen(GX_TEXCOORD2, GX_TG_BUMP0, GX_TG_TEXCOORD1, GX_IDENTITY);
* Setup a indirect stage to read normal map. Note: up to now I have been using RGB565 as normal map format. In that case, the indirect unit can only read Green and Blue color channels. So, when you use this format you MUST convert your RGB normalmaps so that the blue channel contains the normal's X value and the green channel contains the Y value. The Z value is not required since this technique is based on a 2D calculation. I haven't tried RGB8 format yet, since I wasn't aware of the data order at that time.

Code: Select all

	GX_SetIndTexOrder(GX_INDTEXSTAGE0,GX_TEXCOORD0,GX_TEXMAP0);
	GX_SetIndTexCoordScale(GX_INDTEXSTAGE0,GX_ITS_1,GX_ITS_1); // normal map texture scale 1:1

	// setup indirect unit for tev stage 0 (for some reason I get a ABGR triplet, so transforms are done on normal map's B and G components)
	f32 offset_mtx[2][3] = {
	    {  0.0f, -0.125f,    0.0f}, // B -> horizontal coordinate (s)
	    {  0.0f,    0.0f, -0.125f}  // G -> vertical coordinate (t)
	};
		
	GX_SetNumIndStages(1);
	GX_SetIndTexMatrix(GX_ITM_0, offset_mtx, 0);
* Setup the indirect stage to add the bumped coordinate

Code: Select all

	GX_SetTevIndirect(
		tevstage, // tevstage 0 is used to combine normal map and lightmap
		GX_INDTEXSTAGE0, // ind stage is used to read normal map
		GX_ITF_8, // texture format 8 bits per channel
		GX_ITB_STU, // use bias on s and t channels (red and green and blue)
		GX_ITM_0, // use 3x2 matrix 0
		GX_ITW_OFF, // do not use texture wrapping
		GX_ITW_OFF, // do not use texture wrapping
		GX_FALSE, // don't add in previous coordinates
		GX_FALSE, // don't use mipmap stuff
		GX_ITBA_OFF // don't use bump alpha
	); 
* setup tevstage to use the resulting indirect texture coordinates to lookup the light bulb texture. This actually determines the light intensity.

Code: Select all

	GX_SetTevKColorSel(tevstage, GX_TEV_KCSEL_1_8); // ambient intensity
	GX_SetTevColorIn(tevstage, GX_CC_ZERO, GX_CC_TEXC, GX_CC_ONE, GX_CC_KONST);
	GX_SetTevColorOp(tevstage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
	GX_SetTevOrder(tevstage, GX_TEXCOORD2, GX_TEXMAP1, GX_COLORNULL);
* Bind lightmap texture to TEXMAP1 and normalmap to TEXMAP0
* Add a stage that multiplies TEVPREV with material texture. You can SCALE the value by 2 to create bright lighting. Don't forget to set the proper number of tevstages

This is about it. If you continue thinking in this line it gets obvious that you can also add reflection/specular by adding an additional stage. You can also add an extra stage to perform backface culling from the light's point of view.

However, a disadvantage of using bump coordinates is that you get artifacts at T junctions. To solve that, you can use DTT to project the light's position to the polygon and use those values (a bit harder and requires a few CPU cycles).

have fun!

Edit: forgot about setting the normal mtx before you start sending vertex data:

Code: Select all

	GX_LoadNrmMtxImm(modelview, GX_PNMTX0);
	GX_SetCurrentMtx(GX_PNMTX0);

Samson
Posts: 35
Joined: Mon May 19, 2008 8:05 am

Re: how to use bump mapping?

Post by Samson » Tue Nov 10, 2009 8:12 am

That's quite a neat technique! I've got to try that sometime.

DRS
Posts: 11
Joined: Fri Nov 06, 2009 1:50 pm

Re: how to use bump mapping?

Post by DRS » Sat Dec 19, 2009 7:04 pm

Thanks! Though I'm a bit confused how to compute the normal mtx. I'd say modelview minus the translation. I'm not sure, but I suppose that can be achieved by applying mtxinverse, mtxtranspose and a mtx inverse. But doing that makes the bumps hard to see. Any ideas?

Anyway, I'm implementing this and some other techniques in Quake Wii which currently gives results such as this:

Image

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest