NFUS reflection

Hallo,

I just installed (and of course played) the “need for speed underground” demo, and was quite impresse by the graphics.

The thing that most impresses me is all those reflections… the reflection of the environment on the street, and on the car, it looks quite realistic (much better than for example the water in unreal 2).

Well, my simple question is, how is this done? What technique is used?

Of course I know that this is an d3d game, but the general rendering techniques should be the same as with OpenGL I think. Also, I know that it cannot use dx9 pixel shaders as it runs on my dx8 gf4 ti .

Thanks
Jan

Simply by playing the demo, I would say they use a lot of off-screen rendering (opengl : pbuffers, render to texture etc) and then map it to the reflective object.

For the reflective road, they can render once the up-down inverted scenery (without the road), and the map it carefully to the road, only in some places according to the road alpha data.

For the cars, they probably have to render 6 views (like the faces of a cube) around the car, and then cube-map it using texenv and the like. There is an option in ‘video settings’ letting you choose the reflections update frequency, clearly showing it is done on independant renderings.

You know, even before dx9 compliant card you could have quite impressive ‘shaders’, by using multitexture, cube-mapping, and register combiners on gf3 and gf4. Look at Doom3 for example: http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/011088.html

[This message has been edited by ZbuffeR (edited 12-15-2003).]

sounds complicated (and like it would eat a lot of fps ), I already thought that for the reflection on the road, you would have to render the scene “upside down” and map this to the road (maybe in ortho mode?). I am working on a outdoor engine where you could race around a terrain which is about 3x3 kilometers, and as there is nothing to do at the moment for this project, I am thinking about how to improve the visual quality… one idea was a reflective road together with “rain” to make it look wet. Another idea is bump mapping. or maybe both? g

But the whole geometry is inside of display lists, so I guess I have to mess with vertex programs to get it working.

Thanks
Jan

Originally posted by JanHH:
But the whole geometry is inside of display lists, so I guess I have to mess with vertex programs to get it working.

You just have to do glScale(1.0,-1.0,1.0); before calling your dl and if there is no modelview matrix reset in it, it should be ok. Providing your road is not too bumpy of course.

It may not slow down too much as the reflection rendering can be of very low resolution, and your geometry is already in the card. If backface culling is enabled, you may have to reverse the frontfacing mode.

I found a simple demo with source wich uses textured dynamic reflection : http://www.geocities.com/dimi_christop/OGLDemos/ogldemos.html

[This message has been edited by ZbuffeR (edited 12-15-2003).]

The vertex program issue was related to the idea of using bump mapping/per pixel lighting. The bumps in the road seem to be a problem when doing reflections that way, again I have to admit that I have no idea how to deal with this (maybe use a really weird projection mode?). Have to think about it for some time, I think.

Hi

1st i have to thx RipTorn for some help

ok let’s go

what you need is:

NV_texture_env_combine4 or ATI_texture_env_combine3

what you want to do is:

from DXSDK

MODULATEALPHA_ADDCOLOR
Modulate the color of the second argument,
using the alpha of the first argument
then add the result to argument one.

Arg1.RGB + Arg1.A*Arg2.RGB

and thats what you wanna do in OGL

TMU0.RGB + TMU0.Alpha * TMU1.RGB

finaly

PrimaryColor * TMU0.RGB + TMU0.Alpha * TMU1.RGB

On TMU0 setup a RGBA diffuse texture with GL_MODULATE
On TMU1 setup a RGB sphere map (or cubemap) that is added to the diffuse texture on TMU0 using the alpha channel from TMU0 as a mask

BTW: UT2k call it CombineOperation -> CO_Add_With_Mask_Modulation

some code:

for texture unit 0:

glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);

glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PRIMARY_COLOR_EXT);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);

glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);

glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);

glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);

then, for texture unit 1:

for NV combine4

glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);

glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);

glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_ZERO);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_COLOR);

glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);

glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_PREVIOUS_EXT);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_SRC_ALPHA);

or for ATI combine3 (not tested)

glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE_ADD_ATI);

glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);

glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);

glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);

i think is will look like the road in NfSU

LB

thanks

now I have to solve how to create the map that contains the reflection.

diffuse texture (RGBA) has an alpha channel as mask made by Photoshop or some else
simple try it with b/W
were white is full reflection 1.0f and
black is no reflection on the diffuse texture

reflection texture is a shere or cubemap that
you can create static or dynamicly

LB

I came to the conclusion that maybe reflection would not be the right thing to improve visual quaility, as the terrain is quite flat and the road quite bumpy, so I guess it would not be a great improvement, considering the additional rendering costs.

At the moment it loos like this:
http://de.geocities.com/westphj2003/screenshot.jpg

not really dramatic as you can see .

