How to tile a Heightmap the simple way


First you need to make sure the heightmap is divisible by 2

A triangle has 3 vertices and here is what I do for my triangles:

struct TVertex
{
—-float x;
—-float y;
—-float z;
—-TVertex()
—-{}
—-TVertex(const TVertex& v)
—-: x(v.x), y(v.y), z(v.z)
—-{}
—-TVertex(float x, float y, float z)
—-: x(x), y(y), z(z)
—-{}

—-bool operator == (const TVertex& o)
—-{
——–if (x == o.x)
——–{
————if (y == o.y)
————{
—————-if (z == o.z)
—————-{
——————–return true;
—————-}
————}
——–}
——–return false;
—-}
};

class Triangle
{
—-TVertex hypotenuse[2];
—-TVertex vertex[3];
—-short indice[3];
—-short hypotenuseIndices[2];
—-DWORD color;
public:
—-Triangle()

};

 
** Spill about Vertex and Index Buffers **
The index buffer or indices acks as a lookup table for the vertices.
If there are 5 vertices then the index 0 – 4 refers to each of the vertices.
One could set the order of rendering the vertices through the index buffer.

indice[0] = 0;//This refers to the first vertex 0
indice[1] = 2;//This refers to the third vertex 2
indice[2] = 1;//This refers to the second vertex 1

Each tile will be NxN wide and will contain triangles where N can be 1, 2, 4, 8, 16, 32 up to the size of the map
and N is the base value so we *know* how many tiles to create. Use mapsize/2 and stop when the remander is N
use a counter during the process and this counter variable is half the amount of tiles, so counter*2 will be
the entire amount of tiles. For the amount of triangles use N*2=t to get the amount of triangles per row.
then get that number t*N to get the total amount of triangles. (or use (N*N)*2 for total amount)
This is number of vertices -> number of triangles * 3 (each triangle has 3 vertices) and N is the tilesize.
If N is = mapsize then there is only 1 tile and will load the regular heightmap.

Here is an example:
each tile will be 32×32 wide and it will contain triangles
need to / map size by 2 until we get 32 and increment a counter through this process:

lets say the map is 512×512

c=0
512/2 = 256
c=1
256/2 = 128
c=2
128/2 = 64
c=3
64/2 = 32
c=4

there will be c*c = 4*4 = 16 tiles
number of triangles = 32*2 = 64 triangles for one row -> 64*32 = 2048 total triangles
number of vertices = 32*32 = 1024 vertices for tile

 
Main Algorithm:
To actually load the terrain properly need to get the number of tiles in the heightmap

int counter = 1;
int size = MapSize;
while (size != N)
{
—-size /= 2;
—-counter *= 2;
}
NumTiles = counter*counter;
int Row = counter;
At this point we can load each tile which has a boundary that describes the location of the tile.

TBoundary b1;
TBoundary b2;

int lower1=0;
int upper1=N+1;
int lower2=0;
int upper2=N+1;

for (int h = 0; h < Row; h++)
{
—-for (int w = 0; w < Row; w++)
—-{
——–b1.lbound = lower1;
——–b1.ubound = upper1;
——–b2.lbound = lower2;
——–b2.ubound = upper2;

——–//Load tile here

——–lower1+=N;
——–upper1+=N;
—-}
—-lower2+=N;
—-upper2+=N;
—-lower1=0;
—-upper1=N+1;
}

 
The values that were describes at the beginning of this article are first calculated.

numTriangles = (N*N)*2;
numIndices = (N+1)*(N+1);
numVertices = numTriangles*3;

tris.resize(numTriangles);

This will be the tiles boundary
boundary1.lbound = b1.lbound;
boundary1.ubound = b1.ubound;
boundary2.lbound = b2.lbound;
boundary2.ubound = b2.ubound;

 

Create each triangle
This is the vertices for the tile
vector<TFVF> verts;

To create the tile we must iterate through the upper and lower bounds of the tile.

int tx = 0;
int ty = 0;
int vindex = 0;
for (int y = boundary2.lbound; y < boundary2.ubound; y++)
{
—-for (int x = boundary1.lbound; x < boundary1.ubound; x++)
—-{
——–TFVF v;
——–v.x is -x
——–v.y is -height or 0
——–v.z is y
——–tx++; this is for height the height values are in array format
—-}
—-ty++; this is for height the height values are in array format
—-tx=0; this is for height the height values are in array format
}

 
This algorithm is used with a Vertex Buffer Object so no Index Buffer is needed.
The indices are used for each triangle to find the vertices of the triangle.

indices[0] = x + N + 1;
indices[1] = x;
indices[2] = x + N + 2;

tri1->setIndices(indices);

indices[0] = x + 1;
indices[1] = x;
indices[2] = x + N + 2;

