Game Development Community

Has anyone found a way to do waves and breaks near shore?

by James Brad Barnette · in Torque Game Engine Advanced · 06/09/2007 (9:24 am) · 20 replies

Has anyone figures out a way to do this?
In the first farcry I remember there being a wave texture near the showline. I have seen pictures of this in halo 3 as well I was wondering if anyone knows how this is done?

#1
06/09/2007 (9:57 am)
"brute force approach" would be vertical ray casts on the water grid and see how far above ground it as and fade a shore texture depending on this distance.

If you use atlas, it would be possible to lower the bruteforce work if you first do a "block distance" ray cast and if you want to optimize it even further, precalculate a map that shows which atlas blocks / water regions can create a shore at all :)
#2
06/09/2007 (4:17 pm)
So what a bunch of animated textures projected on the entire shorline???? that should like it would be very heavy?
#3
06/13/2007 (2:08 pm)
Here is what I'm talking about. I'm gonna dig throught the game and see if I can figure out a little more by looking at the textures. but after staring at the waves roll in for about half an hour I can tell you that the wave/foam textures are doing a simple translate and scale animation it looks like 3 seperate ones in a loop that plays all the way down the shore. I also noticed that they are being projected on the sand of the shore itself and not on the water. so if you look closely the waves are actually under the water. this is fin because water in farcry has almost no color. the blue color comes from the fact that the sandy bottom is painted blue

here are the pics:

www.pixollusion.com/FC/FarCry0001.jpgwww.pixollusion.com/FC/FarCry0002.jpgwww.pixollusion.com/FC/FarCry0003.jpgwww.pixollusion.com/FC/FarCry0004.jpg
#4
06/13/2007 (2:37 pm)
If you can get this working and combined with the other water Shading work that Jacob is doing, then I think TGEA water will finally be in a condition where it can be used in a commercial game. Which is where it should have been on release day, but oh well...
#5
06/13/2007 (4:56 pm)
Perhaps abit off topic, but has anyone found a smart way to do waves in general, that a boat for example could react with?
Since if i havent totally misunderstood, i assume that you cant get any "height" data out of bump maps only.
I was thinking something along the lines of having "crude" waves with polys that loop (like legacy terrain loop) so you can have an ocean of it :)
You could even use legacy terrain for the seabed, and atlas terrain for islands sticking up of the water, so you dont get the problem of ships sinking into the great unknown.

And then you add "detail maps", bump maps, normal maps to add the detail it needs visually.

Ofcourse things like checking if its a shoreline or the bottom is near enough is also important to making it nice.
#6
06/13/2007 (6:13 pm)
Well I'm not really a programmer. I took it in school and I'm learning it again.

I know that in a way this is very similar to the zodiacs that AFX has which should be ready soon
then it is it is a looping animated texture. Now mapping it to the surface well some how you should have to calculate the agle of all of the edges that cross the waterblock. then have it figureout the right angle between them. Align the texture to this have it repeat on the horizontal axis only

ot at least that is my theory.

The only thing that I know for sure is that it is a looping texture that is repeating horizontaly. and being projected on the sand not the water. " it is aso comming up the beach some. it seams to be scentered on the border where the water intersects the terrain.

@Niklas

Well that is a whole different animal there. Personaly I think that the TGEA water is fine except for its interaction or lack there of with the shore.

I can't remember but I think the water in HL2 interacted with the user. it would be interesting to see how that is done I'm that it was done with some kinda retaime displament map but that is just a guess.

I have Isolated the shaders that were used as well as the textures. from what I can tell it is written in CG. I was wondering if someone that know about this would be willing to take a look at this. I think that once we can understand the process it should be "easier" to write something in HLSL.

email me a calmasacow@yahoo.com
#7
06/13/2007 (7:08 pm)
Well as it turns out it looks like it is projected on both. about equal distance on the sand as out towards the sea.
#8
06/13/2007 (7:11 pm)
I've suggested this before (for the waves). I'm no programmer either:) So my guess is my luck integrating this would be nil. Potentially cool if it could be added though:

www.magicindie.com/

Cheap to boot, if it works as advertised ($15 for source code).
#9
06/14/2007 (6:54 am)
It does look cool, but to be honest with you I have seen better water in torque already. the foma is cool and I like the gui. But they still don't have what we are after hear in this thread wich is shoreline waves/foam.
#10
06/14/2007 (8:38 pm)
I'm working on an advanced water shader using fixed refraction, animated waves, and vertex texture fetching. Though it's expensive, I think its the only realistic way to go when it comes to simulating an ocean.
#11
06/15/2007 (9:14 am)
I don't want to simulate and ocean. I don't even much mind the water the way it is not I simply want to have a texture that uses transform and scale animation porjected along the shoreline. Exactly the way it is in the pictures above. If that can be done with yours or jacobs water shaders. that would be great too. But if it could be done with the existing water. that is fine It needs to be independant of the water/ocean shader though IMHO. at least that is the way they are doing it above.
#12
06/15/2007 (9:22 am)
Here is a copy of the CG shader I found that does this but I have no idea of how it would be converted to the HLSL format that TGEA uses:

