Saturday
Aug272011

Dice Poker Game (CANCELLED)

[Unity3D, RSRM] Dice Poker prototype

Unity3D Web Demo

Art and game behavior courtesy of Anton Hand.

 

Instructions:

Click ring to drop dice in box.

Click chips around box to chuck chips in center.

Click button in upper left to reset ring.

 

UPDATE:

This demo will only work for SM3.0 level GPUs. If you attempt to use it on an earlier generation GPU, you will just see black on all the geometry that is using the RSRM shader.

 

Situation:

If you were wondering why I haven't posted much lately then please allow me to fill you in on the details. Recently, I tried getting my Physically-Based Rendering (PBR) tech into Unity3D, with surprising success. Having gotten this working in a prototype, my artist friend set out to build a game using this new tech. Sadly, the project encountered some complications, and ultimately had to be cancelled.

 

Despite this, the prototype is in a state where the basic functionality is working. So I have decided to re-purpose it as a tech demo, which you can access via the above link. Please check it out and leave some feedback about the visuals in the comments section. ;)

 

Results:

The prototype shader used for this demo was single-pass forward rendered using two fake directional lights and a Radially Symmetric Reflection Map (RSRM). The scene itself also has SSAO, Bloom, and FXAA just to top it off.

 

The results are slightly incorrect due to my misunderstanding of the need to plug the BRDFs into the Punctual Light Equation and cancel some terms out. As a result, the specular ended up too bright, and fresnel for RSRM gives too much rim for rough surfaces. So while it is significantly better than the current standard of Phong & Blinn Phong lighting models, it still falls short of what I wanted to achieve.

 

Currently, I am working on an improved version that will correctly integrate with Unity3D's forward multipass lighting system. It will correctly accumulate the lighting in an FP16 target in linear space, then receive tonemapping before being passed to the rest of the pipeline. I will also being improving upon the built-in Bloom, SSAO, and Depth of Field effects to really sell the effect.

 

Keep your eyes peeled for future updates! ;)

 

Other Updates:

Other than this, I am currently working on a revised RSRM article, to centralize all I have learned in an easy to reference article. It will also detail the PBR BRDF I have chosen for my project, including strengths and weaknesses. Finally, this will provide a good opportunity for me to clear up some incomplete and flat out wrong information from my old articles.

 

Other than that, I've also made a small update to my Partial Derivative Normal Map (PDN) article. Basically, I found an optimization to use a MADD to save an assignment, shaving off another instruction from the recovery equations.

 

Hope you will find them useful. :)

Sunday
Jul102011

RSRM Enhancements

Let me preface this post by saying that I touched on some of these topics before. I decided to revisit them because I have learned a great deal since then, and felt I should make a little update on my progress. In particular, I wanted to correct some things that I got wrong in my prior post on the topic.

Fixes:

For the longest time, I was having trouble reconciling some of my results with those achieved in published Image-Based Lighting (IBL) papers. As it turns out, there were some problems in both my rendering code, and the console app that I wrote to convert an input gradient image into an Radially Symmetric Reflection Map (RSRM). The net result of my mistakes was that my RSRMs' lower specular powers were getting progressively darker when they shouldn't have been.

 

During this time, I had the incorrect notion that I needed specular power zero to represent my diffuse IBL. Naturally, this was incompatible with the non-linear mapping I have been touting so much. So I tried a remapping scheme to store specular power zero, but access it as if was specular power one. Unsurprisingly, this threw off the results for all my specular lighting, on top of producing incorrect diffuse lighting.

 

As a result, I was afraid I was going to have to use a different approach to generate and store my diffuse lighting (eg. Spherical Harmonics (SH)). Fortunately, when I fixed my RSRM generation app, I realized that specular power one can adequately represent diffuse IBL. This way, I can generate all my IBL data using one pipeline, and store all related lighting data in one RSRM texture.

 

In the process of fixing these problems, I took the opportunity to add some improvements to the system. All of which had the effect of greatly improving both the lighting quality, and reducing both storage and runtime costs for my RSRMs.

 

Non-Linear Mapping:

