Wednesday, February 24, 2010

DX11 Hardware Tessellation

hi
recently i got a new job and i got new radeon 5850 which supports dx11 so i stated to check out those nastly new dx11 features, and let me tell you that: hw tessellation is COOOOL.
little info, dx11 tessellation works with 3 new stages added:
1.) the hull shader (aka HS) - get [1..32] input control points of the patch and responsible to output [1..32] new control points, it is also output constants which control how much to subdivide each patch.
2) the tessellator (fixed-function) - get the output of the hull shader as input and generate the new points, you have no control on this stage.
3) the domain shader (aka DS) - generates surface geometry from the transformed control points from a hull shader and the UV coordinates. the DS run once for each point generated in step 2, the input of DS is bary coords of the point on the patch so you could easily interpolate vectors other than position and uv.
HS supports 4 different partitioning methods, topology and few more things (check out dx sdk if you are interested on the tiny details)
so why do we need it if we already have geometry shader? well, geometry shader is programmable and generic in a way that you can do whatever you want in it, such has point sprites, fur, object silhouette and more but its not free and not optimized for things like tessellation. in dx11 you have dedicated unit for doing tessellation so the speed can't even compared with gs.
here is a video that shows dx11 tessellation with adaptive tessellation:


note that the geometry passed is simple 4 vertices quad.

Saturday, January 23, 2010

Atmospheric scattering

hi
this time i'm showing atmospheric scattering using oneil atmospheric scattering from gpu gems 2.
to implement it correctly i started with cpu based solution which computed all the nasty integrals on cpu and store it in a texture, this cpu solution used so i can debug and fix issues with the integral computations.
after everything works on cpu i convert it to gpu version and use it as default.
this texture is then mapped on a sky dome where camera eye is at origin.
clouds are procedurally generated using few noise textures, they also change their color based on sun direction.
for now i'm not taking into account sun lighting, shadowing this is simple solution so the sky wont look empty.
here is a short video to show it in action:



Monday, December 21, 2009

Stable Shadows

hi
this time i worked on stabilizing the flickering when doing cascaded/pssm shadow maps.
if you had the chance to do cssm/pssm you know what i'm talking about, you can't ignore those flickering when you move your camera (panning/rotating).
the first game i know who solve this problem was kill zone 2, nothing to say about this game!
i'v a lot of respect to those guys :)
anyway, if you don't know what i'm talking about and what those flickers are, let me explain (i can't promise you will understand it but i will still try...)
i will talk about cssm from now, the same idea works for pssm.
when you render your shadows you are creating/generating your shadow matrix whenever the view changes (your camera view), if this change is very small and almost smooth you are fine but if not, the shadows boundaries are rendered or more correctly rasterized differently which cause visible flickering of the shadow edges.
the more area your farther shadows (farther cascaded) will cover the more you will notice it.
ok, get the idea, how do i solve it? well, i split it into 2 cases:
1. rotation problem
2. moving/panning problem
case 1: can be solved by eliminating the rotation of the shadow maps when our camera is rotated (this cause our shadow map to be rasterized differently) , we can use smallest enclosing sphere of the cascaded frustum and use it to generate our cascaded matrices, using the center as the lookat target and the radius to generate the orthogonal projection matrix.
this assure that your shadow maps will not rotate with the camera.
case 2: can be solved by canceling the movement in sub-texel level, this can be archived by multiplying a fixed world position with our cascaded matrix, round the result and see how much it differs from your fixed world position, note that this must be calculated in shadow map space in order to get the right offset. we now use this offset to translate our cascaded matrix.
note that my implementation is different, i use bounding box slice selection and different flickering solution which is very sable (can't give info about that because we are working on a big project so i need to keep few tricks inside)
here is a video to show the translation of all those words in action :)


The resolution of the shadow maps are low to make the problem more noticeable

Saturday, November 7, 2009

Revisiting Shadows Methods

hi
shadows are always been an issue when it comes to real-time app, there is no such thing a perfect method for shadows, until now i choose vsm for shadowing, but the more i work with them, the more i get the feeling its great for "demos" not for complex scene where shadow complexity is high , yes i know about the bleeding issues and how to minimize them, but there are scenes where you need to minimize them a lot and at the end you just get simple shadow map, and the softness you applied by blurring or such isn't noticed so much.
because of this i started to investigate few other methods, and i must say i got really good results:
a word about poplar shadowing methods:
1. sm - old school shadow maps
2. pcss - percentage closer soft shadows
3. vsm - variance shadow maps
4. esm - exponential shadow maps
5. cssm - cascaded shadow maps
6. pssm - parallel split shadow maps
as much as it will sound odd, i choose method 1 for indoor shadows, yes, old school shadow maps with poission disk and jittering gives me very good results.
while method 2 sound really good, its not applied very well for every scene, it also not free in terms of performance.
anyway, i created 16 samples of poission disk and generated jitter texture which i passed to the shader. the poission disk can be tuned for more samples or less, the jittering can be tuned for more jitter or less.
because i use two shadow maps, static for static shadows and dynamic for dynamic shadows, i managed to optimize this by using one texture with offsetting.
method 5,6 used for outdoor scenes, i use pssm...
here is few screenshots:

complex shadows from 2 light sources
note that vsm will fail below the platform (light bleeding) and the fence details won't be visible even with 1k shadow maps because the compassion is based on probability and could be failed where simple compassion will pass.

complex surface casting shadows

zoom in on shadows

before you said its not so impressive, note that the 2 light sources using only 8 samples on 1k maps, the barrel is dynamic object which means the dynamic shadow map is updated and merged with static shadow maps, the fence have very tiny elements, and it all runs on my old g6600, so i think its pretty good ;)