Shader 'TerrainWaterBeach'
(
  Public
  (
    float 'WaveAmplitude' (0.1)
    float 'AnimSpeed' (0.5)
    float 'RefrTillingAmount' (2.5)
    float 'RefrBumpAmount' (0.05)
  )
  Params
  (
    Sort = WaterBeach
    Cull  = TwoSided
  )

  HW 'Seq'
  (
    Conditions
    {
      Vars
      {
        r_WaterBeachRefractions = 1
      }
    }
    Array (Verts 3 FLOAT Vertex)
    Array (Color 4 BYTE Color)
    Array (Texture0 2 FLOAT Texture0)

    ShadeLayer
    (
      CGPShader = CGRCWater_Beach_Refr
      CGPSParam ( Name = Ambient Comp = 1 Comp = 1 Comp = 1 Comp = 1)
      CGPSParam ( Name = Matrix Comp =0.05 Comp = 0 Comp = 0 Comp =0.05 )
      
      CGVProgram = CGVProgWater_Beach_Refr
      CGVPParam ( Name = TexShiftRipple Comp = 0 Comp = 0 Comp 'time 0.06' Comp 'time 0.12')
      CGVPParam ( Name = TexGenRipple0 Comp = 0.125 Comp = 0 Comp = 0 Comp = 0)
      CGVPParam ( Name = TexGenRipple1 Comp = 0 Comp = 0.125 Comp = 0 Comp = 0)
      CGVPParam ( Name = TexDetailScale User 'RefrTillingAmount' User 'RefrTillingAmount'  Comp = 0 User 'AnimSpeed')

      //MAIN WAVE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Translate and Scale waves are !!!synchronized!!! except that Scale is a bit lag behind translate to make waves scale down after(!!!) it reaches the sand
      CGVPParam
      (
        Name = TexShift
        
        // Translate
        Comp 'Wave' { Type = sin Level = 0 Amp = 0.25 Phase = 0.0  Freq = 0.1 }
        // Scale
        Comp 'Wave' { Type = sin Level = 2 Amp = 0.9  Phase = 0.15 Freq = 0.1 }
        // Noise
        Comp = 0
        Comp = 1
      )
      
      Layer '0'
      (      
        Map =   fire_noise.dds
        TexType = DSDTBump
        TexColorOp = NoSet
      )
      Layer '1'
      (
        Map      = wave1
        ClampTexCoords
        TexColorOp = NoSet
        DepthWrite = 0
        Blend    'SRC_ALPHA ONE_MINUS_SRC_ALPHA'
      )
    )

    //COPY OF MAIN WAVE!! shifted phase  to make it move different 
    ShadeLayer
    (
      CGPShader = CGRCWater_Beach_Refr
      CGPSParam ( Name = Ambient Comp = 1 Comp = 1 Comp = 1 Comp = 1)      
      CGPSParam ( Name = Matrix Comp =0.05 Comp = 0 Comp = 0 Comp =0.05 )
      
      CGVProgram = CGVProgWater_Beach_Refr
      CGVPParam ( Name = TexShiftRipple Comp = 0 Comp = 0 Comp 'time 0.06' Comp 'time 0.12')
      CGVPParam ( Name = TexGenRipple0 Comp = 0.125 Comp = 0 Comp = 0 Comp = 0)
      CGVPParam ( Name = TexGenRipple1 Comp = 0 Comp = 0.125 Comp = 0 Comp = 0)
      CGVPParam ( Name = TexDetailScale User 'RefrTillingAmount' User 'RefrTillingAmount'  Comp = 0 User 'AnimSpeed')
      CGVPParam
      (
        Name = TexShift
        Comp 'Wave' { Type = sin Level = 0 Amp = 0.25 Phase = 0.4 Freq = 0.1 }
        Comp 'Wave' { Type = sin Level = 2 Amp = 0.9  Phase = 0.55 Freq = 0.1 }
        Comp = 0
        Comp = 1
      )
      
      Layer '0'
      (      
        Map =   fire_noise.dds
        TexType = DSDTBump
        TexColorOp = NoSet
      )
      Layer '1'
      (
        Map      = wave1
        ClampTexCoords
        TexColorOp = NoSet
        DepthWrite = 0
        Blend    'SRC_ALPHA ONE_MINUS_SRC_ALPHA'
      )
    )

    //another COPY OF MAIN WAVE(detail )!! shifted phase  to make it move different 
    ShadeLayer
    (
      CGPShader = CGRCWater_Beach_Refr
      CGPSParam ( Name = Ambient Comp = 1 Comp = 1 Comp = 1 Comp = 1)
      CGPSParam ( Name = Matrix Comp =0.05 Comp = 0 Comp = 0 Comp =0.05 )
      
      CGVProgram = CGVProgWater_Beach_Refr
      CGVPParam ( Name = TexShiftRipple Comp = 0 Comp = 0 Comp 'time 0.06' Comp 'time 0.12')
      CGVPParam ( Name = TexGenRipple0 Comp = 0.125 Comp = 0 Comp = 0 Comp = 0)
      CGVPParam ( Name = TexGenRipple1 Comp = 0 Comp = 0.125 Comp = 0 Comp = 0)
      CGVPParam ( Name = TexDetailScale User 'RefrTillingAmount' User 'RefrTillingAmount'  Comp = 0 User 'AnimSpeed')
      CGVPParam
      (
        Name = TexShift
        Comp 'Wave' { Type = sin Level = 0 Amp = 0.25 Phase = 0.5 Freq = 0.1 }
        Comp 'Wave' { Type = sin Level = 2 Amp = 0.9 Phase = 0.65 Freq = 0.1 }
        Comp = 0
        Comp = 1
      )
      
      Layer '0'
      (      
        Map =   fire_noise.dds
        TexType = DSDTBump
        TexColorOp = NoSet
      )
      Layer '1'
      (
        Map      = wave1
        ClampTexCoords
        TexColorOp = NoSet
        DepthWrite = 0
        Blend    'SRC_ALPHA ONE_MINUS_SRC_ALPHA'
      )
    )

    // Moving detail layer!!!!!!!!!!!!!!!!!!!
    ShadeLayer
    (
      CGVProgram = CGVProgWater_Beach_Shift
      CGVPParam ( Name = TexShift Comp = 0 Comp 'time 0.2') // xy = wavepos, z = 0, w = amplitude
      CGVPParam ( Name = TexScale Comp = 1.25 Comp = 3) // xy = wavepos, z = 0, w = amplitude
      
      Layer '0'
      (
        Map      = water2.tga

        Blend     'SRC_ALPHA ONE_MINUS_SRC_ALPHA'
        TexColorOp = Modulate
      )
    )
  )

  HW 'Seq'
  (
    Array (Verts 3 FLOAT Vertex)
    Array (Color 4 BYTE Color)
    Array (Texture0 2 FLOAT Texture0)

    ShadeLayer
    (
      CGPShader = CGRCWater_Beach
      CGPSParam ( Name = Ambient Comp = 1 Comp = 1 Comp = 1 Comp = 1)
      
      CGVProgram = CGVProgWater_Beach
      CGVPParam ( Name = CameraPos Comp 'OSCameraPos pos 0' Comp 'OSCameraPos pos 1' Comp 'OSCameraPos pos 2' Comp = 0.15)
#13
06/15/2007 (9:23 am)
Contiued:
//MAIN WAVE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Translate and Scale waves are !!!synchronized!!! except that Scale is a bit lag behind translate to make waves scale down after(!!!) it reaches the sand
      CGVPParam
      (
        Name = TexShift
        
        // Translate
        Comp 'Wave' { Type = sin Level = 0 Amp = 0.25 Phase = 0.0  Freq = 0.1 }
        // Scale
        Comp 'Wave' { Type = sin Level = 2 Amp = 0.9  Phase = 0.15 Freq = 0.1 }
        // Noise
        Comp 'Wave' { Type = sin Level = 0.2 Amp = 0  Phase = 0.0  Freq = 0.1 }
        Comp = 1
      )
      
      Layer '0'
      (
        Map      = wave1
        ClampTexCoords
        Blend     'SRC_ALPHA ONE_MINUS_SRC_ALPHA'
        TexColorOp = NoSet
      )
    )

    //COPY OF MAIN WAVE!! shifted phase  to make it move different 
    ShadeLayer
    (
      CGPShader = CGRCWater_Beach
      CGPSParam ( Name = Ambient Comp = 1 Comp = 1 Comp = 1 Comp = 1)
      
      CGVProgram = CGVProgWater_Beach
      CGVPParam ( Name = CameraPos Comp 'OSCameraPos pos 0' Comp 'OSCameraPos pos 1' Comp 'OSCameraPos pos 2' Comp = 0.15)
      CGVPParam
      (
        Name = TexShift
        Comp 'Wave' { Type = sin Level = 0 Amp = 0.25 Phase = 0.4 Freq = 0.1 }
        Comp 'Wave' { Type = sin Level = 2 Amp = 0.9  Phase = 0.55 Freq = 0.1 }
        Comp 'Wave' { Type = sin Level = 0.1 Amp = 0  Phase = 0.0  Freq = 0.1 }
        Comp = 1
      )
      
      Layer '0'
      (
        Map      = wave1
        ClampTexCoords
        Blend     'SRC_ALPHA ONE_MINUS_SRC_ALPHA'
        TexColorOp = NoSet
      )
    )

    //another COPY OF MAIN WAVE(detail )!! shifted phase  to make it move different 
    ShadeLayer
    (
      CGPShader = CGRCWater_Beach
      CGPSParam ( Name = Ambient Comp = 1 Comp = 1 Comp = 1 Comp = 1)
      
      CGVProgram = CGVProgWater_Beach
      CGVPParam ( Name = CameraPos Comp 'OSCameraPos pos 0' Comp 'OSCameraPos pos 1' Comp 'OSCameraPos pos 2' Comp = 0.15)
      CGVPParam
      (
        Name = TexShift
        Comp 'Wave' { Type = sin Level = 0 Amp = 0.25 Phase = 0.5 Freq = 0.1 }
        Comp 'Wave' { Type = sin Level = 2 Amp = 0.9 Phase = 0.65 Freq = 0.1 }
        Comp 'Wave' { Type = sin Level = 0.3 Amp = 0 Phase = 0 Freq = 0.1    }
        Comp = 0.5
      )
      
      Layer '0'
      (
        Map      = water1

        Blend     'SRC_ALPHA ONE_MINUS_SRC_ALPHA'
        TexColorOp = NoSet
      )
    )

    // Moving detail layer!!!!!!!!!!!!!!!!!!!
    ShadeLayer
    (
      CGVProgram = CGVProgWater_Beach_Shift
      CGVPParam ( Name = TexShift Comp = 0 Comp 'time 0.2') // xy = wavepos, z = 0, w = amplitude
      CGVPParam ( Name = TexScale Comp = 1.25 Comp = 3) // xy = wavepos, z = 0, w = amplitude
      
      Layer '0'
      (
        Map      = water2.tga

        Blend     'SRC_ALPHA ONE_MINUS_SRC_ALPHA'
        TexColorOp = Modulate
      )
    )
  )
)
#14
06/15/2007 (10:01 am)
That's not CG shading code. CG is almost identical to HLSL. Jacob's shader doesn't do anything to the water. It affects the terrain instead. Probably the best way would be to measure the distance between the water and the ground through a shader. If it's within a certain range, change the texture to x. I've seen a few implimentations around, but haven't looked into any. GPU Gems 2 has a chapter that covers this somewhat.
#15
06/15/2007 (12:19 pm)
Simply changing the texture to another is not going to do it.what I'm starting to wonder is if actualy shoreline geometry needs to be created. You can see it a little better in the FC editor. But the from a very high agle you can see what is seems like if you take a line where the water meets the sand and then extend a poly from that like in toward land and then to the same thing from the line toward the ocean that area you have just defined you get a whole new shader.

