Game Development Community

Underwater Effects, such as Caustics, Distorted/Wavy Screen, Rays, etc...

by Sorin Daraban · in Torque 3D Professional · 05/29/2009 (11:28 am) · 85 replies

Is something like Hydrax for Ogre3D on the horizon for T3D?

http://www.youtube.com/watch?v=cJM48NBQ3pw
#21
05/29/2009 (6:49 pm)
@Manoel - For beta 3 i just added this to PostEffect::_setupConstants()...

if ( mAccumTimeSC->isValid() )   
      mShaderConsts->set( mAccumTimeSC, MATMGR->getTotalTime() );

... this mimics the same $accumTime you can use from CustomMaterial for texture animations.

You should probably do something similar to get caustics working.
#22
05/29/2009 (6:54 pm)
I'm going the script route for now, to see this working without code changes (I still need to download all those SDKs at home - I'd like to get something running before going to bed), for proof-of-concept.

How do I get this to render before the water? And I'm fighting with the waterPlane constant (trying to limit the effect to underwater surfaces only).

--EDIT--
Ah, the waterplane.z was negative!
#23
05/29/2009 (7:02 pm)
Note that the waterplane is a plane... xyz is a normal and w is the distance from zero... it is not a position of the water surface.

If you look at the water fog post effect you can see how to detect if the 3d position is within the water volume.
#24
05/29/2009 (7:09 pm)
Got it working only below the waterplane and made it draw before the water does. Only need to setup some textures and do the animation script.
#25
05/29/2009 (7:26 pm)
Nice work Manoel! I'm curious to see some screenshots when you get a texture in there.
#26
05/29/2009 (7:37 pm)
I think I hit a roadblock: the textures aren't loading for some reason. I keep getting the $backbuffer at s1 and random normalmaps on s2. Here's the stateBlock, shaderData and postEffect:

singleton GFXStateBlockData( PFX_CausticsStateBlock : PFX_DefaultStateBlock )
{
   blendDefined = true;
   blendEnable = true; 
   blendSrc = GFXBlendOne;
   blendDest = GFXBlendOne;
   
   samplersDefined = true;
   samplerStates[0] = SamplerClampLinear;
   samplerStates[1] = SamplerWrapLinear;
   samplerStates[2] = SamplerWrapLinear;
};

singleton ShaderData( PFX_CausticsShader )
{   
   DXVertexShaderFile 	= "shaders/common/postFx/postFxV.hlsl";
   DXPixelShaderFile 	= "shaders/common/postFx/caustics/causticsP.hlsl";
         
   //OGLVertexShaderFile  = "shaders/common/postFx/gl//postFxV.glsl";
   //OGLPixelShaderFile   = "shaders/common/postFx/gl/passthruP.glsl";
      
   samplerNames[0] = "$prepassTex";
   samplerNames[1] = "$causticsTex0";
   samplerNames[2] = "$causticsTex1";
   
   pixVersion = 3.0;
};

singleton PostEffect( CausticsPostEffect )
{
   isEnabled = true;
   renderTime = "PFXBeforeBin";
   renderBin = "ObjTranslucentBin";      
   //renderPriority = 0.1;
      
   shader = PFX_CausticsShader;
   stateBlock = PFX_CausticsStateBlock;
   texture[0] = "#prepass";
   texture[1] = "~/art/caustics_0";
   texture[2] = "~/art/caustics_1";
   target = "$backBuffer";
   
};

And how the samplers are defined in the shader:
float4 main( PFXVertToPix IN, 
             uniform sampler2D prepassTex :register(S0),
             uniform sampler2D causticsTex0 :register(S1),
             uniform sampler2D causticsTex1 :register(S2),
             uniform float2 targetSize : register(C0) ) : COLOR

The script is at "core/client/scripts/postFX" and the textures are in "core/art" (PNG files).

I can't run a debugger on it now, so I have no idea what's going on.
#27
05/29/2009 (7:44 pm)
Remove the ~... just do "art/caustics_0" and "art/caustics_1".
#28
05/29/2009 (7:45 pm)
--EDIT--
Ah, that also does it =P

--EDIT 2--
Wait, no it doesn't =/

Still not working. The only way I got it to work is by moving the textures to the postFX folder or any folder inside it.
#29
05/29/2009 (7:49 pm)
Ah... i didn't notice you said it was in core/art.... do "core/art/caustics_0" and "core/art/caustics_1".
#30
05/29/2009 (8:22 pm)
I think I tried that and didn't do it. Looking at the source, if the path doesn't begin with "/" the code will append $Con::file and a "/" before it.