Wednesday, September 30, 2009

Maya Exporter

hi
this time i talked about the maya exporter i wrote so i could defines whatever i want where i want and the why i want, without sticking to id md5 format.
when you want to create maya exporter you have few options:
1. create plugin dll
2. create exe application and call maya functions
3. create mel script
i choose option 2 because it more easy to debug and doesn't need your maya run everytime you want to export and test something, the drawback is the you don't go to file menu in maya, select export and see your new format.
option 3 is also good if you know mel script, but doesn't allow you to access everything in maya, and i don't think you have tools to debug it like in dev studio.
anyway, the new format called OGE, this format designed to support both static and dynamic models.
the structure of this format looks like this:
MESH
mesh_info - vertices count, texcoords count, normal count, weight_count (if animated), faces etc...
material_info - the name to material defined in .mtr script
mesh_data - vertices, normals, texcoords, indices etc...
anim_data - weights, skeleton data

global for all meshes
anim_data - anim sets count, fps of each set, joints animated and their anim data

the reason anim_data is shared between all meshes is because each mesh could have different influence on specific joints and those have it own skinCluster, because i don't want to manage and control animation controller per skinCluster, i'm merging those skinCluster's data into one skinCluster data and export it as it was single skin for the whole model meshes.
each of those data is optional and could be selected from the exporter ui.
here i a screenshot of the exporter:

options:
1. convert from right to left handed (maya uses right handed, engine uses left handed)
2. convert from Y up to Z up (engine uses z up)
3. export position, normals, texture coordinates (possible to invert v coord)
4. export materials
5. export animations, possible to set animation name
6. at right i have meshes list, this list allows me to export only the meshes i select. skinned meshes will be shown with '(skinned)' keyword after their name.

the reason i have the option to overwrite animation name is that i can use the exporter to create animation files (containing only animation data without geometry data).
the model could be created at first with one idle animation (or without animation at all), and at later point i can add more animations to it.
also, if you have few characters with same skeleton, you don't want to duplicate all animations, you just want to have shared animation folder containing all animation files for those characters.

Tuesday, September 29, 2009

New Animation System

hi
its been more than a month since i updated this blog, the reason is that i just didn't save time for taking screenshots/create a video and update the blog.
so here i'm finding few minutes to write about the new things i implemented, hopefully updating with screenshots/videos on the next post ;)
list of things i'v working on:
1. new animation system
2. abandon md5 file format and use internal format (writting exporter from maya)
3. real-time atmospheric scattering
4. HDR
5. read shaderx6 :)

the first thing i wanted to rewrite for along time is the animation system, calling it animation system is a nice joke, but still it could play different animations for different parts of the model, do some kind of blending and at the time it was enough.
but the time is come and i wanted more advanced system which allows me control and create animation on the fly, adding sse and such...
the new animation system based on blend trees, what it means is that you can apply operations/operators on trees and get a new tree as a result.
the system designed so the operators works just like in math, you apply operator get a result and apply another operator on it and so on...
so how this is going to help with animation?
when doing skinned animation, you need few things:
a. model with weights
b. bind pose skeleton
c. animation data for that bind pose skeleton
this skeleton form a tree, so you can define the operations in term of animation and you are set.
you can thing of animation as a list of skeletons which defines new position & orientation for this skeleton or just list of that skeleton with different poses.
the operations i'm using is:
a. subtract tree A from tree B - useful for separating certain parts from specific animation, for example: you have walk animation which moves both hands and legs, but you want to separate it to two new animations one that moves on the legs and another for moving the hands.

b. multiple tree A with tree B - useful for merging two trees to form merged animation, for example: merging the two animation created in a and get the original animation (the one which moves both hands and legs)

c. transition from tree A to tree B - the is by far the most useful operation, this create a transition from one animation to another by setting transition/blend factor [0..1], what this means is for blend factor 0 tree A will be the returned, 1 tree B will be returned, for 0.5 for example a tree between A and B will be returned. so why is it so useful? well imagine you have a character that have walk,run animations and you want to play walk animation for velocity under 10 and run over 50, but what happens between 10 and 50? well you can use the velocity to compute blend factor to be used to create smooth transition between walk and run and run to walk.

when setting animation is just a matter of setting list of skeletons, but when implementing you don't want to switch from one skeleton to another in one frame, what you want is to create smooth transition between one skeleton to another, for example: skeleton from frame 1 to 2, 2 to 3, 3 to 4 and so on... the result is a skeleton inbetween old frame skeleton and current frame skeleton, this skeleton used as input to other operations.
also, the animation system works hand by hand with the new engine format 'oge', used for both static and animated models, this format created using the new exporter i wrote.
next time i will write about the other things i worked on...
cya

Thursday, August 20, 2009

Deferred Lighting

hi, quick update
last crytek presentation they show their deferred lighting system, and i thought.. hmmm, i implemented those things few months ago, doing test and stuff to see if its good, but i didn't finsih all the tiny things that make it unstable (i wanted to focus on things other the graphics & effect), so last week i finished handling those tiny things and here is the result:

87 dynamic lights (yes, they all cast dynamic shadows)