now wether it is done via actualy modeling geometry or some folmula that extracts the polys and use that to project the way that afx zodiacs work I don't know.
#16
06/15/2007 (1:58 pm)
@ James -- I found it pretty interesting that the waves were on the terrain rather than the water. This suggests that an AFX zodiac-like technique could probably be utilized here. Zodiacs won't work as is since they don't take an animated texture, and they are tuned for circular textures. With the added capability of an animated loop of textures and the shape changed to an elongated rectangular strip, you would have a building block for this effect.

Zodiacs work by identifying intersecting polys in the underlying terrain, and then drawing these polys on top of the terrain with their UVs re-calculated to show a proper projection of the zodiac texture. This same thing could be done with rectangular strips tiled along a shoreline, and unlike zodiacs, your shore is probably not going to move around, so all the polys could be pre-determined.

I think the real challenge would be getting adjacent strips to blend together without producing an obvious seam. It might work to just have the strips fade-off at the ends and then place the strips overlapped. There could also be curvature issues. You might have to do something clever with the UVs to curve them with the shoreline.
#17
06/15/2007 (4:30 pm)
The textures in that picture is seamless horizontally. An there actually is only one texture with and alpha channel the animation is simply transformaing and scaling the UVs of the texute similar to the cube in the TGEA walkthru demo. An it is being drawn trice with the second one that the opposite point in the animation cycle. I wonder if there is a way I can get a vid cap of it.
#18
06/15/2007 (5:34 pm)
If there's only one texture, that suggests a lot of manipulation going on in the pixel-shader.
#19
06/15/2007 (6:13 pm)
I really don't think the waves are on the terrain. It looks as if they're using multiple billboards with a foam texture that have basic UV animation.
#20
06/15/2007 (7:28 pm)
Here is it in motion so you can see it.

See it here

there is a main wave that has a copy of itself "as per what the code above says."That is slightly offset in phase. there there is a second single wave that is completly opposite in phase.