Thursday, June 9, 2011

Soft Particles

Last weekend I made some tests on soft particles.
For now I'm just posting the visual results:

Hard mode


Soft mode

Monday, April 4, 2011

GPU Displacement Mapping

In these days I was studying some texture projection approaches. In order to make things more interesting I tried to combine this technique with Vertex Texture Fetch to achieve something like a geometry deformation effect.

The image below shows the result:

The red area represent the orthogonal texture projection. In the Vertex Shader I just fetch a displacement map to displace the vertices which are inside the projection area.

Considerations
This sample has been wrote in a couple of hours and it suffers from some limitations:
  • Only one projection is available.
  • The projection volume is not in Tangent Space.
  • Normals are not correct after the displacement.
The first point is trivial to solve and I won't discuss it. The second point is not a big challenge as well, the easier solution is to cast a ray and transforms the projection volume according to the intersection results. The last point seems more tricky than the previous ones. In order to get a correct normal after the displacement I need some extra informations in the vertex shader such the normals of the others shared vertices. The goal is to provide these extra informations as input to the vertex shader. Since I'm using DirectX 9, I thought a couple of approaches:
  • To render this technique in a single pass using a second data stream containing the adjacent triangles data. So, for each vertex I can transform and compute the average of the shared normals. The major drawback of this method is efficiency. This approach may fit better in per primitive stage (Geometry Shader) avoiding wasteful repeated computations.
  • To render this technique in two passes, storing in a texture the required vertex data and then gather any required vertex data through texture lookup. This approach avoids per vertex repeated computations but processes the geometry twice.
Another thought I've in mind is simply to use normal mapping. I guess even if the normal is not correct it won't be much noticeable in the result. Of course I have to prove that : )

That's it for now, any suggestions?

Saturday, June 19, 2010

Reference Counting

Dealing with a large number of shared object, especially in large and complex projects, involve us to take care about their relationship. Consider the example below:

// Create a new enemy and point the player to it
Entity *pEnemy = new Enemy;
player.SetTarget( pEnemy );

// ..
// The enemy dies and is deleted
delete pEnemy;

The player class is keeping a pointer to the entity it is focused on, but what happens when that entity is deleted? How is the player going to know? The pointer looks the same but doesn't belong to the previous entity. This is a common case of dangling pointer because the memory location the pointer was referring to is gone or has totally changed. This is the fundamental problem of shared objects. There are several approaches to solve this problem and one of these are reference counting.

How does reference counting works? The underlying mechanism is quite simple: an object will be kept alive until someone needs it, then, when nobody needs it anymore it will be deleted. To be able to use reference counting, our shared object needs to implement two functions: AddRef and RemoveRef. Whenever any part of code acquires a pointer to the object, AddRef is called, instead, whenever any part of code is done with an object it calls RemoveRef. The object keeps track of how many references it has. AddRef increments the reference counter and RemoveRef  decrements it. Finally, when the reference count is equals to zero, the object is deleted.

To make things easy to use, one possible solution is to place all reference counting functionality into a class and let any class that inherits from it to automatically become reference-counted.

// Reference counting class declaration
class RefCounted {

public:

    RefCounted() m_iRefCount(0) {}
    virtual ~RefCounted() {}

    void AddRef();
    void RemoveRef();

    int GetRefCount() const { return m_iRefCount; }

protected:

    int m_iRefCount;
};
// Adds a reference
void RefCounted::AddRef() {

    ++m_iRefCount;
}

// Removes a reference
void RefCounted::RemoveRef() {

    if( --m_iRefCount <= 0 )
        delete this;
}

Is Reference counting capable for every shared objects situation? Unfortunately not, there are a few drawbacks to keep in mind. The most important is to remember to call AddRef and RemoveRef correctly. If in the code there is an unbalanced number of AddRef and RemoveRef calls, objects will be never destroyed or they will be destroyed prematurely due to an incorrect reference counter value. The second drawback is that objects might get destroyed a bit too easily. This implies that for certain resources as a texture or geometry, would be preferable maintaining them in memory instead to destroy them frequently because load them from the hard-disk has an high performance cost. To avoid this problem can be used a resource manager that keeps an extra reference to all the resources. Finally, the last drawback is that it causes verbose code: it will soon be filled with AddRef and RemoveRef calls everywhere hindering the reading.

Thursday, February 18, 2010

Hello world!

Before starting this blog i had two ideas about how to use it:
1. To control the minds of all visitors with a special language, and in a possible future conquer the world.
2. To open a space where i can put and share all my projects.
Unfortunately the second choise seemed more user-friendly.

Seriously, I use to start every project with a little introduction, then, Hello World!