tri2->setIndices(indices);

 

Once each vertex is found each triangle will be filled with its vertexes.

for (int tri = 0; tri < numTriangles; tri++)
{
—-//First look at the triangles indices
—-short index[3];

—-index[0] = tris[tri]->getIndices()[0];
—-index[1] = tris[tri]->getIndices()[1];
—-index[2] = tris[tri]->getIndices()[2];

—-TVertex v[3];

—-v[0].x = verts[index[0]].x;
—-v[0].y = verts[index[0]].y;
—-v[0].z = verts[index[0]].z;
—-//DWORD c0 = verts[index[0]].color;

—-v[1].x = verts[index[1]].x;
—-v[1].y = verts[index[1]].y;
—-v[1].z = verts[index[1]].z;
—-//DWORD c1 = verts[index[1]].color;

—-v[2].x = verts[index[2]].x;
—-v[2].y = verts[index[2]].y;
—-v[2].z = verts[index[2]].z;
—-//DWORD c2 = verts[index[2]].color;

—-tris[tri]->SetVertex( v );
}
After all of this is done the Vertex Buffer needs to be created.

And rendering each tile in the terrain mesh is trivial once it is all setup.

 

I will be writing another blog that explains the advanced algorithm I currently use

for tiling terrain with with index buffers and LOD soon.

 

-Dustin Watson

Making Mindless Monsters Matter More


Undead and other mindless creatures are popular choices for antagonists in fantasy games. Anything you can find alive in your fantasy world, you can also find dead, and anything that can be dead, can be undead. Plants and people are popular choices, and you can usually find everything from zombie sharks to vampire trees if you know where to look. Anything that isn’t necessarily alive can be animated. Rocks, slimes, and oozes also make good mindless minions.

Just because these creatures are popular and easy to insert into a fantasy setting, doesn’t necessarily make them the best choice for every game. Though oozes make popular low-level enemies in role-playing games, their presence very often isn’t explained, or otherwise barely justified. Undead can also be overused, particularly zombies, especially when allowed to endlessly re-spawn. Players can be left to wonder if there are more undead than there are living.

It’s important then, if you’re going to use mindless creatures, to have them somehow tied to the setting. The more specific and detailed your creatures are, the better. Even if all you’re doing is re-skinning the same zombie sharks for this aquatic zone as the last one, make them part of a unique mob, give them a special creator or back-story, or give them something to set them apart from the rest of the similar creatures in the game.

If your game contains a lot of grinding, remember that the players are going to see these creatures a lot, and it’s up to you to make the fights as unique as possible. This can sometimes mean putting a lot of little variations in your monsters that might appear at random after a few battles. Giving a creature a unique sound, attack, or even a bizarre war cry can be a cost-effective way of enhancing an otherwise humdrum encounter.

Consider creating templates for your mooks, which generate slight variations. Sometimes a monster might be said to smell terrible, sometimes lurch when it moves, or rattle and wheeze as it attacks. Perhaps a pack of piranha plants might bark and snap at the player’s heels. It isn’t strictly necessary that these variations have a numerical game effect, though anything you can add to make your mindless monsters different from one another is something to consider.

When you make a new monster, make sure you can answer some basic questions about what the creature is, where it came from, and why it was made. Did it spontaneously appear from nature or was it created by a character? Why was it created? Is it a guardian or a roving beast? Is it a solitary creature or does it tend to travel in packs? Does it have any needs or desires? Also important to consider: do the powers you’ve given the creature support the your answers?

Try to never include monsters as padding or filler. Your players will notice the flaws in a monster, and even if you’ve done a thorough job of fleshing it out (whether it has flesh or not), they’ll still poke holes in them. Your job is to make that difficult. One tip to leave you with: when designing any monster, give it a secret that will never be revealed in the game. Take this secret into account as you develop the monster’s concept, but never show it to the players.

~Nick Foster

Follow me on twitter!

https://twitter.com/#!/dither001

Fast Resource Mapping


So, it may be a while until I actually start implementing the better DOF, but until then I will be working on Screen Space Billboard Reflections (SSBR). An issue that I ran into, that I thought I would never have to deal with, is parsing textures at extremely fast rates.

The majority of the cycles are spent finding the 2D texture coordinate from the current buffer index. While my approach to the issue isn’t the best, it decreased load time from 27.8sec to 22.4sec with 150 512×512 textures.

What my approach does, instead of calculating Y on every cycle, it just calculates every X amount of cycles. This saves over X – 1 ticks for every Y. Remember, even the simpliest modification can have a massive impact on your program

~Louis Castricato

Apology


Sorry guys, no new entry from me this week. I’ve been very busy, and haven’t had the time to work on any implementations

 

Hopefully I will make up for it next week

 

