Game Development Community

Waterblocks: submergeTexture0 and submergeTexture1

by Edward F. Maurina III · in Torque Game Engine · 03/27/2004 (3:11 pm) · 23 replies

Hello. This is a quicky. I'm clear on the purpose and use of the various textures for water, excluding these two:

submergeTexture0
submergeTexture1

If anyone can give me a definitive description of their purpose and how to use them, I would surely appreciate it.

Thanks,

[HOW]EdM


PS - I already gather it has something to do with the camera being under water, but I really want to know where I should be seeing these textures and what physical effect they represent. Yes, I'm looking through the code, but I'm still unclear...

:)
Page «Previous 1 2
#1
03/27/2004 (5:40 pm)
Hmm, me neither. Do tell if you find out. ;)
#2
03/28/2004 (2:54 am)
Edward, Ben, I looked at this stuff a while ago, and here's what I discovered. (I'm not near my code at the moment so I can't give exact class and routine names, but here's what I remember).

The two submerge textures are currently used only in the lava class to give the 'underwater' equivalent for being in lava. What the lava code does is paint a semi-transparent background colour (hardcoded as reddish) and then animates the two submerge textures over that.

Historically, it seems as if there was a Underwater class which did exactly what the Lava class does, but was removed when Melv updated the the fluid system.

If you like you can see how the underwater class worked by making a few simple changes to game.cc and the lava classes.

Firstly, the lava render routine has a hardcoded background colour. You need to either change this to be the water colour, or do what I did, namely, pass a ColorF parameter to the lava render routine, and use that parameter as the background colour in the lava render.

Second, comment out the underwater code in game.cc and call fxLava.render() instead, or the new fxLava.render(ColorF) with the watercolour if you decided to pass the colour as a parameter. (If you're passing the colour, you need to change the existing calls in the underlava routines to call fxLava.render(Colorf) with the lava colour as well. (This is all in game.cc)

As for the two submerge textures, I found two high density (lots of complexity) greyscale caustic textures to work quite well (relying on the colour parameter to differentiate between lava or water.

The textures need high density patterns or no pattern at all, ie. just a hazyness, to work well because the whole 256*256 is stretched accross the current resolution screen and hence may not scale very well.

Edit: In summary...
The two submerge textures are animated over a background colour across the entire screen, including gui's, similar to the water effect, to give the water a texture effect rather than the standard even coloured approach.

See my gui being coloured by water effect bug fix to get rid of the gui being overpainted.

PS: If you think anyone will be interested, then I can submit the above a resource or code-snippit. If so, then it would perhaps be best to rename the lava classes to fxSubmerge or something to show it's being used for both water and lava effects.
#3
03/28/2004 (3:56 am)
This would make for a great resource! Please share :)
#4
03/28/2004 (4:08 am)
Sure, I'll whip something up during next 24.
#5
03/28/2004 (4:23 am)
Just a few caveats on the use on the two-texture method for the full-screen effects...
I neglected to mention I found the method itself to be somewhat limiting, lacking in depth, and of course orientation being totally wrong for caustic effects. (Dreams on about TSE providing shader Waterblock functionality...)
The hazyness effect is interesting and does provide a way of adding grittiness to the water.
Maybe we need a few more textures though, so maybe I should tag on a dml feature?

EDIT: And a scriptable 'use backcolor" toggle so we can use texture colours rather than having to use the back colour to specify colour...?

If so, then hmmmm.... better make that 72h or so.

EDIT2:
I'd appreciate any and all thoughts on this, because I feel kinda guilty for how much stuff I've been using offa these here forums, and would like to give back something reasonably complete.
#6
03/28/2004 (8:38 am)
Interesting stuff, guys. Best of luck getting it working. ;)

And TSE is gonna have awesome effects, caustic and otherwise. Worry thou not. :)
#7
03/28/2004 (8:50 am)
Ben, glad to hear about the waterblock, (and from another thread, the terrain) changes to using shaders!!!

As to getting it working, it works with the changes I outlined above, but that's without the dml and 'use backcolor' options. (I'm not too sure whether we needs a dml anyway, because having more than 2 textures (which a dml will facilitate) may be too much a performance hit).

What are you're thoughts regarding the dml matter, and should I rename underlava.h and .cc to be fxSubmerge.h and .cc?
Seems to explain the functionality better.