In my prior article, I demonstrated how a non-linear mapping of specular powers can reduce storage costs for IBL . It accomplishes this by accounting for the fact that the specular lighting has a non-linear rate of change for increasing specular powers. So we can store more samples for the rapidly changing lower powers, and less for the slowly changing higher powers. This allows us to reduce the number of discrete samples needed to recreate the full range of specular lighting. As it turns out, that was merely scratching the surface of how this technique can benefit the graphics pipeline.

 

Firstly, it allows artists to use a more intuitive "smoothness" parameter [0, 1] to handle the transition from rough to smooth materials. This allows them to use linear values to effect a perceptually linear change in the smoothness of the material. Compare that to using specular powers directly, which make it hard to tweak materials as their smoothness gets higher.

 

Secondly, this new parameter can be represented quite efficiently using only byte precision. As a result, it works great with g-buffers that use RGBA8 targets to reduce storage costs. Of course this also applies to storing the data in a smoothness map texture for materials. So it can be sampled directly from the texture into the g-buffer with no need for packing instructions.

 

Thirdly, this parameter is efficient to use at runtime, because it can be used to directly sample an RSRM. Plus it is cheap to recover the specular power for analytical lights, which only requires a pow(2048.0f, smoothness). This way, the two lighting systems gel together perfectly!

 

Finally, I decided to go with 256x32 for the map's resolution. This seems to be adequate for representing all the specular powers I want while being reasonably compact. Plus, it establishes a good habit for if I ever develop for the XBOX 360 (ie. 360 uncompressed textures have a lower size limit of 32x32, including the mipmaps).

 

Results:

Here are some videos and screenshots showing the new improvements in action. Please note that for all these tests, the only sources of illumination are an RSRM and a directional light.

 

Enjoy! ;)

 

RSRMs:

[RSRM] Linear [1,2048][RSRM] Non-Linear [1,2048]

Figure 1. 1, Linear [1, 2048]; 2, Non-Linear [1, 2048]


Material Demos:

 

Figure 2. 1, Iron Sphere; 2, Plastic Sphere; 3, Plastic Statue; 4, Plastic-Metal composite (Model by Ben Mathis)

 

Final Thoughts:

After much testing, tweaking, and re-testing my RSRM implementation has developed to the point where I feel safe integrating it into my project. The next step will be to add RSRMs to my Light Pre-Pass renderer, and see how they will look with local lights using physically-based BRDFs. I'll keep everyone posted on my progress.

 

As always, questions and suggestions are welcome in the comments section. ;)

Sunday
Jun262011

Coding Style

Sorry for the lack of updates folks. Sadly, my lengthy job search on top of my regular work hours has been eating a lot more time than I could have imagined. As a result, I haven't been able to get much work done on my new project. However, I have been doing a lot of planning to make my next project far more portable and maintainable.

In particular, I have taken a keen interest in finding a coding style, and using it throughout my new project. For those who took the time to look through the code for my Cubism Demo, let me apologize right now. That code is packed with unfinished experiments and ideas that broke down as the project grew. It may work, but it should not be considered an example of good coding style!

That having been said, I have been taking what I learned from that little excursion, and have been building on it. Below I have listed a few extremely handy resources I have found that offer plenty of insights into good coding style. I highly recommend them for anyone wanting to improve their coding practices. ;)

 

Links:

[1] Google C++ Style Guide

[2] wxWidgets Programming Style Guide

[3] Windows to UNIX porting, Part 2: Internals of porting C/C++ sources

[4] C++ Frequently Questioned Answers

[5] Unity builds

[6] Doxygen

 

Example code:

I've attached some examples of my latest coding style that implements everything I have learned up to this point. If you would be so kind, I would be most appreciative if you would look over them and leave comments. Thanks.

 

Random.hpp

StringId.hpp

Wednesday
Apr272011

Update (4-27-2011)

Hello again my faithful readers!

 

Let me assure you that I am still alive, and still working toward another big release. I've just encountered a lot of delays with that whole "real life" thing. On the bright side, my 8-5 has taught me the importance of good coding style. Sadly, this is because the decade old code I am updating has poor style, and causes me to cringe every time I look at it. :p

 

