PDA

View Full Version : outdoor beautifullyizing



HamsterofDeath
01-16-2003, 02:52 AM
ok...i want to know everything about things i could use to make my outdoor-game look cool (at the moment, i got a plasma-morphing sun, day/night shift, dynamic height textures, nice trees...)

i can't use a lightmap because the moon / sun circles around my world, so the lighting is dynamic

weak points :
my main texture is very blurry, so i'm using a detail texture to fix this. but the same detail texture EVERYWHERE doesn't look really good...any idea how i can blend detail textures from one to another ? i don't want a sharp edge between 2 detail textures to be visible and ugly...

i want to add some details like a path or something, or blood after some monsters have been killed ^^, but the main texture is not high-resd enough. how can i fix this ? putting a lot of high-res textures across the whole landscape needs about 32-64 mb of ram...too much...

MickeyMouse
01-16-2003, 03:19 AM
What I've seen in some games having detailful terrain, with patches, grass etc, all together is just a collection of textures e.g.:
-grass texture
-patch texture
-grass/patch texture combinations for all cases like grass being only on the edge etc..

Doing this in NxN grid constraints a bit possible layouts of e.g.patches on he grass.

But you may try terrain without strict texture to grid wrapping, so your patches will be allowed to have arbitrary directions.

JustHanging
01-16-2003, 03:23 AM
Have you seen the grass discussion here?
http://www.opengl.org/discussion_boards/ubb/Forum2/HTML/011397.html
There are a couple of demos there with very unclear explanations. But I think it might add to your outdoor beauty if you are running for perfection.

A good terrain texturing article can be found at
http://www.delphi3d.net/articles/viewarticle.php?article=terraintex.htm

Once you've read that, you should know how to make those paths with their own detail texture. Altough I use a general purpose detail texture and a low-res colormap on my terrain, it looks quite good too.

Blood splats and such are best made with decals.

-Ilkka

HamsterofDeath
01-16-2003, 04:40 AM
thx for the links...
especially the second one...
i don't understand the code (maybe i should read it again) but is it right that u basically draw all 3 or 4 detail textures and just change the opacity by enabling glblend, and let ogl interpolate between the different points of the quads/triangles ?

if yes, i have to tell ogl for every point what colors it should use...is it possible to do this by a vertex array ? (i'm asking because display lists don't save multitexture commands)

M/\dm/\n
01-16-2003, 05:23 AM
Don't save multitexture commands http://www.opengl.org/discussion_boards/ubb/eek.gif
Worked for me until now http://www.opengl.org/discussion_boards/ubb/eek.gif
Although I experienced some problems with intel built in graphic boards.
But not with TNT2 or GF2GTS http://www.opengl.org/discussion_boards/ubb/smile.gif


[This message has been edited by M/\dm/\n (edited 01-16-2003).]

HamsterofDeath
01-16-2003, 06:02 AM
glmultitextcoordarb1 or what the name is never was saved in my displaylists... maybe it's because i'm using gl4java...

JustHanging
01-17-2003, 03:00 AM
Yes, you can use vertex arrays for that. You could also put the weights in some low-res textures, I think that's what the article is about. A simple multipass version would go like this:

-render terrain with color=weightTex[1]*detailTex[1]
-set depth test to GL_EQUAL and blending to GL_ONE, GL_ONE
-render other layers with color = weightTex[n]*detailTex[n]

Of course you should, for each pass other than the first, only render those triangles that have at least some of the detail texture in question on them. The technique works best, if the weights for every texel add up to 1.

-Ilkka

HamsterofDeath
01-19-2003, 06:22 AM
10 minutes ago, i had the idea to combine the low-res texture with an alpha channel, draw the first detail texture, and use a third texture unit to draw a second detail texture, which i set to gl_dst_alpha,gl_one

will this work ?
would increase the peformance i think because i would not have to use any additional commands...

JustHanging
01-19-2003, 08:22 AM
Yes, the idea is correct, but I think you're confusing something... At least me.

You can get two detail textures with 3 texture units, but you can't use blending for that since it all happens in one pass. You have to do it in texture enviroments, GL_TEX_ENV_COMBINE should be enough. If I recall correctly the article describes this. Please note, however, that many cards, including GF1 and GF2 (I may be wrong about the 2), only have two texture units.

-Ilkka

HamsterofDeath
01-19-2003, 08:52 AM
if i use GL_TEX_ENV_COMBINE, the detail textures are drawn everywhere... i want one to blend into another, dependend on their height

HamsterofDeath
01-19-2003, 09:46 AM
this seems to do everything
can anyone explain how the code does what it does ?
i know what vertex arrays are and how to use them - my problem are the gltexenvi-commands...

