David's Blog

Mostly Hobby Stuff

Lazy Lights

leave a comment »

Well I have added support for only evaluating lights when they move. This helps performance a lot when there are large numbers of lights. So now I can add lots of lights to improve the visual quality of my levels:-)

In addition I also added support for inheriting light filter settings. This is nice since I tend to work on models for each room of the indoor parts of the level. Each room in turn contains many other models for fixtures, trim etc.

 

apr28 apr28_2

Written by therealdblack

April 28, 2010 at 8:30 pm

Posted in Hobby Game, XNA

Higher Resolution Video

leave a comment »

I also have a better quality version of the water shader video on Vimeo, the reason I posted a YouTube version was that Vimeo took like 2 days to encode the video once I uploaded it…

Written by therealdblack

April 12, 2010 at 7:05 pm

Water Shader Video

leave a comment »

I figured out how to capture video and post to my blog, so I am posting a quick test video of my water shader. For anyone that is interested in the simulation of the water a great site to check out is: http://www.matthiasmueller.info/ (don’t be put off by the scary photo:-). What is shown here is the most basic shallow water simulation possible.

So here’s the water video:

Note: The artwork/settings are only preliminary, so things like the shadows, water colour, reflection image etc will look a lot better when I show proper artwork. Also ignore the misbehaving bit of cloth in the background, it is badly tuned and was put in the test scene a while ago to debug something.

Written by therealdblack

April 10, 2010 at 9:45 pm

Moving to wordpress

leave a comment »

Well I think I am going to move my blog to wordpress from spaces (http://davejohnblack.spaces.live.com/blog/).

Mainly because the spaces blog software seems rather limited. I originally started using it because live writer seemed rather handy.

Note, I used therealdblack for the user name, I wanted dblack.wordpress.com but it seems to be already taken. In fact I think it is probably me who registered it but I have forgotten the password and I think the email it is set to is dead. Never Mind.

Written by therealdblack

April 10, 2010 at 5:20 pm

Posted in Uncategorized

Light Attenuation

leave a comment »

Recently I have mostly been doing art stuff however one thing I found that needed improvement was the lighting system. I was using, the fairly awful standard method for computing light attenuation i.e.:

attenuation = 1.0f / (a + b*dist + c*dist*dist)

The reason this is bad is that it requires 3 rather unintuitive parameters, plus it may not fall off to zero at the edge of the lights range. There are a number of alternatives:

  • Use a texture (3D or 1D) to encode an arbitrary function. This would be a good way to go but it would increase the complexity of the material system and require more work to define the textures. In addition there is likely a performance cost. Since I am already heavily bandwidth bound I didn’t want to pay this cost.
  • Use smoothstep(), this produces nice looking results, but it provides little control.
  • Use something similar to the way spot light falloff is calculated. i.e. have a MinDistance parameter which specifies the range at which the light has full effect, then use a pow() to encode a falloff. The exponent gives a nice intuitive control for the rate of falloff. Hence I chose this solution.

For example:

float ComputeAttenuation(float3 position, float3 lightPosition, float4 attenuation)
{
	float dist = distance(position, lightPosition);
	float range = attenuation.w;

	if(dist < range)
	{
        float attenMinDist = attenuation.x * range;
        float attenExponent = attenuation.y;
        //attenuation.z is unused for now

        float attenIn = clamp((range - dist) / (range - attenMinDist), 0.0f, 1.0f);
        float result = pow(abs(attenIn), attenExponent);

        return result;
    }
	else
	{
		return 0;
	}
}

Which is nice and simple and saves a huge amount of time when tweaking light attenuation.

At the moment I am working on improving my lighting performance, which really suffers once I start having 10s or 100s of lights in a level. Of course only a few are visible at once, but searching for the lights, evaluating filtering, shadows, setting effect constants etc is not good. So what I am doing is evaluating light<=>material bindings only when lights or objects move.

This however does lead to not being able to make the light selection view dependant, hence in principle lights could be bound which are not visible. However this is perhaps not a bad thing, since it will eliminate lights going on and off as the player moves. In addition lazy evaluating light bindings will make it easier for me to add support for static shadow maps.

Written by therealdblack

April 10, 2010 at 5:12 pm

Posted in Graphics, Hobby Game, XNA

Water Shader

leave a comment »

Recently I have added support for rendering water(and other similar effects). The features I added:

  • Refraction texture coordinate generation, this is done in screen space with depth checks to ensure only geometry behind the refracting geometry is shown.
  • Support for distortion maps(i.e. a copy of the main render target is made before executing distortion shaders).
  • Reflection texture coordinate generation, the texture coordinates are generated in the texture space of planar reflectors and offsets added for normals which are not planar with the reflector.
  • Support for object space normal maps
  • Support for displacement mapping/texture sampling(in the vertex shader).
  • Support for applying a blur to reflection maps, this allows much lower resolution reflection maps without the reflection becoming pixelated. Plus it looks better too.
  • A Fresnel material node.
  • Support for dynamically binding values to material constants(e.g. the projection matrix for reflectors).

In addition I added a basic shallow water simulation module for dynamic models which allows the user to use vertex painting to specify the height of the ground and water. I will talk later about the water simulation after I have added a few more interesting features.

Below I have added a screen shot of the water shader, in the editor. I will have to get around to figuring out how to post a video in order to do an actual render of the water justice. However, the node based shader editor is beginning to prove its worth, it would have been much more tedious to tweak the water into something acceptable had I not had the ability to re-arrange nodes, tweak values etc etc:-)

