miércoles, 29 de enero de 2014

Deferred Lightning

A few months ago I gave a talk in the National University about game programming.
I asked the attendees a few questions, and was amazed that none of them had
heard about Deferred Lightning. They were still students, so its completely
normal they didnt have a clue about it, but being Deferred Lightning
such a cool thing, I thought on posting an introduction to it, for all
those game programmers that still havent heard about it.
In OpenGL and DirectX you have a limit as to how many lights can
lit an object, in PC and mobile phones, this limit tends to be 8, (in SGI
it used to be 16). Though you can have more than 8 lights in your scene,
the system has to decide at every frame and for every object which 8 to render.
For complex scenes like an indoor scene, where you have candles an torchlights
8 is never enough. Also, the rendering of 8 lights is VERY expensive, because
for every lit object the object has to be rendered once for each light. So you
end up rendering your scene 8 times.
This is where Deferred Lightning comes in. Deferred Lightning is a technique
where lights are not rendered through the normal fixed function pipeline, but
as a postprocessing effect AFTER the scene has been rendered with no lights.

To give you an estimate, without deferred lightning I used to render a scene
with 2 lights at 60 FPS, with deferred lightning that scene had 120 lights
at 60 FPS.

So Deferred Lightning is very cool. BUT its quite difficult to implement. It took
me in PhyreEngine 1 whole week to get it running the way it should. And it
has a few drawbacks, for example, Alpha Objects, must be rendered separetly
and to a different Render Texture and the composed at the end of the
rendering pipeline.

How does it works?

Well, actually, its very clever how it works.

First, the scene is drawn WITHOUT lights (that means everything is lit as if
it had a WHITE Ambient Light) to a render texture the COLOR BUFFER 
(that means, we render it to a separate texture NOT the back buffer)
We render the NormalDepthBuffer
to ANOTHER texture. The normalDepthBuffer is a texture which holds all
the Normal and Depth information of every pixel written to the Color Buffer.
That means after the scene render, we end up with two textures, the 
COLOR BUFFER and the NORMALDEPTHBUFFER
The Color Buffer holds the diffuse
color of the pixels rendered, and the NormalDepthBuffer holds de DEPTH
and NORMAL information of the pixels written in the Color Buffer.

When we have this two textures, we render the lights on top of them.
A Point Light is rendered as a Sphere, a Spot Light is rendered as a CONE
and a Directional Light is rendered as a PLANE.

We render this objects, on top of the COLOR BUFFER, accessing the
NormalDepthBuffer in the Light's Shader. With the informtion in the 
NormalDepthBuffer we know the Depth and Normal, of the Pixel
being rendered to, so we can calculate how much do we have
to LIT that pixel.

For example, if we are rendering a Point Light, we render a sphere
on top of the Color Buffer, and in the PointLight Fragment Shader
(that is being executed for every pixel written) we read the NORMAL DEPTH
BUFFER so we can calculate now much that particular pixel is being lit
(if its in the Point Light Attenuation range), and if it should be bright
because of the normal, because of specular effects.

After rendering all the lights, we end up with a COLOR BUFFER
that is lit by all the lights.

We then copy or postprocess that COLOR BUFFER to the Back Buffer
and voila.

Why is it so FAST?

Well, with normal lightning, we end up rendering:

Number of Objects X Number Of Lights(max 8)

With Deferred Lightning:

Number of Objects + Number Of Lights(any number)


Cheers!


 Deferred Lightning 120 lights running at 60FPS
 NormalDepthBuffer Texture
Normal Lightning, 1 Light running at 60FPS

Thoughts on Ogre, PhyreEngine, Cocos2d-x and Construct2

Through my career as game programmer, whether as a hobby
or as way of living I've used several engines, but the ones
i've used the most are Ogre, PhyreEngine, Cocos2d-x and Construct2.
I want to share a bit of what I've perceived on this rendering
Engines, particularly about the power, architecture and
ease of use they have.

OGRE
I think Ogre should be one of the KEYS to learn game programming.
It is VERY powerful, yet very easy to use and master. I used
it for many projects, videogames and VR alike, and honestly
speaking, I could not find something I could not do through
Ogre. Something I particularly enjoyed about Ogre is that its
so well planned, maybe I didn't know how to accomplish this or
that, but I just could sit down for a moment or two, and GUESS
how to do it, because its so well planned, that everything works
in the same way. There was this killer combination of libraries
that I found when using Ogre
Ogre + Bullet or Newton + dotSceneFormat
+ OpenAL + BETAGui + CG + Theora for Videos. 
With this libraries, 
I felt unstoppable. The community is very active, and very helpful.
I ended up smashing into a wall, when I tried to port Ogre
to the PS3 platform though. After a few days trying to port Ogre
to then Port my game, I felt it was faster to rewrite my game from
scratch, and thats when I met PhyreEngine.