procedure TTTForm.ConfigureSinglePass;
begin

// Configure OpenGL for the single-pass rendering.

glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].R);

glClientActiveTextureARB(GL_TEXTURE3_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U2);

glClientActiveTextureARB(GL_TEXTURE2_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U1);

glClientActiveTextureARB(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U1);

glClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U1);

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].X);

// Texture 3: previous * L
glActiveTextureARB(GL_TEXTURE3_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, L);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

// Texture 2: lerp(C0.alpha, previous, T3)
glActiveTextureARB(GL_TEXTURE2_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, T3);

glMatrixMode(GL_TEXTURE);
glScalef(0.2, 0.2, 0);
glMatrixMode(GL_MODELVIEW);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);

// Texture 1: lerp(C0.rgb, T1, T2)
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, T1);

glMatrixMode(GL_TEXTURE);
glScalef(0.2, 0.2, 0);
glMatrixMode(GL_MODELVIEW);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);

// Texture 0: T1
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, T2);

glMatrixMode(GL_TEXTURE);
glScalef(0.2, 0.2, 0);
glMatrixMode(GL_MODELVIEW);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

end;

HamsterofDeath
01-20-2003, 12:30 AM
plz help ....
my engine would be godlike if i would understand this...

JustHanging
01-20-2003, 01:22 AM
You can read about GL_TEX_ENV_COMBINE from opengl specs. In general, the idea is following:

You have some number of texture units, each of which can have a texture bound. In addition with GL_TEX_ENV_COMBINE you can define each unit's outcome as a funcion based on the unit's texture, outcome of the previous unit, primary color and a constant. The outcome of the last unit is the one that goes to screen, possibly through blending.

The available functions are replace, add, add signed, modulate and lerp (linear interpolation). Different functions can be assigned to color and alpha channels.

In your code units 0-2 have different detail textures in them and unit 3 is propably a lightmap. Primary colors (as in glColorPointer) contain the interpolation factors, one in color channel, one in alpha.

Unit 0 just outputs it's texture color. Unit 1 interpolates it with it's own texture using primary color as interpolation factor. Unit 2 takes this result and interpolates it with the third texture, this time using primary alpha as the interpolation factor. Finally the result is modulated with the lightmap in unit 3.

I hope that was clear enough, I don't exactly marvel at explaining things.

-Ilkka

HamsterofDeath
01-20-2003, 01:37 AM
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
-> i'm using simple detailtexturing so no problem to understand this one

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);
-> i think this one tells opengl how to combine the new texture with the other one.

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
-> i guess this means : do something with the previous texture unit, and something with the color of the texture binded to unit 0.

glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
-> ???

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
-> ???

glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
-> ???

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR_ARB);
-> ???

glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
-> ???

HamsterofDeath
01-20-2003, 02:05 AM
ok got it !
found a site that explains multitexturing perfectly

HamsterofDeath
01-20-2003, 03:03 AM
but how to use GL_ARB_texture_env_crossbar
just replace GL_texture_env ?

JustHanging
01-20-2003, 03:19 AM
No, you replace the source (for example GL_PREVIOUS_ARB) with GL_TEXTURE<n>_ARB where <n> is the number of the texture unit. But nvidia doesn't support crossbar on any cards I think, so make sure you have a fallback if you ever want to release whatever you're doing.

-Ilkka

HamsterofDeath
01-20-2003, 04:01 AM
nvidia has its own extension doing the same i think...

HamsterofDeath
01-20-2003, 01:16 PM
after some hard work, i got 2 detail-textures combined. but i absolutely don't understand the calculation of the coverage factors...

can anyone help me?

HamsterofDeath
01-20-2003, 01:21 PM
thats the code :

a1 and a2 are the coverage factors..
but how are they calculated ? there are no comments in the code *grr*


procedure Color(x, y: Integer);
var
h, s: Single;
w1, w2, w3, l: Single;
a1, a2: Single;
cl: TColor;
begin

// Encode the blending weights for this heightmap pixel in an RGBA color.

if coverage = nil then
begin
h := map[x,y]/255;
s := CalcSlope(x, y);

cl := LUT.Canvas.Pixels[Trunc(h*LUT.Width), LUT.Height - 1 - Trunc(s*LUT.Height)];
w1 := (cl mod $100) / 255;
w2 := ((cl div $100) mod $100) / 255;
w3 := (cl div $10000) / 255;

l := sqrt(w1*w1 + w2*w2 + w3*w3);
w1 := w1/l;
w2 := w2/l;
w3 := w3/l;