PS: The way I have it implemented, if the submerge textures are missing, the color parameter is still used, which replicates the current functionality.
#8
03/28/2004 (9:36 am)
Did someone mention water?

I've already had a quick discussion with Mark F. about TSE and a new water object.

Being as this wouldn't be a major investment in time and energy (I've already done the research) then I can safely say that I could do this before my new baby is born, assuming the TSE is ready by then. ;)

You guys are in safe hands.

- Melv.
#9
03/28/2004 (10:06 am)
Melv, good to hear you're all over the new shader waterblock.
In the meanwhile then, I'll release the submerged texture resource so folks can use textures to add grittiness to water. I'll leave out the bells and whistles and just give the basic functionality as exposed by the underlava class.

PS: And Melv, please don't forget caustics, and cube-map reflections, these are the two areas the current waterblock needs most (IMHO).
#10
03/28/2004 (10:42 am)
The things that I feel would most benefit, in order, would be...

- Easier fluid-block placement/control
- More realism for surface deformation (perlin noise-style or more complex wave characteristics)
- Environment Reflections / Refractions
- Terrain Interaction (Shoreline/Depth)
- Object(s) Interaction (Boats, players, precipitation etc)
- Caustics

I'll start simple and work-up from there.

- Melv.
#11
03/28/2004 (10:57 am)
Melv,

I've been writing a guide (just about forever...since mid 2002) for Torque, and it is nearing completion. This thread was spawned as part of my effort to be sure the water section is up to date.

If you're curious, I list a basic TOC in my plan.

Regardless, if you decide to add some more features in the near future, could you post an announcement or resource when its done, or if it isn't too much trouble, ping me? I'd like to be sure this guide is as up to date as possible when I get ready to submit it. Note, I'm only worried about changes to TGE for now. I'm leaving TSE till after this is done.

Also, thanks to Everyone that replied to this thread.

[HOW]EdM
emaurinaverizonnet
#12
03/28/2004 (11:49 am)
Matthew,

I just wanted to say thanks again, since you came back with the answer I was looking for.

[HOW]EdM
#13
03/28/2004 (10:47 pm)
Pleasure, Edward.

Melv@: One thing not on your list and which I forgot to mention is the way being underwater is represented as a full-screen effect.
The current approach is cumbersome and causes problems when one is in a portalised structure underwater. You don't get the underwater effect if water is not in view, but go completely underwater when it is. In other words, the underwater effect should only be visible for say, a window area, not as a full-screen effect, hence flooding the whole room.
I know this touches on the interior code too, but it is relevant in that underwater is a state defined, checked and maintained by waterblock.

This particular problem is a major obstacle to creating amazing underwater games with Torque. Imagine a glass tunnel leading from one underwater complex to the next. With the current underwater effect this is impossible.

Any thoughts?
#14
03/29/2004 (3:09 am)
Ok, below follows the no bells-and-whistles resource. I'll post it here for those that can't wait, and submit it as a resource for those who can :)

The resource assumes the following:

1) If you are using submerge textures, whatever colour you want is in the textures. Hence no background colour will be applied.
2) If you are using submergeTexture1, submergeTexture0 is also specified.
3) If no submergeTexture is specified (or it doesn't exist as specified in the waterblock) the default water/lava colour is used as hardcoded in game.cc.

Possible enhancements:

1) The ability to specify the background colour.
2) The ability to use both background color and textures.
3) The ability to use more than two textures.
4) Renaming the underlava.h and .cc to be something more meaningfull like submerge.h .cc.

In view of the TSE upgrade to the waterblock I didn't think it worthwhile to do the enhancements above, although they should be quite trivial to do.

First: BACK UP THE FOLLOWING FILES:

game.cc
underlava.h
underlava.cc

Second: In underlava.h,

find ...
#ifndef _MPOINT_H_
#include "math/mPoint.h"
#endif

and include the below after that...
// included color - MJC
#ifndef _COLOR_H_
#include "core/color.h"
#endif

then find...
void render();

and replace with...
void render(ColorF color); // changed MJC to accept color

Third: In underlava.cc,

find...
void UnderLavaFX::render()

