Friday, May 1, 2020

Improving The 2D Noise Page

One of my goals for 2019 is to improve my existing pages. Yesterday I decided to work on my old 2D noise page. We normally use Perlin/Simplex noise to make terrain heightmaps, but on that page I used Fourier transforms instead. Perlin/Simplex noise are a fast approximation of the things you can get from Fourier transforms.

The 3D renderer on that page always bothered me. It was one of my early experiments with WebGL. I had never been able to figure out exactly what I didn't like or how to fix it.

I decided to improve the renderer.

I read through the code to and realized it was written so long ago that let and const weren't even widely available! I started by updating the code style to match the code I write today. I read through the rendering code and decided to switch from raw WebGL to regl.js, which lets me experiment and iterate much more quickly.

I wanted to compare the old and new output easily, so I put them side by side on the page. I wanted to try two techniques with the new renderer:

  1. Instead of building a new 3D quad mesh on the CPU every time the data changed, I built a single 2D triangle mesh with x,y, and then read the heightmap data from a texture on the GPU. Reading textures from vertex shaders is widely supported now. This way, I only have to update the texture on each render instead of rebuilding the mesh. Unfortunately I couldn't figure out why it wasn't interpolating pixels values; I had to put in my own interpolation.
  2. Instead of calculating normals and lighting on the CPU every frame, I calculated them in the fragment shader on the GPU. But I didn't want to use a standard lighting system; I wanted to apply outlines instead. I had learned how to do this in mapgen4 and wanted to try an even simpler approach here. This worked out really well.

In this comparison you can see how the dark/light spots in the noise are renderered in the two renderers. With the old renderer (green) the color changes but the shapes are all mushy. With the new renderer (gray) the dark/light matches the noise, and the mountain peaks are easier to see.

2D noise values Old renderer New renderer
Landscape: old (green) and new (gray) renderer

In smooth areas you can see how the outlines help show the shapes. You can also see that the old renderer flipped the elevation upside down (oops!).

2D noise values Old renderer New renderer
Smooth area: old (green) and new (gray) renderer

With blue noise (positive exponents) the new renderer looks much better:

2D noise values Old renderer New renderer
Blue noise: old (green) and new (gray) renderer

I'm really really happy with outlines! Compare:

No outlines Light outlines Medium outlines
Without and with outlines

The outlines are one line of code:

void main() {   float light = 0.1 + z - fwidth(z) * u_outline;   gl_FragColor = vec4(light, light, light, 1); } 

I darken the color based on fwidth(z). The GL extension OES_standard_derivatives calculates how much an expression changes from the current pixel(fragment) to adjacent pixels. When z changes a lot, that usually means it's changing from one mountain peak to another, so I darken the output color.

There are still more things I'd like to improve on this page, but the renderer was the thing that bothered me the most, and I'm now happy with it. The other changes will wait until another day.

The New Angry Birds Game Is A Master Class On Hyper Casual Game Design

I have already discussed this subject here and here, but, from time to time, I like to bring it up again just to remind myself of the huge potential of hyper casual games in the contemporary scenario.

The inspiration for this text was the new Angry Birds mobile game named "Dream Blast". Created by Rovio Studio, the game is an excellent example of how it is possible to create an interesting gaming experience using hyper casual game design. 



The game mechanics consist of a very simple touch-screen gesture where you must destroy two or more connected balls of the same color. If you destroy four or more balls, you will create a red bird. If you create two red birds side by side they will become a yellow bird; and, finally, if you create two yellow birds side by side you will create a big black bird. Each one of them, when touched, explodes in a different way destroying more or less of the scenario. 

The interesting part of the gaming experience comes from how the levels show interesting and varied challenges just by using a touch movement in the screen. The video below shows the intro and some of the main features of the gameplay:



Obviously, Dream Blast uses a business model based on virtual coins that the player can earn by playing or just buying them from the game store. 

Another interesting point of this subject is: how platforms like Google Stadia and Apple Arcade will change the "ecosystem" of the hyper casual games. Will they attract this kind of players to simple experiences with multiscreen possibility? But that's a subject for another post.

#GoGamers