~Louis Castricato

Better Depth Of Field


After testing my implementation for energy conserving Blinn Phong, I looked for more next gen algorithms, seeing if I could strike gold yet again.

I found this: http://research.nvidia.com/publication/real-time-stochastic-rasterization-conventional-gpu-architectures

 

It seems very interesting, and I will post updates on implementation progress here daily 

 

Oh, and Billboard reflections are 35% done, and I will be working on optimizing my ray caster today, and then finish the GPU accelerated side tomorrow. It should be done by Wens. or  Thursday next week.

~Louis Castricato

AI – Behavior Trees


Behavior Trees

 

In AI a behavior tree can be considered among most to be the best data structure to use when it comes to
achieving different states among an Artificial Intelligence.

What is a behavior tree?
It allows the programmer to stack up different behaviors with actions and conditions at the heart of
the behavior tree. It uses sequences and selectors that are complements of each other because a
sequence will bail out on success and a selector will bail out of the tree on failure.

A behavior tree has a root that branches off into a list of behaviors that each contain a selector.
A selector can be a priority selector or a dynamic selector. Each selector will contain a list of nodes that contain a decorator object.
There can also be a node that just contains an assertion check that only checks if a certain condition is true.
A decorator is an object that adds new functionality to an object without creating a new object.

There are many types of decorators that can be created and the designers will love then because you will
find them using decorators for just about anything.

Some different types of decorators include:
Semaphore: For resource allocation so that two animations or more than one of anything will not be played at the same time.
Wait: Signals the tree that a sub tree is not accessible yet until a time in seconds has passed.
Loop: tells a sub tree to keep executing.
Continue: Everything that is not a selector will return success, otherwise failure.

The decorator object will contain an action and a condition. An action is something that the AI will do like ‘throw grenade’
and a condition is something that must pass like ‘can I throw a grenade’ in order to succeed.

For each behavior one could answer the question of “What happens if…”
For example:
What happens if patrolling
-> I am walking/moving
-> I am …

With all of this logic put together one can easily create a simple solution to the complex problem of behavior trees.

The Behavior Tree can also contain a Parallel node that basically run every sub tree and list of assertions at the same time.
If just one fails then the entire parallel node fails.

 
A behavior can be created like this for those of you who know C++:

Behavior<AIGuard>* combatBehavior = new Behavior<AIGuard>(“Combat”);
{
—-//Create a priority selector for the combat behavior
—-Selector<AIGuard>* combatBehaviorSelector = new PrioritySelector<AIGuard>();
—-{
——–//SEQUENCE 1 (ATTACK)
——–//Create a sequence for the combat behavior that the priority selector will select
——–Sequence<AIGuard>* combatBehaviorAttack = new Sequence<AIGuard>();
——–{
————//Create a node for the attack sequence
————Node<AIGuard>* combatBehaviorAttackNode = new TaskNode<AIGuard>();
————{
—————-//Create a decorator the the combatBehaviorAttackNode
—————-Decorator<AIGuard>* combatBehaviorAttackDecorator = new Decorator<AIGuard>();
—————-{
——————–//Now create a action for the decorator
——————–Task<AIGuard>* attackAction = new Task<AIGuard>(“ATTACK”);
——————–Delegate<AIGuard, Status>* attackDelegate = new Delegate<AIGuard, Status>(guard, &AIGuard::doAttack);
——————–attackAction->AddAction(attackDelegate);
——————–//Now create a condition for the decorator
——————–Delegate<AIGuard, bool>* attackCondition = new Delegate<AIGuard, bool>(guard, &AIGuard::canAttack);
——————–combatBehaviorAttackDecorator->AddDecoratedComponent(attackAction);
——————–combatBehaviorAttackDecorator->AddCondition(attackCondition);
—————-}
—————-//Finally we can add the decorator to the node
—————-combatBehaviorAttackNode->AddDecorator(combatBehaviorAttackDecorator);
————}
————//Add the attack node to the attack sequence
————combatBehaviorAttack->AddChildTask(combatBehaviorAttackNode);
——–}
——–//Add the attack sequence to the priority selector for combat attack
——–combatBehaviorSelector->AddSequence(combatBehaviorAttack);
——–//SEQUENCE 2 …
—-}
—-//Add the combat attack priority selector to the combat behavior
—-combatBehavior->AddSelector(combatBehaviorSelector);
}
//Finally Insert the combat behavior into the behavior tree
mBehaviorTree->InsertBehavior( combatBehavior );

If you want to know more about behavior trees see aigamedev.com
Alex j. champandard is the main person there that talks about behavior trees.

More on AI will soon follow.

-Dustin Watson

Energy Conserving Blinn Phong


