Researching a replacement for dynamic shadows continued…

I am still playing Nier: Automata so you will get a few of these pics for a bit.

A while back, I posted an article about researching a replacement for dynamic shadows.

On projects I have worked on we often default to using dynamic shadows to make stuff look good, but they can kill our performance on mobile. In order to hit the 60 FPS mark (or sometimes even 30) theya re one of the things we turn off. We then replace them with blob shadows, which are OK, but are still not as performant as we may like I found this advanced technique called graphics command buffers and a sample that includes decals in deferred shading. Decals are quite a nice way of creating blob shadows.
I have since knocked up a super quick test bed to see the difference between real time shadows, projectors and decal textures.
Realtime shadows:
Projector:
Decals:
And here are there corresponding BASIC stats:
Real time shadows:
Projector Blob Shadows:
Decal blob shadows:
Again, this is only a cursory test, but so far the decal blob shadows are edging out on the number of tri, batches and overall framerate. Of course this is needed to be taken with a pinch of salt and needs to be profiled more in other scenarios, however as a starting point it looks promising.
My next step is to see if I can create real time shadows using render textures and combine it with the decal techinque.
There is a warning here though that at time of writing this technique only supports deferred rendering and not ALL mobile gpus support it. However, I will press on and get a better overview of what hardware is affected, and come up with an alternative for that.
Share

Very Simple Obscuring Object Culling

This little trick is from something that I worked on that involved robots. So I added the Robot from Infinite Warfare (a game which I have, but need to actually finish… like all my other games!). Essentially there was a character that moved around an environment and attacked enemies. The problem was he sometimes got obscured by the environment. As it was a prototype, I made the quickest and dirtiest thing I could and whacked it in.

As the diagram shows above I raycasted from the camer to the player character. If the raycast hits anything marked “Obstacle” or equivalent term the object is deactivated.

This is SUPPPEEERRR basic. There are some cleverer things you can do like do a box cast and seeing how much an object is inside the box cast and fade it out, but if you need to get somehting up and running quickly then this is a quick and dirty implementation.

Share

Design Patterns – Observer

Today I am going to talk about the Observer Pattern. From Wikipedia once again:

“The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.”

In plain old English, the Observer pattern “Defines a dependency between objects so that whenever an object changes its state, all its dependents are notified.”

What does this amount to in the real world. So you know when you sign up to one of those voucher code sites for a specifc type of voucher and you get a notification whenever there is a new voucher type available? That is basically the observer pattern.

In game development a common use case is an Achievement system. It is an example that has been used multiple times, but hey, if it ain’t broke, don’t fix it. In a game, there are Achievements that can be obtained through a variety of different methods. Maybe you are working on Final Fantasy 12 and want to add an achievement that the player gets for shouting they are Captain Basch 1000 times.

If we aren’t clever about how we design this system, we could have a crazy spaghetti like thing that is linked to every part of our code base. This is bad, as the likely hood of you breakign the achievement system if you make a change or vice versa is pretty high. Are you thinking about using a Singleton for this? DON’T. This is a prime example of where not to use a Singleton. We want our nice Achievement system all lumped in one place and we don’t want to tightly couple the system to every single part of the code base. This is where the Observer pattern comes in. The pattern allows one piece of code to announce something has happenned without actually giving a damn who recieves the notification.

Let’s look at some nice C# code. Essentilaly the code can be broken down into two parts. The Subject  and the Observer.

First we will take a look at the subject. The subject holds a list of all the observers interested in getting information ewhen something cool happens. When said something has happenned, it sends a notificaiton to all the observers.

public abstract class Subject
{
    List<IObserver> _observers = new List<Observers>();
    
    public void Notify()
    {
        _observers.ForEach(x => x.OnNotify());
    }

    public void AddObserver(Observer observer)
    {
        _observers.Add(observer);
    }
    public void RemoveObserver(Observer observer)
    {
        _observer.Remove(observer);
    }
}

And to reiterate somewhat, the Observers are the objects interested in doing something when the event happens.

public interface IObserver
{
    void OnNotify();
}

In fact rather than going into the previously mentioned Achievement system, I am going to talk about the “I’m Captian Basch” bit in FF12.

What I want is the NPCs in a certain area to see if they hear it and increase the notoriety. In the below code I have already added the NPCs as Observers from some other system.

public class BaschShouter : Subject
{
...
    private void OnShoutedImBasch()
    { 
        Notify();
    }
...
}

So every time the player refutes Ondore’s lies:

public class NPC : IObserver
{
     public void OnNotify()
     {
          if (NPCIsInEarShotOfPlayer())
          {
              DontBelieveOndoresLies();
          }
     }
}

You also may have some NPCs that are loyal and stop you shouting and you have also registered those:

public class NPCLoyalToOndore : IObserver 
{ 
    public void OnNotify() 
    { 
       if (NPCIsInEarShotOfPlayer())
       {
            ChastisePlayerForLyingAboutMyLeige();
       }
    } 
}

And there we have it. Observer pattern.

Share