Advertisement Jump to content
  • Advertisement
Sign in to follow this  
  • entries
  • comments
  • views

Progress & Water

Sign in to follow this  


Progress & Water

Last night I added some new features to the level editor, including 'Select All Tris with Material'.

There already exists a pretty good smart selection routine that will travel through a connected mesh in order to find other tris to select. You can use this to select all connected tris of a material, but if the tris aren't connected, it's click city.

Also, I added routines to select triangles enclosed by selected vertices, as well as selecting the vertices of selected triangles.

Also I made the in-game & engine decals so that they don't show up on backfacing or >90 degree surfaces from the projection plane. This prevents stretching of the decals, and from them inadvertently showing up on the back of walls.

Just today I started on part of the trigger system. At times game designers may want to hide part of a level from the player until a certain event occurs, for instance, until you open a door, you might not be able to see behind it. This turns out not to be a trivial problem to solve in the cleanest possible way, but I think I've found a decent compromise solution.

The idea is to have OBB trigger objects in the level. When a trigger is touched, entered or left by a player character, then the trigger is 'triggered'. At this point, it can perform one of several things, including turning on and off other triggers.

Certain triggers are placed by the designed to indicate areas that should be initially hidden from the player. When the engine gathers material chunks to render, the chunks will be culled against the on-screen occlusion trigger boxes first. If any material chunks AABB lies fully within one or more hidden trigger box AABBs, then it is not drawn.

One approach would be to clip all geometry to all trigger boxes, so each part could be turned on and off individually. This seems like a huge pain, so the simpler method of simply culling chunks if possible, and then drawing the opaque boxes to the z buffer to start the scene seems like the best approach.

Here is a prototype shot of a black box in the level. It's wrong right now b/c the engine is actually drawing the box as geometry, so it's shadowing things, and also its not doing any
culling - I was just curious how it would look in game.

black box

Water, Part 1

Ok, now on to the water. Now just to start, there is nothing particularly innovative about the water, to my knowledge. It is a mix of vertex and pixel effects with true refraction and fake reflection. Once the technical part was functioning, it took me a couple of days of mucking with the art to get a decent look. I'm sure a real artist could do better.

Actually, the system in my game is for liquids in general, but right now the water is the only one with the art worked out. We will likely have lava, scummy water, etc.

The first step is to identify one or more triangles that will make up a water surface. The idea is that the water surface vertices would be simulated via a simple 2d method, and that the surface would be able to detect being hit and generate ripples, etc.

One classic method for making water ripple relies on the water vertices being on a regular grid. This wasn't going to work for me, however, because I wanted rivers that flowed around corners, without having to simulate a giant grid underneath the entire level, or to make several connected grids manually.

So, I took the method in game gems 4, and modified it so that instead of each water vertex looking at its n,s,e,w neighbors by direct index math, it instead stored the index of its n,s,e w neighbors explicitly. This is a little bit of a waste for vertices internal to the grid, but it means that you only need exactly as many vertices as you are going to simulate. The code itself is fairly straightforward - each vertex's height is simply an average a force pulling it back to zero and the differences with height of its neighbors. This looking at the neighbors is what causes ripples to flow from one place to another. There are various parameters you can tweak, like how badly the vertices want to return to zero, and how much you weight your neighbor height differences.

It's fairly easy to just use the height difference with each neighbor as the approximate x & z part of the vertex normal, and choose a y, like 0.5, and then renormalize it in the vertex shader.

Then, you can reflect the eye through the per-vertex normal, and look it up in a cubemap. Blend this with the frame buffer ( containing the pool bottom ) depending on the per-vertex fresnel term.

The Fresnel term is the idea that when looking at water from a low angle ( like the ocean far away ), it reflects perfectly - there is very little refraction. Look at water from top down, and it looks very much refracted, and very little reflection. Typically this is calculated via something like 1-E.N or 1-(E.N)^2, etc.

This is one of the most important effects for water. It also is very key for doing skin shaders, and cloth shaders. Making something like cotton or denim clothes light up on their edge is accomplished with the Fresnel term - this can make materials look soft, and reflective things look like liquid.

So, in the interest of doing to simplest thing that could possibly work, I implemented just this, with an alpha blended texture on the liquid mesh and the cubemap, but it looked really fake. The lack of detailed movement just didn't look like water. I'm sure a better artist could have made it look decent,
and this is still a valid method for non-shader hardware.

water 1

The next step I tried was a better texture on the water, where I could calcuate the fresnel per pixel with a normal map. This is simply 1 - e.n, which boils down to eye.z in tangent space. If the eye is low in tangent space, blend in more cubemap, if high, show underneath the water.

water 2

This looked a bit better, but still wasn't what I was after. Over the next few updates, I'll talk about refraction, fresnel, reflection, fog, and water shadowing.
Sign in to follow this  


Recommended Comments

That's what I'm talking about. Awesome post, I learn more here than I do in my Comp Sci class.

Share this comment

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!