At the end of the last part, I had coded up a shader which draws a sphere as a texture. I wanted to continue on with this until I rendered atmosphere correctly with blue skies and red sunsets. However, I am finding it a real chore to debug shaders. I'm not sure what tools other people use. Google finds something called GLSL Devil that looks like a complete tool, but other comments on the net don't seem to think too highly of it. I also didn't want to risk messing up my development environment installing that or another low-level debugger. Instead, I did something else. The problem with debugging the shaders isn't the syntax or other details of the code. The compiler messages are terse but they do the job. Instead, the problem is debugging the algorithm. I want to walk through statements and see intermediate results, and put out trace files. Some of the advice on the net tells you to just draw intermediate results as graphical output. If the shader variable is 0, you'll see black. If it's 1, you'll see white, etc. That's not what I'm used to. So I coded up a little testbed for shader logic. In the full app, I can hit my debug key, which sets a flag causing the shader inputs to be written to the trace file. This is only for the quad and shader I used to render the planet. I write out the vertexes and the transform matrices. The testbed takes this input and renders the quad. This is not an OpenGL application. A simple rendering path is implemented in C++, with the code setting pixels in a bitmap. The important thing is the inner loop. After I have all the interpolated shader inputs for a pixel, I call a "shader" method. This method has all the same logic as the real fragment shader does, but written in C++. I can step through it and debug it normally. When the logic is right, I can translate that into GLSL without much trouble. It took me a couple of days to get that the way I wanted it, but then I continued with rendering the planet. More Planet ShadingFirst, I added diffuse lighting, then a specular highlight from the sun. This makes the entire surface shiny, including clouds and land. To make only the water shiny, I needed to mask everything else. I regenerated the terrain texture and used the alpha component to indicate the "shininess factor". Currently, this is just the percentage of water showing at that pixel. A couple of weeks ago, I ran into this video of Earth from the space station (Figure 1). Flying over city lights looked so neat that I decided to add some to my planet image. I'm tempted to add an aurora, but I'm not sure how to get the effect you see in the video. I also need to do something more with clouds.
All three of these elements -- lights, clouds and (maybe) aurora, should be dynamic. As people build, there will be more lights. Cloud cover will change with the weather, and an aurora slowly shifts pattern around the poles. I can compute a completely new texture pattern for the world in the background, but a single texture isn't enough. Lights from the ground show on the dark side, but not so much on the light side. They are also dimmed by the clouds. To do this right, I needed a second texture, which currently has lights (on the red channel) and clouds (on green.) I changed the shader to combine these elements with the terrain, applying diffuse and specular lighting. This all seems like overkill, but if I use a static pattern of clouds or lights, it will be noticeable in the game. It will be raining at ground level (since I want weather to change there), but when you get high enough, the pattern would change to the static texture. It might even be useful to game play to see city lights, since it makes it easier to find communities. Of course, so would a map... Coding up a realistic city light pattern was more of a project than I wanted to do now, so I just used some simplex noise to make a lava pattern over the world. In Figure 2, you can see the results so far. We're looking at the dark side of the planet with bright lava below, partially obscured by clouds. You can see the specular highlight on the ocean, and see that it does not reflect off the clouds or land.
This doesn't look too bad, but I still have things to do here:
I spent the rest of the week fooling with some other shader experiments that didn't pan out at all, so I'm not going to write them up.
blog comments powered by Disqus |