and comment out the whole routine, replacing it with the routine below...
void UnderLavaFX::render(ColorF color) // changed MJC to pass color
{
   init();

   glMatrixMode(GL_MODELVIEW);
   glPushMatrix();
   glLoadIdentity();
   glMatrixMode(GL_PROJECTION);
   glPushMatrix();
   glLoadIdentity();

   glEnable(GL_TEXTURE_2D);
   TextureHandle submergeTex = WaterBlock::getSubmergeTexture(0); // uncommented MJC
   glBindTexture(GL_TEXTURE_2D, submergeTex.getGLName()); // changed MJC

   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   glDepthMask(GL_FALSE);
   glColor4f(color.red,color.green,color.blue,color.alpha); // changed MJC
   // begin MJC to do submerge color
   if(!submergeTex) { 
	   glBegin(GL_TRIANGLE_FAN);
	   glVertex3f(-1, -1, 0);
	   glVertex3f(-1,  1, 0);
	   glVertex3f( 1,  1, 0);
	   glVertex3f( 1, -1, 0);
	   glEnd();
   }
   // end MJC
   if( submergeTex ) // changed MJC
   {
      glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

      // render layer 1
      for( U32 i=0; i<mNumPoints.y; i++ )
      {
         renderRow( i, mNumPoints.y-1, mNumPoints.x-1 );
      }
   }
   
   // give second layer a different phase
   mWave[0].velocity += 10.0;

   submergeTex = WaterBlock::getSubmergeTexture(1); // uncommented MJC

   if( submergeTex ) // changed MJC
   {
      glBindTexture(GL_TEXTURE_2D, submergeTex.getGLName());

      // render layer 2
      for( U32 i=0; i<mNumPoints.y; i++ )
      {
         renderRow( i, mNumPoints.y-1, mNumPoints.x-1 );
      }
   }

   glDepthMask(GL_TRUE);
   glDisable(GL_TEXTURE_2D);
   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
   glDisable(GL_BLEND);
   
   glMatrixMode(GL_PROJECTION);
   glPopMatrix();
   glMatrixMode(GL_MODELVIEW);
   glPopMatrix();
}

As you can see I've commented the sections I've changed.

continued...
#15
03/29/2004 (3:11 am)
Furthermore...

Fourth: In game.cc, in routine void GameRenderFilters(const CameraQuery& camq),

find...
if (WaterBlock::isWater(WaterBlock::mSubmergedType))
         {
            // view filter for camera below the water surface
            glMatrixMode(GL_MODELVIEW);
            glPushMatrix();
            glLoadIdentity();
            glMatrixMode(GL_PROJECTION);
            glPushMatrix();
            glLoadIdentity();

            glDisable(GL_TEXTURE_2D);
            glDepthMask(GL_FALSE);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glColor4f(.2, .6, .6, .3);
            glBegin(GL_TRIANGLE_FAN);
            glVertex3f(-1, -1, 0);
            glVertex3f(-1,  1, 0);
            glVertex3f( 1,  1, 0);
            glVertex3f( 1, -1, 0);
            glEnd();         
            glDisable(GL_BLEND);
            glBlendFunc(GL_ONE, GL_ZERO);
            glDepthMask(GL_TRUE);

            glMatrixMode(GL_PROJECTION);
            glPopMatrix();
            glMatrixMode(GL_MODELVIEW);
            glPopMatrix();
         }
         else if (WaterBlock::isLava(WaterBlock::mSubmergedType))
         {
	 gLavaFX.render();
         }

and replace with...
if (WaterBlock::isWater(WaterBlock::mSubmergedType))
         {
             // view filter for camera below the water surface
/* begin MJC
	glMatrixMode(GL_MODELVIEW);
            glPushMatrix();
            glLoadIdentity();
            glMatrixMode(GL_PROJECTION);
            glPushMatrix();
            glLoadIdentity();

            glDisable(GL_TEXTURE_2D);
            glDepthMask(GL_FALSE);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glColor4f(.2, .6, .6, .3);
            glBegin(GL_TRIANGLE_FAN);
            glVertex3f(-1, -1, 0);
            glVertex3f(-1,  1, 0);
            glVertex3f( 1,  1, 0);
            glVertex3f( 1, -1, 0);
            glEnd();         
            glDisable(GL_BLEND);
            glBlendFunc(GL_ONE, GL_ZERO);
            glDepthMask(GL_TRUE);

            glMatrixMode(GL_PROJECTION);
            glPopMatrix();
            glMatrixMode(GL_MODELVIEW);
            glPopMatrix();
end MJC */
	 // added MJC to send colour and use submerge textures
	 ColorF waterFilterColor(0.2, 0.6, 0.6, 0.6);
	 gLavaFX.render(waterFilterColor);
          }
         else if (WaterBlock::isLava(WaterBlock::mSubmergedType))
         {
             // added MJC to send lava colour
	 ColorF lavaFilterColor(1.0, 1.0, 1.0, 0.5);
	 gLavaFX.render(lavaFilterColor);
         }