I knew I wasn’t the only one who thought current gen BDRF looks horrible, so I started looking around for better techniques. I ran across Energy-conserving Blinn-Phong, and my face instantly lit up.  It uses physically based shading, which allows for very simplistic debugging. It is also extremely close to current gen Blinn-Phong implementations, allowing it to be inserted in almost any current gen application.

The algorithm is as follows:

Where:

 is Schlick’s Approximation

n is a normalized vector

 is the light direction

  is the notation for clamping to 0

 is the the specular power parameter

And now, for the moment you’ve all been waiting for….. An implementation! 😀

float4 BlinPhong
(float3 g_CameraDirection,
float3 n,
float3 LightCol,
float3 LightDirection,
float3 SurfaceMaterial,
float h,
float spec)
{

float3 HalfH = normalize(g_CameraDirection + LightDirection);
float2 b = float2(dot(n,HalfH), dot(n, LightDirection);
float3 Col = ((spec + 2) / 8) * clamp( b.x, 0, b.x);

Col = pow(Col,float3(spec, spec, spec));
Col = mul(Col,fresnel(SurfaceMaterial, LightDirection, h));

LightCol = mul(LightCol,clamp( b.y, 0, b.y));
return float4(mul(Col, LightCol), 1);

};

And now, how to calculate Schlick’s Approximation

float fresnel
(float3 H,
float3 V,
float F0 )
{


float base = 1.0 – dot( V, H );
float exponential = pow( base, 5.0 );
return exponential + F0 * ( 1.0 – exponential );


};

 

~Louis Castricato

 

About The Arbiter of Darkness


This game will encompass 3D visual elements and will be an RPG action type game with mostly action elements and it will be using the WZ Game Engine for development which we are converting to C++.

The game itself will span over different areas like an Island, a forest, and a sky village and much more, also this game will be moddable and the MOD content will be something extra with the game. I am creating a Quest Editor for the MOD content, which is currently underway.

I am using DirectX11 Dynamic Hardware Tessellation for the Terrain Engine and the engine will support Collada format (.dae)

To make things look good in the game I will be working trees and vegetation to help give a good visual element to the terrain.

More to come soon!

-Dustin Watson

Radiosity – Pt 2


In the last post, I talked about Radiosity using the hemicube method. Don’t be turned off, but this is the essentials of almost all radiosity algorithms (And the sample I linked to provides an amazing framework)

Although, in this post, I will talk about a method that dates back the some of the earliest developments in radiosity: Instant Radiosity. The original thesis can be found here: http://giga.cps.unizar.es/~diegog/ficheros/teaching/instant_radiosity.pdf

The concept is once gain very simple. Shadow map is rendered from the perspective of the light, and a flux scale is then computed. Using the flux scale, and halton distribution, VPLs are placed and re-rendered as individual lights. Back then (Before deferred lighting) this was very computation heavy. But as time advanced, this became simpler and simpler.

Like most VPL based algorithms, this requires a fairly large GBuffer and the scene is very limited in complexity. This method is not ready for a commercial usage, but hopefully will reach that point in a few years. Its a shame, since other VPL methods have advanced past this, but this one remains stationary.

If you are willing to lose quality for speed, then I have just the thing for you. You can use a ray tracer to cast lit pixels on screen. I have some code that I put together in about 10min, and it can be downloaded here: http://www.megaupload.com/?d=J50CYMKD

Still a lot more to come! Thanks for your time

~Louis Castricato

First Post – All About Radiosity


Radiosity seems to date back to about the 1980s, when computer graphics were just starting to come into shape, and some of todays ideals were still working in their parents garage.

 

TRADITIONAL

The idea is simple, the entire world (Patches)  is split up into something called form factors. An easier way to simplify this is, imagine that all games looked like minecraft. Electrical forces would infinitely bounce between the premade voxels,  sort of like a ray tracer, or octree rendering.

 

The points would bounce until the irradiance factor was < the falloff rate. In that case, all light is absorbed and the color of the patches are then multiplied by their irradiance factor.

OPTIMIZATION Ver 1

As you may realize, this is very slow at an extremely large scale. Some further developments have been made to bring this into the real time realm, but an old classic is the hemicube implementation. The idea behind this is single, every patch has its own render target, and all visible patches are then picked. After that, any selected patches are simulated, and baked.

This is a very large improvement over traditional radiosity since it basically has its own version of culling.

Sadly, this is still far too slow for any realtime application, and can’t be used in most games since it removes the ability for dynamic meshes

An implementation on this can be found here:

http://mynameismjp.wordpress.com/2011/01/31/radiosity-dx11-style/

 

Stay tuned for further articles, about Radiosity, Post Processing, Content Loading, Terrain Rendering, Atmospheric Scattering, and much more!

 

~Louis Castricato

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Design a site like this with WordPress.com
Get started