Game Development Community

Underwater Terrain Shading

by Jacob Dankovchik · in Torque Game Engine Advanced · 02/17/2007 (11:01 pm) · 54 replies

This is the shader code for the stuff posted in the topic here: www.garagegames.com/mg/forums/result.thread.php?qt=39336

There are a few things I need to mention though. Unfortunately, I can't get it to work with Atlas2. I've not the time to learn the ins and outs of Atlas2 to get this working smoothly, so I'll just post the code here that I used in the past and let someone who knows the Atlas code better try to work it in. If someone out there does get it working, at least please post the solution... Otherwise I'd rather not you use it at all if you don't share your help.

Anyhow, the way this was setup to work was as a second pass called through the Atlas material with a multiply blend function. It would work out the shade value for the terrain underwater and just times that by the actual color.

It starts with a small engine change. I know this could probably be done better. And i've no clue the effect multiple waterblocks has. But this is to get the waterblock's size and position into the shader so we can check if the pixel is underwater. This goes in waterblock.cpp, in setShaderParams:
reg[0] = mObjScale.x;
   reg[1] = mObjScale.y;
   reg[2] = mObjScale.z;
  GFX->setPixelShaderConstF( 9, (float*)reg, 1 );

  Point3F pos = this->getPosition();
  reg[0] = pos.x;
   reg[1] = pos.y;
   reg[2] = pos.z;
  GFX->setPixelShaderConstF( 11, (float*)reg, 1 );

  reg[0] = mBaseColor.red;///mBaseColor.alpha ;
   reg[1] = mBaseColor.green;///mBaseColor.alpha;
   reg[2] = mBaseColor.blue;///mBaseColor.alpha;
   reg[3] = mBaseColor.alpha;
   GFX->setPixelShaderConstF( 17, (float*)reg, 1 );

The shader requires 2.0, so assemble any material def's with it with that in mind.

And now the shaders itself. These aren't modified or cleaned up, this is just the stuff I used that works. No big deal to clean it up anyhow really. You get the idea.
Page «Previous 1 2 3 Last »
#1
02/17/2007 (11:01 pm)
Vertex:
#define IN_HLSL
#include "..\shdrConsts.h"

//-----------------------------------------------------------------------------
// Structures                                                                  
//-----------------------------------------------------------------------------
struct VertData
{
   float4 position        : POSITION;
   float2 texCoord        : TEXCOORD0;
float3 T               : TEXCOORD1;
   float3 B               : TEXCOORD2;
   float3 N               : TEXCOORD3;
   float3 normal          : NORMAL;
};


struct ConnectData
{
   float4 hpos            : POSITION;
   float2 texCoord        : TEXCOORD0;
   float2 fogCoord        : TEXCOORD1;
   float2 detailCoord     : TEXCOORD2;
   float2 detailCoord2    : TEXCOORD3;
   float3 outLightVec     : TEXCOORD4;
   float4 hpos2           : TEXCOORD5;
   float3 eyePos	  : TEXCOORD6;
};

//-----------------------------------------------------------------------------
// Main                                                                        
//-----------------------------------------------------------------------------
ConnectData main( VertData IN,
                  uniform float4x4 modelview       : register(VC_WORLD_PROJ),
                  uniform float4x4 objTrans        : register(VC_OBJ_TRANS),
                  uniform float3   eyePos          : register(VC_EYE_POS),
                  uniform float3   fogData         : register(VC_FOGDATA),
		  uniform float3   inLightVec      : register(C24),
                  uniform float4   texGen          : register(C44),
                  uniform float4   scaleOff        : register(C45),
                  uniform float4   morphInfo       : register(C46)
                  )
{
   ConnectData OUT;
   
   // Do positional transform on the heightfield data, and apply morph.
   float4  realPos;
   realPos.x = IN.position.x * scaleOff.z + scaleOff.x;
   realPos.y = IN.position.y * scaleOff.z + scaleOff.y;
   realPos.z = IN.position.z + IN.texCoord.x * morphInfo.x;
   realPos.w = IN.position.w;
   
   OUT.hpos        = mul(modelview, realPos);
   OUT.hpos2 = realPos;
   float3 worldPos = mul(objTrans,  realPos.xyz);
   float3 worldEye = mul(objTrans,  eyePos);

   /// Generate texture co-ords.
   OUT.texCoord.y = realPos.x * texGen.z + texGen.x;
   OUT.texCoord.x = realPos.y * texGen.z + texGen.y;

   // And fog texture co-ords.   
   OUT.fogCoord.x = 1.0 - ( distance( worldPos, worldEye ) / fogData.z );
   OUT.fogCoord.y = (worldPos.z - fogData.x) * fogData.y;

   // And detail texture co-ords.
   OUT.detailCoord  = realPos / 5.1;
   OUT.detailCoord2 = realPos / 1.3;

float3x3 objToTangentSpace;
   objToTangentSpace[0] = IN.T;
   objToTangentSpace[1] = IN.B;
   objToTangentSpace[2] = IN.N;

   OUT.outLightVec.xyz = -inLightVec;
  // OUT.outLightVec.xyz = mul(objToTangentSpace, OUT.outLightVec);
  // OUT.outLightVec = OUT.outLightVec / 2.0 + 0.5;

OUT.eyePos = eyePos;

   return OUT;
}
#2
02/17/2007 (11:01 pm)
Pixel:
//-----------------------------------------------------------------------------
// Structures                                                                  
//-----------------------------------------------------------------------------
struct ConnectData
{
   float4 hpos		  : POSITION;
   float2 texCoord        : TEXCOORD0;
   float2 fogCoord        : TEXCOORD1;
   float2 detailCoord     : TEXCOORD2;
   float2 detailCoord2    : TEXCOORD3;
   float3 lightVec        : TEXCOORD4;
   float4 hpos2           : TEXCOORD5;
   float3 eyePos	  : TEXCOORD6;
};