In addition I made a few optimizations to improve the frame rate, especially at higher resolutions. In particular I disabled bilinear filtering for a bunch of screen space operations which didn’t need it(going from one render target to another of the same size). This provided a huge boost to the SSAO shader… Which went from being memory bandwidth limited to shader instruction limited. (it works in view space, so can probably be improved further).

mar17

Written by therealdblack

April 10, 2010 at 5:11 pm

Reflectors

leave a comment »

Recently I added support for reflectors, i.e. mirrors, refraction maps etc. You might say that is not very impressive, granted it is quite simple to add such support to a demo app, but when you add this to a larger engine it can be quite involved. Below I will list the changes I had to make in order to support this (and future similar functionality, for example cube maps in addition to planar reflectors).

  • Add a framework of abstract base classes and collections for reflectors and reflector instances. A Reflector belongs to a model and contains most settings, a ReflectorInstance belongs to a model instance and contains instance specific data(e.g. an instance transform).
  • Add content processor support for converting (portable) reflector content into the runtime format.
  • Add editor support, including the command sequences to create reflectors(e.g. select two points which form the corners of the reflector), drawing, selection, serialization, plugin support for multiple types of reflectors etc.
  • A small amount of refactoring of the system for selecting render targets and render target textures during rendering. Plus control of which render passes are used during reflector rendering. For example particles, decals etc are rendered into reflectors. Ambient occlusion is not rendered in reflections(wouldn’t be difficult to add, but it seems kind of expensive).
  • Improve the method used to bind texture maps to materials. i.e. a new content and runtime abstract type TextureBinding(and TextureBindingContent). These allow arbitrary sources to be added for textures. Plus I added a new material node, which represents a dynamic texture from reflectors(and other sources with similar semantics).
  • Support for occlusion culling of the reflector, by implementing IRenderProxyItem. With this reflectors are only rendered when the front surface of the reflector is visible.
  • Make the cascaded shadow map code aware of reflectors so it can extend the furthest cascade to encompass the reflector view frustum. Otherwise directional lights loose shadows when the viewer can see reflections behind the camera.

Even with these changes there are still a few issues or desirable enhancements:

  • In some cases it is probably not desirable to disable cloth and particle animation when the systems are not visible by the viewer, but still visible in a reflector.
  • Render target format control + multi sampling control. At present reflectors are rendered into a RGBA float16 render target without multi-sampling. This is likely too expensive for some uses.
  • Support additional modes of operation, for example rendering refraction maps and cameras(for example a security camera which display on a monitor).
  • Support for additional reflector types, for example cube maps.
  • More control of the data rendered into the reflector, for example I could output just emissive/ambient/etc light information to the reflector.
  • etc etc 🙂