// If '/', then path is specified, open normally
      if ( texFilename[0] != '/' )
         texFilename = scriptPath.getFullPath() + '/' + texFilename;

      // Try to load the texture.
      mTextures[i].set( texFilename, &PostFxTextureProfile, avar( "%s() - (line %d)", __FUNCTION__, __LINE__ ) );

Anyway, I have a screenshot!
i43.tinypic.com/1f3g5.png

The effect almost disappears when viewed from outside the water, though.
#31
05/29/2009 (8:33 pm)
Ok, for anyone wishing to try it: www.mediafire.com/download.php?wmmzmzojwwq

Throw the "game" folder inside the .zip over your own game folder. It adds files to "core" and "shaders". Since scripts in the PostFX folder are executed automatically, no script changes are required. The effect is set to enable automatically, and it needs a water plane (I have no idea what will happen on a water-less mission).

It's very simple, doesn't deal with shadows. The caustic scale and movement speed values are all hardcoded into the shader, but they can be easily exposed to script.

Anyway, PostEffect is awesome. I knew T3D had more of its graphics system exposed to script, but this is well beyond what I expected. Can't believe you guys didn't mention this in a blog post yet. When posting about the light rays the system behind it should have got a mention. Heck, many of the effects like SSAO and DOF are almost pure PostEffect trickery.

BTW, I can try documenting this experiment into a tutorial resource, if anyone is interested.
#32
05/29/2009 (8:40 pm)
Nice Manoel - Can't wait to give this a try and see what it looks like in motion.
#33
05/29/2009 (8:46 pm)
Cool! That looks really good so far... i think a little bit better texture/animation and you'll be in pretty good shape with it. Also maybe do some chromatic dispersion dynamically instead of being part of the texture.

Take a read of the Crysis Next Gen Effects presentation where they talk about their caustics and other water effects.
#34
05/29/2009 (9:00 pm)
Thanks Tom, will take a look at those slides. The current effect is a good starting point for others, although.

Now, I'm interested in making good use of that matPrevScreenToWorld constant to make a certain other effect. ;)
#35
05/29/2009 (9:07 pm)
Heh... We hope that in a future update to T3D we'll directly add motion blur support. :)

If you look at the Deferred Rendering in Killzone 2 slides they talk about how they store a 2d motion vector per-pixel during their deferred prepass. If T3D were to do the same you could do correct motion blur and not just a camera movement blur.

The reason why we don't have this working already is that our prepass texture is full and no room exists for storing 16bits of motion vector. We would either need DX10/11 where we can directly read the depth buffer... freeing 32bits of prepass... or use MRT to bind a second target to store motion vectors and other stuff.
#36
05/29/2009 (9:41 pm)
I'm really interesting about a tutorial resource for the PostEffect like this!
#37
05/29/2009 (9:45 pm)
I'd vote for another render target. It would help with a few things, like having the SSAO affect only the ambient color (instead of everything) and allow specular intensity and power for deferred lights.

I'm not a big fan of the velocity buffer approach. For objects, it cannot blur outside their silhouettes, and for camera movement having the previous camera matrix would suffice. The objects need to stretch along the velocity vector for it to look good. At least the moving and animated ones. This is what makes Lost Planet look so good. They even went to add exaggerated spin motions to monsters and mechs since they look awesome when motion blurred.

Once I got setup for adding Lost Planet-style blur to TGEA, but got lazy when I reached the part where I needed to generate a 2nd vertex buffer for the blur: in order to stretch an object along it's motion, all vertex normals must be the average of their polygons' normals, otherwise the stretching might become wrong, or even break up if there are hard edges.

The pixel and vertex shaders themselves are amazingly simple. After I got done with them in RenderMonkey they had around 5-8 actual lines of code each, and could run well in SM 2.0 hardware (I though they would require SM 3.0).

I'll try go compile a tutorial tomorrow, I should have been sleeping for a while already...
#38
05/29/2009 (11:29 pm)
that is AWESOME!!!
Manoel, well done, and thank guys for getting this going,
drops right in and works a treat!!

gleams 8o)
#39
05/30/2009 (3:36 am)
I did the turbolence PP shader and is working just fine.
But in the end texcoord positions i fell the render like a winded flag.
Ani suggestions how to fix it?
#40
05/30/2009 (3:43 am)
turbolence PP shader??