Thursday, October 18, 2012

Using a texture for data

For coloring the world I was putting the color value into the vertex. then in the pixel shader i would multiple the color by that color percent. this worked, however it depended on the size of the triangle and even more importantly it required changing of vertex data. So I had a dynamic vertex buffer and was setting data to it each frame. However this became a problem when the grass was added as it had 17 vertices and 84 thousand objects.
So after reading an article about GPU particle systems from Jon, i realized I could use a texture to hold the color value of that area. The texture would be like a grid over the world such that every spot on the world points to a pixel in the texture (which holds a float of its color value). I can calculate that location in the pixel shader (or vertex shader for the grass) by (position.X - minWorldPosition.X) / worldSize.X. Then i can do the same for the Z axis. I do not consider the Y axis for this, although i could use a 3D texture if i wanted to include the Y axis.
The nice thing about this is to change it i do a draw call and the GPU handles it (which is very optimed for exactly this). I have a circle in a vertex buffer which is what i actually do the draw call on. I set a scale and translation matrix for that circle in the shader so the circle will be centered to where i want it and the size i want. I wrote the circle's vertex positions in screen space (which is really texture space) so i only needed to scale and translation, not project.
This would set all of the values on that circle to the color percent. However i also wanted a gradient. So I used the Z value of the vertex position (of the circle's vertices). I wasn't using the Z value because i was drawing right to a texture of floats, aka i didn't have a depth buffer and so wasn't doing any depth testing. I set the center of the circle to a Z value of 1 and the outside edges to 0. Then when the pixel shader got that value it was between 1 and 0 for how far out it is from the center. Thus i can set it darker or lighter according to how close it is to the center.
Then for lighting the world i used an alpha blending of Max. Where it would take the larger value between the value i was setting from the draw call and the value that was already on the texture. And for darkening i used a Min alpha blending.

Overall this helped the efficiency of this tremendously. Although the grass itself still needed more optimization (such as cpu visibility culling). But i learned a lot about shaders doing this process and any time i need to pass a lot of dynamic data to a shader i will first look into using a texture.

Monday, October 1, 2012

Change in philosophy

This weekend was interesting for making the game. we had a working version of the game but it was very simple and did not feel like a game. The giant just walked around and the lanterns were simple. However Sagar is working on the giants and Jon is working on the lanterns. So i decided to take on atmosphere of the game instead of gameplay mechanics. To do this i made grass that moves by wind and snow.
The grass was interesting to make, at first i made it without it moving. but grass that does not waver at all looks strange and not like grass. So I made it bend. However i made it bend away from the player so the the wind is coming out from the player. However when an object is bending away from you it isn't easy to tell what it is doing because the only real change you get is that it gets shorter. So the grass looks like it is just getting shorter and taller. Also i have them all oscillate at the same time which is also not how grass works. Wind as it goes through makes the grass bend in some local areas and not bend in others. So i need to implement the bending of the grass using a sine wave that will move through the area. Overall it was good because i am challenging myself in making both the particle system of the snow and the grass.