That having been said, I'm hoping that my next major demo will have a greater degree of polish and interactivity. To that end, I am going to add support for an AntTweakBar GUI, Light-Prepass rendering, RSRMs, SSAO, and FXAA. I've also been wanting to experiment with component-based entities, but I am not sure if I am going to work that into my next release.

 

Keep an eye out everybody! ;)

Monday
Feb282011

Robot Butler - My first shipped title!

IMG_08022011_190739

Ladies and gentlemen...I give you Robot Butler! This game was made in 6 weeks for Kongregate's Unity 3D game contest. In it, you play LX-27, a robot butler just trying to attend to his human masters' needs while keeping them from being slaughtered by invading rogue robot butlers!

 

My role in this project was designing a set of custom enviroment and character shaders that would allow the game to look good and run smoothly on a wide range of hardware. Given that we had to use the basic Unity3D package, this was quite a tricky task.

 

Unity3D:

First, let me say that Unity is a capable, affordable game development platform. In particular, the most recent iteration has a rather convenient system for designing surface shaders. Sadly, its lighting system left us in a bit of a bind.

 

Now under ideal conditions, we could just use their new deferred lighting renderer and call it a day. Sadly, this dramatically ups the hardware requirements for anyone who would want to play our game. Plus, the project's artist would have had to scale back his lighting setups to get reasonable performance. Finally, it would have forced the whole team to buy Unity Pro licenses to work on the game.

 

Sadly, Unity's forward renderer wasn't quite right either, since its Single Lightmap system is rather lacking. Not to mention having no Irradiance Volumes to integrate dynamic objects with the static environment. Our artist needed a capable replacement that would scale well to older hardware, support the full suite of baked lighting effects, and handle highly detailed surfaces. So let's take a look at what I had to do to meet those needs.

 

Environments:

So the buzzwords here are: Radiosity Normal Mapping, Detail maps, & Fake specular cube maps.

 

To get the best kind of baked lighting for the least storage, we needed support for Radiosity Normal Mapping. This way, we could use low-res lightmaps, while still being able to support arbitrarily detailed normal maps. Plus, all normal-mapped surfaces could get the benefits of radiosity, ambient occlusion, and an arbitrary number of lights with soft-shadowing.

 

Now, while this system doesn't cover specular, we were able to do a convincing job using a cube map with fake highlights. Then it was a simple matter of multiplying it with the diffuse contribution to get color, shadowing, and ambient occlusion. Not perfect by any stretch, but adequate for this project.

 

For more details, please check out my official post on the Unity 3D forums. ;)


kitch_01 kitch_02 kitch_03 kitch_04 

Figure 1. 1, Flat RNM lighting; 2, Normal-mapped RNM; 3, Normal-mapped Fake specular; 4, final materials

 

Characters:

So the buzzwords here are: Rim lighting, Environment maps, AO maps, & Constant Ambient.

 

We used high-quality scene capture environment cube maps for reflections, which provides most of the enviroment's influence for dynamic object lighting. The rest comes from rim lighting and a constant ambient color with Ambient Occlusion. Despite its simplicity, this worked out well since all our dynamic objects occupy so little screen real-estate.

 

The only major annoyance we encountered was getting a decent system for setting zones for the varying colors/environment maps, and then smoothly interpolating/switching between them. Each dynamic object had to be aware of all the zones, and handle the transition itself. If our game world wasn't so small, and we didn't have so few parameters to change per zone, this would have become unmanageably cumbersome in a big hurry.

 

Despite its limitations, the results look great and are quite efficient.

 

Character shader:

RB01 RB02_env_occ RB03_addnormals RB04_complete

Figure 2. 1, Ambient Occlusion; 2, Environment map; 3, Normal mapped Env map; 4, final material

 

Lighting Environments:

RBinEnv01 RBinEnv02 RBinEnv03 RBinEnv04 RBinEnv05 RBinEnv06

Figure 3. 1,bedroom; 2, bathroom; 3, living room; 4, dining room; 5, kitchen; 6, shed

 

Conclusions:

Overall, I'd argue that despite their shortcomings, these custom shaders make Robot Butler one of the prettiest Unity3D games you will ever see. That is, until they really start taking advantage of their Beast license to provide more advanced static lighting options. ;)

 

In the meantime, go play the game people! :p