struct Fragout
{
   float4 col : COLOR0;
};

//10,20,50

//-----------------------------------------------------------------------------
// Main                                                                        
//-----------------------------------------------------------------------------
Fragout main( ConnectData IN,
              uniform sampler2D diffuseMap      : register(S0),
              uniform sampler2D fogMap          : register(S1),
              uniform sampler2D detailMap       : register(S2),
              uniform sampler2D detailMap2      : register(S3),
              uniform float4    ambient         : register(C2),
	      uniform float3    scale		: register(c9),
	      uniform float4     baseColor      : register(c17),
	      uniform float3    pos		: register(c11)
              )
{
   Fragout OUT;
 
  float4 detailCol = (1,1,1,1);


if (IN.hpos2.z < pos.z && ((IN.hpos2.x < (pos.x+(scale.x/2))) && (IN.hpos2.x > (pos.x-(scale.x/2))) )
&& ((IN.hpos2.y < (pos.y+(scale.y/2))) && (IN.hpos2.y > (pos.y-(scale.y/2))) ))
{
float depth = distance(IN.hpos2.z,pos.z);
 
  float coeffR = -log(2)/(baseColor.r);
   float coeffG = -log(2)/(baseColor.g);
   float coeffB = -log(2)/(baseColor.b);


detailCol.r *= (pow(2.718281828,coeffR*depth));
detailCol.g *= (pow(2.718281828,coeffG*depth));
detailCol.b *= (pow(2.718281828,coeffB*depth));

}

OUT.col = detailCol;

   return OUT;
}


And there you go. However, this code doesn't take any angles into account. I wrote the code for that, but I'm not releasing it until I test it at least. Sort of a policy of mine. Anyhow, if you get it working right, lemme know. I'd really like to release this fully working, I hate half-done solutions. If I can get this fully working, theres still quite a bit I'd like to do with it.

And you may notice, its actually very simple, isn't it? It's amazing what a single math formula based on actual scientific data will do, rather than some half-assed random basic math you would think up that sorta does the trick.

So, please help on that as I've not the time to try to learn it all myself. And for now I move on to the next good idea of mine. This one should be very interesting indeed if it works. It'll be a definite first, so far as I've found. :)
#3
02/18/2007 (12:20 am)
Hey glad to see this moving forward, I cant wait to see this functioning for RC1... Good job guys!

addikt
#4
02/18/2007 (5:03 am)
Yeah, nice one Jacob! Great timing with the R1 release etc. Be interesting to see what people can get out of it - H
#5
02/18/2007 (9:39 am)
What file am I putting these vertex and pixel shaders into? Take it easy on me as I'm an artist not a programmer I'm assuming I put the waterblock into the write place.

in waterblock.cpp I had

edited to make thread easier to read

is this correct?
#6
02/18/2007 (10:07 am)
This looks really really cool. I have no time to integrate it, just wanted to say cheers :)
#7
02/18/2007 (10:32 am)
@matt do I need to integrate the version above or just what you changed? as fare as the shader goes anyway.

Basicly I replaced everything in atlas.h with what you have.

and I made the chages to shader.cs and waterblock.cpp.
is this all I need?
#8
02/18/2007 (12:21 pm)
Hmm I compiled and got the following warings:

c:\program files\microsoft directx sdk (october 2006)\include\strsafe.h(5595) : warning C4996: '_vsnprintf' was declared deprecated
        c:\program files\microsoft visual studio 8\vc\include\stdio.h(339) : see declaration of '_vsnprintf'
        Message: 'This function or variable may be unsafe. Consider using _vsnprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'


c:\program files\microsoft directx sdk (october 2006)\include\strsafe.h(5635) : warning C4996: '_vsnwprintf' was declared deprecated

        c:\program files\microsoft visual studio 8\vc\include\wchar.h(719) : see declaration of '_vsnwprintf'
        Message: 'This function or variable may be unsafe. Consider using _vsnwprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'


