3 textures with DOT3 - 1 pass ?

Started by
16 comments, last by Ilici 20 years, 6 months ago
LOL! Well, I''m glad that''s fixed.

I''m not sure about the ambient light, though. . . With only three texture units, you''re at the limit already, and I''m guessing that adding another multitexturing stage would require yet another texture unit. It''s likely that you''d have to do ambient light in a second pass.
-Ostsol
Advertisement
And how would i do it with another pass?

I''m guessing a blank white texture blended into the frame buffer. But how should it be blended (what equation)?

[ My Site ]
''I wish life was not so short,'' he thought. ''Languages take such a time, and so do all the things one wants to know about.'' - J.R.R Tolkien
/*ilici*/
Well, I suppose you could just render a quad the colour of your ambient light over everything. . . That''s not something I''ve ever done before (actually, I''m using fragment programs almost all the time, now), but I suppose it could work if you use a blend factor of (GL_DST_COLOR, GL_ONE). Shouldn''t using a standard OpenGL fixed function ambient light work as well, though?
-Ostsol
Using a fixed function will mean that i have to enable lighting which i certanly do not want. And even if I did, because the DOT3 texture is black applying color to the vertices wont change anything.

I discovered that there is some sort of artifact - the DOT3 texture does not look right:

the resulting terrain for light = (0, 1, 0)

the heightmap:

the normalmap:



[ My Site ]
'I wish life was not so short,' he thought. 'Languages take such a time, and so do all the things one wants to know about.' - J.R.R Tolkien
/*ilici*/

[edited by - Ilici on October 9, 2003 2:08:59 PM]
What did you use to generate that normalmap? When I put your heightmap through ATI''s own little utility, I get an entirely different looking normalmap. . .
-Ostsol
I used my own routine for generating it. Here it is:

It converts a 2^n + 1 height map to 2^n normal map by averaging the normals of the four corners of the pixel. It also loops the texture (when i = size -> i = 0)
	int i, j, ci, cj;	CVector3 vSum, v1, v2, v3;	Img.Create(ImgSize - 1, ImgSize - 1, 3);	CVector3* Normals;	Normals = new CVector3[ImgSize * ImgSize];	for (i = 0; i < ImgSize; i++)	{		for (j = 0; j < ImgSize; j++)		{			vSum = CVector3(0, 0, 0);			v1 = CVector3(i, SrcImg[i * ImgSize + j], j);			ci = i - 1;	cj = j; ci = abs(ci % ImgSize); cj = abs(cj % ImgSize);			v2 = CVector3(ci, SrcImg[ci * ImgSize + cj], cj);			ci = i; cj = j + 1; ci = abs(ci % ImgSize); cj = abs(cj % ImgSize);			v3 = CVector3(ci, SrcImg[ci * ImgSize + cj], cj);			vSum = vSum + Cross(v1 - v2, v1 - v3);			ci = i;	cj = j + 1; ci = abs(ci % ImgSize); cj = abs(cj % ImgSize);			v2 = CVector3(ci, SrcImg[ci * ImgSize + cj], cj);			ci = i + 1; cj = j; ci = abs(ci % ImgSize); cj = abs(cj % ImgSize);			v3 = CVector3(ci, SrcImg[ci * ImgSize + cj], cj);			vSum = vSum + Cross(v1 - v2, v1 - v3);			ci = i + 1;	cj = j; ci = abs(ci % ImgSize); cj = abs(cj % ImgSize);			v2 = CVector3(ci, SrcImg[ci * ImgSize + cj], cj);			ci = i; cj = j - 1; ci = abs(ci % ImgSize); cj = abs(cj % ImgSize);			v3 = CVector3(ci, SrcImg[ci * ImgSize + cj], cj);			vSum = vSum + Cross(v1 - v2, v1 - v3);			ci = i;	cj = j - 1; ci = abs(ci % ImgSize); cj = abs(cj % ImgSize);			v2 = CVector3(ci, SrcImg[ci * ImgSize + cj], cj);			ci = i - 1; cj = j; ci = abs(ci % ImgSize); cj = abs(cj % ImgSize);			v3 = CVector3(ci, SrcImg[ci * ImgSize + cj], cj);			vSum = vSum + Cross(v2 - v1, v3 - v1);						vSum = Normalize(vSum);							Normals[i * ImgSize + j] = vSum;		}	}	int Size = ImgSize - 1;	for (i = 0; i < Size; i++)	{		for (j = 0; j < Size; j++)		{			vSum = Normals[i * ImgSize + j] + 				   Normals[i * ImgSize + j + 1] + 				   Normals[(i + 1) * ImgSize + j] + 				   Normals[(i + 1) * ImgSize + j + 1];			vSum = Normalize(vSum);						Img.PutPixel((i * Size + j) * 3    ,(BYTE)(vSum.x * 127.0f + 128));			Img.PutPixel((i * Size + j) * 3 + 1,(BYTE)(vSum.y * 127.0f + 128));			Img.PutPixel((i * Size + j) * 3 + 2,(BYTE)(vSum.z * 127.0f + 128));		}	}	delete [] Normals;	Img.SaveToFile("data\\normal.bmp");	if (!built)	{		texnum = 0;		while (GL.IsTexture(texnum)) texnum++;		GL.GenTextures(1, &texnum);	}	GL.BindTexture(GL_TEXTURE_2D, texnum);	GL.BuildMipmaps2D(GL_TEXTURE_2D, GL_RGB8, Size, Size, GL_RGB, GL_UNSIGNED_BYTE, Img.GetDataPointer());	GL.TextureParam(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);	GL.TextureParam(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	GL.TextureParam(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);	GL.TextureParam(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


I was thinking the same - the normals are screwed up - and i dont have that utility for generating normals, but i''ll search for it.


[ My Site ]
''I wish life was not so short,'' he thought. ''Languages take such a time, and so do all the things one wants to know about.'' - J.R.R Tolkien
/*ilici*/
Here''s a link to ATI''s tools site:

http://www.ati.com/developer/tools.html

The one I used is called NormalMapper.
-Ostsol
I've used that and it works nice now. Thnx a lot Ostsol!

The DOT3, when the angle is 90 or more results always to 0 so to get a nice effect the angle must not be allowed to go above ~90.
Also, specifing a material color (eg: glColor4f(1.0f, 0.0f, 0.0f, 0.0f) does not affect the DOT3 op as it would without it because the result is not modulated with the primary color

I think i'll have to make my own dynamic lightmap for the terrain because without pixel shaders the DOT3 is not satisfactory. I'm gonna use a smaller size normalmap to do the calculations and then load it as a texture.


EDIT: just implemented my own dot3 function, for ambient light just clamp the values below to the light value.


[ My Site ]
'I wish life was not so short,' he thought. 'Languages take such a time, and so do all the things one wants to know about.' - J.R.R Tolkien
/*ilici*/

[edited by - Ilici on October 11, 2003 7:32:26 AM]

This topic is closed to new replies.

Advertisement