GameDev 2019 Week 17: Better Water
New Water Renderer, Sky, Fog, Editor Improvements11.05.2019 - 17:17
I created a proper class to create animated water textures and it uses the 3D periodic noise solution from the day before. It is set to produce 16 frames of 512x512 textures. You can imagine the 3D noise as blocks, which repeat themselves in all 3 axes, so the resulting textures tile in both directions and the animation also repeats itself seamlessly. Interpreting the noise in every single frame as a heightmap of the water surface, I then calculate a normal map from them.
To render the water I created a new class in my engine. It uses texture arrays for the frames of the animation and a custom rendering system with 1 vertex buffer and n texcoord buffers, one texcoord buffer per frame of the water animation. When rendering the vertex buffer and two texcoord buffers are bound depending on the time in the animation. The shader can then smoothly interpolate between the two frames. Previously I used a DuDv map to distort the water reflection and refraction, but I realized that the x and z values of the animated normal map also work quite well for that, so there is no need to have an extra DuDv texture bound. Finally I added a fresnel effect to the water, so the amount of reflection and refraction is based on the viewing angle. When looking directly from above a water surface there is very little reflection and a lot of refraction, while looking from a low angle results in a lot of reflections and almost no refraction.
So far I was only using the grayscale texture from the initial tests. Today I added some color to it. I used a mix between a darker and a brighter cyan and I also colored the highest parts of the heightmap - the top of the waves - white, like the white foam on top of waves. This already created a very nice texture. Then I added the texture and the normal map to the editor and experimented with a bunch of different settings, changed the colors slightly, changed the normal map "steepness" until I found something that I liked. However, the sky was just a single color, which is not very realistic. So I added a skybox with a color fade from the bottom to the top, but the skybox produced noticable artifacts in the corners, so I changed it to a sky quad that rotates with the camera and doesn't have any artifacts. I also limited the cameras rotation to the upper half sphere, so you cannot look from below the ground or below the ocean surface, which would break the illusion of the sky. Finally I added distance fog to the water shader, so it gets a little bit hazy in the distance and the fog color is the same as the lower sky color so there is a very nice transition between the water and the sky.
The aforementioned water and fog parameters were hardcoded in the code or the shader. So I added shader uniforms for the fog color and density, as well as the water lighting parameters, the water scale, the water reflectiveness ( the mix between reflection and refraction ) and the water clearness ( the mix between the reflection/refraction and the color texture ). I refactored the editors water class and moved all the water parameters into their own class and added variables for the fog settings. Then I added a color selection button and an edit field for the fog density to the general map options in the editor and completely reworked the water options window, so there is now a way to change all the options in the editor. I also added a new spin box utility class to my menu lib, which is just an edit field with a plus and minus button next to it, and used that for most of the parameters.
Today I added all the different options to the editors project save files and made sure they get restored correctly when a project is loaded. I also added the new options to the export files, while trying to keep some backwards campatibility, so older exports can still be loaded. Then I created a new functionality to create the terrain heightmap from an image and in the evening I made some more environment models in Blender: 2 bushes ( I'm not really happy with either of those ), a mushroom ( which started as a bush with a stem, but looked more like a mushroom, so I just made it a mushroom ), a stone and a wooden dock.
First I did some cleanup in the water class and shader, and I also moved the shader from the map renderer into the engines water class, because the shader is only ever going to be used to render the water surface, so it may as well be in the same class and not clutter anything else. Then I added the water texture and normal map to the map assets, so they are copied when the map is exported and are referenced relatively in the exported map. I also added the distance fog to the the terrain and model shaders, changed the ambient and diffuse lighting factors to uniforms and created spin boxes in the editor to change them. Finally, I removed the specular maps from the terrain, because I wasn't really using them and almost all terrain isn't reflective anyway. Then I just had some fun placing random models and made a nice little island. I gotta say, I really love the new water :)
by Christian - 11.05.2019 - 17:17