feb21_1
The above screen shot shows the CSM cascades for a view position with the viewer looking into the reflector from a small distance(the shadow and reflector updates where disabled prior to moving the player).

feb21_2
This screen shot show a close up of the reflector with the player shooting the mirror surface, note the decal on the mirror and the reflected particle system.

Written by therealdblack

April 10, 2010 at 5:10 pm

Posted in Uncategorized

MessageHub and Logic Nodes

leave a comment »

Today I spent time enhancing the logic system. The test problem I had was this: The player has to push a block(rigid body) across a bridge in order to create a step to climb onto a platform. The problem with this is that it is possible for the player to push the blocks off the bride into the void below. Once the player has pushed all the blocks off the bridge they should be informed that they have failed and be respawned at the last resurrection point.

The features I added to support this:

  • Rigid body state saving/restoration on resurrection(or when instructed to do so by a logic node).
  • Support for generating trigger events when a rigid body enters a trigger.
  • A counter logic node to count the number of blocks pushed off the bridge and trigger an event when they have all been pushed off.
  • A “Set” node which given a list of objects in the editor can determine if the object generating an event belongs to the set.
  • A way to cause the players death/mission failure.

The need to trigger a mission failure and selective state restoration caused me to add a global message bus, i.e. a central class which receives events and dispatches them to listeners. I guess there are downside to allowing global messages, however it is kind of bound to the problem, i.e. the events by there nature have global influence so it seems to be the cleanest way of doing it. Centralizing this in one place will allow me to, for example queue and synchronize the messages in future if needed.

feb11

Written by therealdblack

April 10, 2010 at 5:09 pm

Posted in Uncategorized

Jumping and Resurrection

leave a comment »

Recently I improved the jump system, so that now the jump from standing direction (e.g. up or forward) can be decided after the jump key is pressed, during the preliminary animation. This makes jumping from platform to platform a lot easier/intuitive. I also improved the logic to decide if to perform a running jump, now the space between the player and the point where the run up finishes and the jump begins is split into segments and each segment checked to see if there is a floor to run on(helpful when jumping between platforms:-)

I added a cheat state to the movement control, which allows the player to fly up and through things when in a cheat mode. I guess it is an interesting landmark when you start to need cheats…

Next I added support for player resurrection, i.e. when a player dies, after a pause they are revived and teleported to the last resurrection point that they came into contact with. So for example I can add resurrection points before puzzles in which they might die.

I also improved the light selection criteria to consider both the distance to the object which is being lit and the distance to the player(which is needed if there are multiple lights in a large model). Ideally I guess the volume of intersection between the view frustum, the object and the light would be considered, but that seems a bit expensive to compute. At least until I move to a lazy system of light selection(i.e. binding lights to objects until one of the lights/objects move).

feb07

Written by therealdblack

April 10, 2010 at 5:08 pm

Posted in Uncategorized

Lights and Shadows

leave a comment »

OK, today I got the chance to do a bit on lights. In particular I fixed issues with lights contained within models which have scale applied. I also added support for light filter groups, so the objects which a light is applied to can be selected.

In addition I added an option to limit the number of shadow slices which have blur applied to them. This was quite a performance win, it appears I am more fill rate limited than I thought (PerfHUD can be very misleading in this respect). Despite the fact that this was mainly an optimization, it actually improves the appearance of the shadows. Artefacts from using a constant width filter kernel between slices and over blurring in some areas are eliminated.

Still to do on shadows:

  • Most importantly I need to clamp the CSM frustum slices to a fixed grid, which should eliminate a lot of shimmering during movement.
  • Try using MSAA for shadows maps. In principle this should work with VSM and is probably a quality and performance gain. i.e. I think MSAA will require less bandwidth and be more accurate than the blur I am using at the moment(unless I am missing something).
  • Add shadow filtering in addition to light filtering, i.e. choosing which objects cast shadows etc. Although I am not sure how effective this will be since VSM needs casters and occluders to be rendered into the shadow map. Despite this the grass etc seem to receive shadows fine, despite not casting shadows.

feb02 

(Note shadow map resolution is 512, Slices 4 and Blur samples 4)

Written by therealdblack

April 10, 2010 at 5:06 pm

Posted in Uncategorized