PhyreEngine
Phyre is like an amazing opportunity for PS Developers. Though is not
as user friendly as UDK, or Havok, it is FREE and you get access
to many things reserved for Engines that cost a lot. When I mean
its not user friendly, I really mean it; I have found classes that have
SETTERS but dont have GETTERS, so I have to store that variable
outside that particular class; other times I have found that the programmers
FORGOT to uncomment this or that and that was WHY my code
was not working. BUT, if you want to program a videogame
for Sony platforms like a pro, but do not have the money, Phyre
is definitely a great option, you have to have the guts to get
deep into the Phyre source code and change it if you need to.
I am working currently working with Phyre in two projects,
and now that I have tamed it, I really enjoy it, and enjoy
the computing power it gives me.

Cocos2D-x
I am a 3d person, I do not tend to feel comfortable with
2D engines, there is something I just dont quite get about making
2D games, BUT if I have to do something in 2D, Cocos2D-x is
definitely my first choice. Aside from all that internal memory
management, like RETAIN and RELEASE that have become
very usual, I really like the architecture of Cocos2D-x; I dont think
the architecture is AS GOOD as Ogre's, and its definitely less
elegant, but its still very good. There is something I dont
really like about the name of the functions and methods, I think
they are elusive to understand for a new comer, I believe Ogre
is way more practical in the naming and general accessing
of characteristics, but it should still be easy to learn.

Construct2
I was amazed when I met this software. Im not normally
very keen to non-programming softwares to create games but
Construct2 beat me. It was very easy, and if you were an
artist and wanted to created your html5 game, Construct2
could definitely be at hand. For me, as a programmer, it
was sometimes cumbersome to use the software, I kept
thinking, I could do something so easily by code, and
in construct it had to be such a pain, but I could get
a game running in less than a week. For hobby programmers,
artists or work for hire games, Construct2 its worth the time.
Also its extremely cheap, 100USD for the complete version.


 Construct2 Game, created in 1 week
 Ogre game demo running in iOS
Phyre game demo running on PSVita



Stencil by Discard-ing pixels through a shader

Drawing alpha objects tends to be very expensive. If you want to draw
a lot of alpha objects to simulate grass or plants, it quickly becomes
TOO expensive, lowering dramatically your FPSs.
This happens because in order to render alpha objects, the renderer
has to sort them by distance first, you end up having to sort 300
objects.
There is another problem with alpha objects: when an object is very large,
for example a plane, it cannot be SORTED by distance correctly because
a vertex in the end of the plane would have another distance pass than
the object itself; you end up having artifacts, where a pixel that should
be behind another object, is rendered in front.
As a hobby game programmer i used to have this issues with the alpha objects
a lot, but did not know how to fix them, until, when I started working as
CTO in Hollow Games, i finally found the ultimate fix.
I came to the answer, because I kept thinking, that a plant, for example
is not REALLY an Alpha, but some sort of stencil, where the renderer
has got to either write the pixel or dont. There is a function in CG
(obviously there should be one in GLSL, GLSLES and HLSL as well, but
havent had to use them) called discard that does exactly that.
So I wrote a new shader (its an UberShader in my engine) that
when it reads the texture (tex2D) it checks if the alpha byte is less
than say 0.9, if it is so, the renderer should not write the pixel.
With this DISCARD-stencil technique, the renderer is not sorting
anything, and for objects like plants, it works like a charm. If your 
texture is in DDS format (honestly it should be) there is an option
for 1 bit alpha, instead of explicit alpha, that way, the texture
is lighter than an actual alpha, and 1 bit is all you need to decide
if to render or not to a pixel.
There are some other advantages to this technique, for example
if you are using deferred lightning, alphas are a problem, but
discard-stencils are not, they can be rendered as any other object.
Another advantage is that discarding is completely friendly with
bump mapping, which can seriously upgrade your plants, also, 
discarding tends to be neater.
Oh, by the way, most game programmers in the industry probably
knew about this, but me as a hobby game programmer did not
have a clue.


 Alphas instead of stencils, look dirty
 We can see here, how some grasses are not being rendered in the right order
 Stencils look much more clean
Stencils with bump in the leaves

Have a good one!