I am looking for ways to make it look better, but the terrain is so dull that I run out of ideas… mabe shadowmaps (self-shadowing of the terrain) and bump mapping, for example to make the road look “wet” when it’s rainig, but I really guess that the main part would simply be better design…

Jan

strangely the link does not work when clicked on (at least on my computer), but does when typed in (or simply pushed “enter” with the cursor in the url edit field of the browser).

Originally posted by JanHH:
strangely the link does not work when clicked on (at least on my computer), but does when typed in (or simply pushed “enter” with the cursor in the url edit field of the browser).

Same for me (Win2000+MozillaFirebird).

Hey, your terrain is not so bad you know. Maybe more trees, or put them near the road. Can you use smoothed polys instead of flat ones ? Of course shadows would make it better, and maybe a more contrasted lighting (less ambiant/sun at lower angle).
Contrary to what you said, the road seem quite flat and the terrain more bumpy. Or is it the screenshot ?
And if you add telephone poles/ milestones/ barriers near the road, it will increase the speed sensation. Well it depends on the game, but you mentionned NFS:Underground
Just some ideas…

thanks

More (and better) trees is an idea, but I cannot change the place where they are, as this is not a fictive terrain but real world data (this is somewhere near Lübeck in Germany), and it’s not a game but the graphics modue of a scientifc driving simulation.

The polys are smoothed, depending on the angle, most of them are smoothd but sharp edges remain unsmoothed.

The problem with shadowing ist the size of the shadow map, the terrain is 2000 x 2000 meters, making a shadow map with the granularity of one meter 2048 x 2048 texels = 16 MB (with 32 bit RGBA format which is used for all textures), and this still looks crappy, shoud be about ten times finer, but this would take one hundred times the memory, which clearly is too much. Is there a way to use compressed textures so they would take REALLY less memory, not only the half or something but really much less?

The problem with the reflection I think is that you would hardly seen anything relfect on the street as the terrain is rather flat (the pic shows the bumpiest part of it), and as the road is not flat, it is rather complicated to render a reflection map by simply inversing geometry (at least, I think so ). So I guess, bump mapping (with specular) would be more effectify, and per-pixel-lighting would make it possible to do a night situation with the car lights illuminating the terrain.

Of course adding telephone poles/ milestones/ barriers would increase the visuall effect dramatically but as I said, I am already very sure that the main part is an issue of graphics design and not programming, and I am not really good at this, nor do I have the time, nor am I getting paid for it .

Jan

so many typos… sorry

The fact that this is a real terrain makes it possible to compare the graphics with the real world scenario but this ends up being rather depressing.

Jan

Ahh… The inherent complexity of nature…

Well, I will try to give more ‘programming’ ideas :

  • slight blueish fog/haze (to add depth)
  • anisotropic texture filtering (THE most useful with terrain engines) :
  float aniso_level;
  glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,&aniso_level);
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE );
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso_level );
  • mix different textures scales. From the screenshot, it looks like 1 detail texture and 1 very large texture. More in-between maybe, with more color variations ?
  • use volume shadows instead of shadow map if you have few polys and large terrain scale. Or just vertex colors, processed offline with high-res shadow maps ?
  • add fractal detail to your real world 3d data, it is often both nicer and not too far from reality (ala Vistapro, etc)
  • more atmospheric effects like rain, low fog in some places only, moving-clouds shadows on the terrain, wind making the trees moving
  • maybe a slight full scene glare or glow ? (copytexsub the whole screen or use RTT, and add as blurry level mipmapped texture on top).
    Hope it helps.

And if the terrain is so flat, just reflect the blurry sky texture, it will be much easier.

Now I added reflection to the water, it looks much better than before I think.

Some screenshots:
http://de.geocities.com/westphj2003/refl.html

Yeah, it rocks !
Really, it does bring more life to your terrain.

I find the reflection texture a bit ‘aliased’ though, maybe using a lower res mipmap would help : GL_EXT_texture_lod_bias. But it is a matter of taste.

Maybe you can randomize a bit the texture coordinates and animate them, to simulate reflection distorted by the water waves.

What is the point with the teapot ? A testbed for cubemapped reflection maybe ?

Keep up the good work !

thanks

The program has two modes, cockpit view and view from the outside at the simulated vehicle, and the teapot marks the place where the simulated vehicle normally is (as the program doesn’t run in “real simulation mod”, but simply flyby/demo mode).

The reflection is in fact too flat, no refraction at all, this looks rahter unrealistic, biased by the fact that the water itself is rather wavy (look at http://de.geocities.com/westphj2003/water.html ). But I did not find out by now how to solve this, the reflection is simply one orthgonal quad with the upside-down terrain as texture. Maybe as you said tesselate this and shift the texture coordinates randomly, but the, the texture coordinate shift would not have much to do with the waves the water has.

Right now I am working on the sky reflecting on the street, masked by an alpha texture (perlin noise) to make the road look wet.

Jan