c:\program files\microsoft directx sdk (october 2006)\include\strsafe.h(5719) : warning C4996: '_vsnprintf' was declared deprecated

        c:\program files\microsoft visual studio 8\vc\include\stdio.h(339) : see declaration of '_vsnprintf'
        Message: 'This function or variable may be unsafe. Consider using _vsnprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'


c:\program files\microsoft directx sdk (october 2006)\include\strsafe.h(5871) : warning C4996: '_vsnwprintf' was declared deprecated

c:\program files\microsoft visual studio 8\vc\include\wchar.h(719) : see declaration of '_vsnwprintf'
        Message: 'This function or variable may be unsafe. Consider using _vsnwprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'


t:\torque_game_dev\torque\torqueadvanced\sdk\engine\platformwin32\dxversionchecker.cpp(149) : warning C4996: '_wsplitpath' was declared deprecated
        c:\program files\microsoft visual studio 8\vc\include\stdlib.h(782) : see declaration of '_wsplitpath'
        Message: 'This function or variable may be unsafe. Consider using _wsplitpath_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'

t:\torque_game_dev\torque\torqueadvanced\sdk\engine\gfx\d3d\gfxd3ddevice.cpp(39) : warning C4482: nonstandard extension used: enum 'GFXVertexColor::ColorOrdering' used in qualified name


Results      
Build log was saved at "file://t:\Torque_game_dev\Torque\TorqueAdvanced\SDK\engine\out.vc8.win32.debug\BuildLog.htm"
Torque Game Engine Advanced - 0 error(s), 6 warning(s)


then when I tried to run the resulting exe I got:

window titled: Fatal: (t:\toque_game_dev\torque\torqueadvanced\sdk\gfx\d3d\gfxd3dshader.cpp @206)

that said:

Unable to compile pixel shader 'shaders/atlas/atlasSurfaceP2.hlsl'

Retry or cancel.

and the debug want not much help.

any ideas?
#9
02/18/2007 (12:33 pm)
Also, in all honesty I wouldn't do my update. Wait until the clipMap issue is solved.
#10
02/18/2007 (1:38 pm)
I have the right SDK I sintalled exactly as I was instructed in the TDN how-to
#11
02/18/2007 (2:43 pm)
The console? in the TGEA console?

I replaced everything to how it was and I still get those errors but everything compiles and runs fine so the shader not compiling WAS one of the things I changed.

oh well I will wait for this to get fixed.
#13
02/23/2007 (2:36 pm)
We achieved a similar result via a slightly different method. By increasing the water block translucency and using L3DT to paint the Atlas seabed as a gradient.

Image 1: i141.photobucket.com/albums/r75/piratelordx/Water.jpg

Image 2: i141.photobucket.com/albums/r75/piratelordx/Water2.jpg

Image 3: i141.photobucket.com/albums/r75/piratelordx/Water3.jpg

Image 4: i141.photobucket.com/albums/r75/piratelordx/Water4.jpg

Image 5: i141.photobucket.com/albums/r75/piratelordx/Water5.jpg

We havent established yet if it will cause any annoying redesigns, but it sure looks good.
#14
02/23/2007 (2:46 pm)
Beautiful skybox you have there. What's neat about this is that you wouldn't need it painted into the texture. It also is amazingly accurate, because this approach is an adapted formula that explains how water is blue in real life.
#15
02/23/2007 (2:59 pm)
@addiktive (piratelord! now I recognize you from L3DT forums :) )
Is that a Blended or Unique terrain? I'm constantly looking at ways to get a better terrain texture coming from L3DT.
#16
02/23/2007 (3:07 pm)
Heya,

It's a Unique Terrain. Piratelord is our Terrain guy for the LegendRPG Project, you can catch him on the Legend Forum or email him direct, we are also trying to constantly improve our terrain results, and would love to discuss it further ;)

LegendRPG Website: www.legendrpg.com/
LegendRPG Forum: addiktive.proboards58.com/index.cgi
Piratelord Email: Pirates.Retreat@btinternet.com

Sorry Jacob, dont wanna derail your thread...

addikt
#17
02/23/2007 (4:37 pm)
No problem.

But yeah, the downside to that is it requires a unique texture. The idea for this is for it to be realtime and work with blended terrains. However, L3DT's approach is just as accurate as mine, as the idea for this whole thing came from L3DT and we use the same formula. Once this is done properly though, it'll be much more accurate then L3DT's approach for a realtime solution.
#18
02/25/2007 (3:15 am)
At the moment we need to use Unique texture, so it's not an issue for us, but depending on future development of Atlas, we might need this shader :D
#19
03/02/2007 (8:16 pm)
Quote:using L3DT to paint the Atlas seabed as a gradient.

you mean that the bottom of the seabea has a gradient that turns it blue?
#20
03/17/2007 (9:29 pm)
So has this come to a stop again or what?
Page «Previous 1 2 3 Last »