bmp.Canvas.Pixels[x,y] := RGB(Trunc(w1*255), Trunc(w2*255), Trunc(w3*255));
end
else begin
cl := coverage.Canvas.Pixels[x,y];
w1 := (cl mod $100) / 255;
// w2 := ((cl div $100) mod $100) / 255;
w3 := (cl div $10000) / 255;
end;

a1 := w1/(1-w3);
a2 := 1 - w3;

va[y*mW + x].R := a1;
va[y*mW + x].G := a1;
va[y*mW + x].B := a1;
va[y*mW + x].A := a2;
end;

JustHanging
01-21-2003, 02:34 AM
That code is quite Delphi specific, no wonder you don't understand it.

The coverage factors are nothing but layer opacities for the detail texture layers. How you calculate them depends on the result you want to achieve. For total control, you can just paint them in a paint program, or alternatively you can generate them procedurally using vertex height and slope.

What this code does, is that if you have specified an explicit coverage map, it just reads it to the coverage factors. The coverages are encoded in an image with different coverages being in different color components.

If the coverage map isn't there, the values are calculated procedurally. For this, there's a look-up table (another image) which has, in a way, height as x-axis and slope as y. So when you get the color at point (height, slope), you get the appropriate coverage values. For slope, you can use the y-component of the vertex normal.

-Ilkka

Mazy
01-21-2003, 04:51 AM
Clearification : Whilst nVidia doenst support the crossbar extension, it supports the functionallity of it in most ways, the only thing stopping them to expose this extension in the extensionlist is the behaivor of an unbound texture unit. So it you use it to access only TMUs with bounded textures you can rely on nvidias driver to work.
When the function was moved into the core the result if querying an unbound units value is specifyed as undefined and therefor works well. All this is in the openglExtensionSpec.pdf from nVidia

HamsterofDeath
01-21-2003, 09:30 AM
---
the problem was not that the code is delphi (i can code in delphi, too) specific, the problem was, that i dont know what to use here :
glcolor4f(x,x,x,y);
if i want to set x to 40% and y to 60%
---
(a few google searches later)
----

i got the formula...
but...
i never see my second detail texture...
at the top of my mountains is no detail texture, and the bottom there is ONLY my detail texture...

i tried some values (formula :
coltex1 = 0.6f,
coltex3 = 0.4f,
cov1=coltex1/(1-coltex3),
cov2=1-coltex3;
cov1 = coltex1/(1-coltex3);
cov2 = 1-coltex3;
glColor4f(cov1,cov1,cov1,cov2);
)

but i can only control the factors of the main texture and the second detail texture...

HamsterofDeath
01-21-2003, 10:07 AM
just solved the problem !

coverage factor 3 at 0,5f means texture 2 is automatically at 1-cov factor 3

JustHanging
01-21-2003, 11:39 PM
Good for you. Hey, how about some screenshot, after all this it'd be nice to see what you've got together.

-Ilkka

HamsterofDeath
01-22-2003, 02:43 AM
i'll upload one in 6 hours...

HamsterofDeath
01-22-2003, 09:42 AM
screenshots available at :
ftp://hamsterdevelopment.homeftp.org -> public (thats my computer^^, so not on 24h/day)

the highter the number the newer the shot

here you find a demo-shot : http://de.geocities.com/vegankatze/screenshot10.jpg

-> screenshot is uploaded, but the server seems to be ****ty. geocities = bad, right ?

anyone has webspace for me ?


[This message has been edited by HamsterofDeath (edited 01-22-2003).]

[This message has been edited by HamsterofDeath (edited 01-22-2003).]

JustHanging
01-23-2003, 02:22 AM
So that's a plasma-morphing sun... No, it looks good, keep it up!

A little advice on those trees though, if you don't mind. You're on the right track, especially with those tall trees, but you have to take care of a couple of things to make the illusion perfect.

First, you should never be able to see a straight polygon edge in a tree. It's easy to fix this, just extrude each such edge to a polygon and texture it to create a better silhouette.

The slightly harder problem are the polygons that are viewed from steep angles. You can't totally get rid of these, but you do have a pretty good control over which directions they are seen from. In an 1st person kind of game, which you seem to be creating, the trees are typically viewed from the same level or a little bit below. So then you construct the trees so that the polygons become "buggy" mostly when viewed from above.

You can look at the trees in my grass demo to see how I managed these things. The trees are normal polygon meshes, aroung 50 faces each.

-Ilkka

Miguel_dup1
01-23-2003, 05:09 AM
I have written a demo that uses three textures blended together. I have my server down right now, but I will post the link later so that you can download it. http://www.opengl.org/discussion_boards/ubb/wink.gif

Miguel Castillo.

HamsterofDeath
01-23-2003, 10:36 AM
mhh grrmrmorf *hate*
my coverage factors are stupid ! they hide my third texture. i can interpolate between 2 but the third simply dissapears.