continued...
#16
03/29/2004 (3:12 am)
And finally...

Since game.cc is currently using the USEOLDFILTERS setting, that's actually is all that is required to make this work, but for sake of completeness, you can make the changes below as well to ensure that the NEWFILTERS section will also work.

Fifth: Still in game.cc, and routine void GameRenderFilters(const CameraQuery& camq),

find...
F32 invincible       = 0.f; ColorF invincibleFilterColor(0.f, 0.f, 1.f, 0.f);

and after that insert...
ColorF lavaFilterColor(1.0, 1.0, 1.0, 0.5);

Sixth: Still in game.cc, and routine void GameRenderFilters(const CameraQuery& camq),

find...
if(addWaterFilter)
      {
         Xcolor         = ( Xcolor * ( 1 - waterFilterColor.alpha ) ) + ( waterFilterColor * waterFilterColor.alpha );
         Xcolor.alpha   =   Xcolor.alpha * ( 1 - waterFilterColor.alpha  );
      }

and comment it out...
/* begin MJC
      if(addWaterFilter)
      {
         Xcolor         = ( Xcolor * ( 1 - waterFilterColor.alpha ) ) + ( waterFilterColor * waterFilterColor.alpha );
         Xcolor.alpha   =   Xcolor.alpha * ( 1 - waterFilterColor.alpha  );
      }
end MJC */

Seventh and last: Still in game.cc, and routine void GameRenderFilters(const CameraQuery& camq),

find...
// if were under lava, apply appropriate texture
      if( addLavaFilter )
      {
         gLavaFX.render();
      }

and replace with...
// added MJC to use submerge textures for water and to 
      // send colour
      if( addWaterFilter )
     {
        gLavaFX.render(waterFilterColor);
     }
     // end added MJC
     // if were under lava, apply appropriate texture
     if( addLavaFilter )
     {
        // changed MJC to send colour
        gLavaFX.render(lavaFilterColor);
     }

And that's it! Do a full-rebuild and you should be good to go.

PS: A note about the textures - make sure they wrap properly else you get unseemly seams.
Also, for water, blue or grayscale hazemaps work quite well.

Enjoy!
#17
03/29/2004 (7:27 am)
The underwater fullscreen effect was only a hack anyways. Part of my experimenting really and it sucks in terms of integration with the SceneGraph. As you show, it's really just a part of the existing fullscreen effects.

Sure, there are much better ways of doing things and I'll be sure to collaborate with everyone when I finally come to looking at doing some new water. Maybe I'll not be the only one working on effects; someone like Brian Ramage may do something before I do, so we'll have to see.

I'd like to try my hand though at something more realistic and controllable.

- Melv.
#18
03/29/2004 (8:33 am)
Melv, you've proved yourself so many times on these forums that my only real fear is that there is only one Melv May, (any relation to the author Julian May, by the way?), and he is spread really thin, what with baby, Strategem, particle engine, and now the shader waterblock.

Please feel free to delegate some of the grunt work my way. I'm getting a feel for the engine and have some c++ experience, some shader experience, and all things being equal, may have some time available. Although the last bit is on the hush, hush. Got deliverables and all. (Sure do hate working for myself, can never slip one by the boss).

Perhaps, as you say, Brian and the GG gang are doing most of this for us, so let's not stress too much until we hear what exactly they are including in their scope.
#19
03/29/2004 (8:44 am)
Matthew,

Agreed. Doing something like a new waterblock would be so much less time-consuming than Strategem is and would be a nice change so I look forward to working on it.

Not too long to wait. :)

- Melv.
#20
03/29/2004 (8:54 am)
Melv: So are you related to Julian May? I'm a big fan. Well, not stalker big, but you know what I mean.
Page «Previous 1 2