why can't there be a simple function in the article calculating them ?


[This message has been edited by HamsterofDeath (edited 01-23-2003).]

i got 3 factors, one of them is always 0.
how to get a1 and a2 ?

[This message has been edited by HamsterofDeath (edited 01-23-2003).]

hm looks like i got the solution, just by randomly trying out everything.
bruteforce always wins. it's only a matter of time.

[This message has been edited by HamsterofDeath (edited 01-23-2003).]

HamsterofDeath
01-23-2003, 11:53 AM
ok, here is my hopeyfully last problem :
if i want to draw only the first texture (the lowest) glcolor has to be 1,1,1,0 right ?
for the second, it has to be 0,0,0,1, and for the last 0,0,0,0.

right ? (ignore the order - are the values correct for only displaying a single texture ?)

the problem is that one of the textures is nearly invisible...no matter wich of the 3 settings i try...

[This message has been edited by HamsterofDeath (edited 01-23-2003).]

can anyone help me ? i'm dying.

[This message has been edited by HamsterofDeath (edited 01-23-2003).]

HEEEEEEEEEEEEEEELP

the coverage factors aren't calculated anywhere in the code !!

the article is lying !

[This message has been edited by HamsterofDeath (edited 01-23-2003).]

HamsterofDeath
01-23-2003, 10:27 PM
that s how to calculate the coverage factors :

---
So, how do you compute alpha and beta for a vertex from its texture weights? With some math you get that alpha = c0/(1-c2), beta = 1-c2 if c2<1 and beta = 0 and for alpha you can choose any value if c2=1. Isn't it cool? http://www.opengl.org/discussion_boards/ubb/smile.gif
---

as i expected, i don't understand the most important sentence.

alpha = c0/(1-c2), beta = 1-c2 if c2<1 and beta = 0 and for alpha you can choose any value if c2=1.

so beta is 1-c2 and beta is 0 ?
???

i just want a function that need 3 floats (c0,c1,c2) and gives me 2 floats (rgb,alpha)

is there nobody who got one ?

HamsterofDeath
01-24-2003, 02:23 PM
code: for (int x =0;x<size;x++)
{
for (int y = 0;y<size;y++)
{
if (map[x+size*y] <=128)
{
float percentB = (float)(map[x+size*y])/128f;
System.out.println(map[x+size*y]);
float percentC = 0;
float percentA = 1-percentB;
float[] cov = calculateCoverage(percentA,percentB,percentC);
Color color = new Color(cov[0],cov[1],0);
covertex.setRGB(x,size-1-y,color.getRGB());
} else
{
float percentA = 0;
float percentC = (float)(map[x+size*y]-128f)/128f;
float percentB = 1-percentC;
float[] cov = calculateCoverage(percentA,percentB,percentC);
Color color = new Color(cov[0],cov[1],0);
covertex.setRGB(x,size-y-1,color.getRGB());
}
}
}

the code is java, but it's easy to guess what it's doing. i tried to fill in 0,0,1 / 0,1,0 and 1,0,0 for percenta->c, and everything worked fine. i saw the textures i wanted to see.

so, the bug must be in my weight-calculation. but where ?
map[..] is my heightmap. the lowest point is 0, the highest is 256.

so for every point below or equal 128, i use height / 128 as the percentB-weight, and 1-percentB = percentA

for every point highter than 128, i subtract 128, then divide by 128 to get the percentC-weight. percentB then is 1-percentB.

where is the error ?

here is my coverage-calculaton :

private float[] calculateCoverage(float c1,float c2,float c3)
{
if (c1+c2+c3 != 1 &#0124; &#0124; c1 < 0 &#0124; &#0124; c2 < 0 &#0124; &#0124; c3 < 0 &#0124; &#0124; c1 > 1 &#0124; &#0124; c2 > 2 &#0124; &#0124; c3 > 1)
{
return null;
} else
{
float[] cov= new float[2];
cov[0] = c1/(1-c3);
cov[1] = 1-c3;
return cov;
}
}


[This message has been edited by HamsterofDeath (edited 01-24-2003).]

JustHanging
01-25-2003, 01:52 AM
Sorry, I didn't take the effort to go through all the code you posted, I think the functions you need are:

alpha = c3
rgb = c2/(c1+c2)

That is assuming you use the combiner setup you posted earlier. If c1+c2=0, rgb doesn't matter, just set it to some value like 1.

-Ilkka

HamsterofDeath
01-25-2003, 07:32 AM
I LOVE YOU !
it works

HamsterofDeath
01-29-2003, 09:08 AM
how to change the gltexenvi-commands to make the texture be completely transparent at alpha 0 and completely opaque at alpha 1 ?