Showing posts with label shadows. Show all posts
Showing posts with label shadows. Show all posts

Monday, 19 April 2010

Wibble!

Mmm, lunchtime blogging.

First off, have a screenshot:


I've been playing with exponential shadow maps, and they're kinda fun. Not sure whether I'll use them over variance shadow maps, but it's tempting. I've also been messing with lit particles, although this has not been superbly successful. The image shows some alpha-tested jobbies that interact nicely with the deferred lighting, cast shadows and generally behave themselves, but the ultimate aim is to have nicely lit smoke effects and they do little to advance that goal.

I've been playing with rendering a lot of small fake-sphere particles to a render target and blurring it as a post process, but it's a bit too crude to work and smacks of megaparticles. I may go for a simple volume rendering approach.

I have moral objections to CPU-driven particles, which precludes the standard sort-and-render which makes such things easy. I'm also avoiding texture fetch in general (I got burned by ATI's render-to-vertex-buffer non-implementation in the past), so simulating particles in a position texture and doing the sorting GPU-side is not tempting either, although I may yet go back to that. In the meantime, the hunt for order-independent transparency continues!


do => for

I can't write much about this because I'm still feeling my way, but using a for expression to perform computation inside a monad is... weird, but quite nice. I'm not sure I prefer it to Haskell's do notation.

It's odd enough that I want to dump my exploratory fiddlings anyway, so here's a stub for the conflict-resolution step for two entities colliding after a movement phase. Note the awesome game logic for deciding the winner:
   private def collidePair( a: Ent, b: Ent ) : (Ent,Ent) = {
      val ab2 = for{
        aPos <- a.get[Int3]("position") if( a("solid",true) )
        bPos <- b.get[Int3]("position") if(aPos == bPos && b("solid",true) )
        aPosHis <- listToOption(a.history[Int3]("position").drop(1))
        bPosHis <- listToOption(b.history[Int3]("position").drop(1))
      } yield {
          val aWins = Math.random < 0.5
          if( aWins )
            (a,b.extend("position",bPosHis))
          else
            (a.extend("position",aPosHis),b)
        }
      ab2.getOrElse(a,b)
    }


Slightly odd exploratory code. Anyway, it crudely rips the current position from both entities, as well as their previous position, and yields an Option containing a tuple of new entities. If any of the extraction steps or predicates in the for chunk fails, it simply returns the original pair of entities.

Errors abound, of course. An entity doesn't always have a 'last' position, and if it does this in no way implies it's a reasonable place to go if it fails the conflict step. The listToOption thing is ugly as well. Bleh. But my original point stands: for is a weird and flexible beast in Scala, which I didn't appreciate before.

Thursday, 27 November 2008

When in doubt, add random useless stuff

New bit o'fluff. I'm beginning to think that I'll need a better way of scattering general clutter - maybe something based around blue noise, there's a nice paper on using such point sets for placement of objects. A data driven way to specify new clutter objects also seems increasingly logical.

Shadows on meshes are behaving weirdly, with lots of banding and acne despite using the same algorithm as the terrain (which works fine in most cases). Oh, and I broke text rendering... whee.

Games are hard, eye candy is easy, nothing ever works as it should.

Monday, 8 September 2008

Even more deferred tentacles

Just a quicky today.

These are lighting-only shots showing the same scene with and without screen-space ambient occlusion, the latest hacktastic post process to take the rendering world by storm. Unfortunately I have to concede that even my less than stellar implementation does add a lot to the rendering, for a moderate cost, so I guess I'll be jumping on the bandwagon. It's an especially useful technique when combined with deferred lighting, as attempting any real shadowing with a bucketload of small point lights is very bonkers, so the illusion that the faked ambient occlusion provides is doubly useful.

As an aside, I do like my dungeon fairy lights. They add such a nice ambience...

Before (no SSAO):



After (mit SSAO):

Friday, 5 September 2008

Deferred Tentacles

Further work on the deferred rendering side. I finally found an example online using FBOs with a stencil buffer, and thereby discovered that despite using a combined depth-stencil renderbuffer it needs to be attached to the frame buffer object twice, once as a depth attachment and once as a stencil attachment. Sigh.

That done, efficient rendering of small lights via z-and-stencil-tested spheres works nicely!

Behold the scene, containing no less than fifty ickle lights, plus the large shadow-casting light from the player's avatar.


The majority of the screen is taken up by the final composite image. On the right, small sections show a sample of the buffers involved (yes, I don't even turn off my debugging chuffle before posting, I'm that lazy). Top is the SSAO term (very low intensity in the final image, as it looks pants). Below that are the lighting accumulation buffer, world-space normal, and finally unlit diffuse buffers.

Lastly, the image displays some filthy aliasing as the source render targets are only 512x512, violently scaled up to match the screen resolution. I should fix that.

Edit: here's a version using 1024x768 buffers throughout. Ouch, bye-bye framerate. Need to fix my absurd pixel shader usage methinks.

Wednesday, 27 August 2008

Visual fluffs


As my other post is waffly and dull, I thought I'd post some equally dull screenshots.

First, we have soft shadows and a general framerate improvement. I found I wasn't using buffer objects for my mesh streams (bad!), switched to position-only streams for shadow rendering when possible and changed the shadow buffer format to rgba16f. All this has reduced the frame time hugely, even after I started adding more crazy stuff. For comparison, a similar scene with blurred shadows was previously in the single-figure frame rate. Ouch. Still vastly too slow at the moment of course, but moving in the correct direction.

The soft shadows are done with a simple 3x3 guassian blur over the cube. It has errors on the cube edges for some reason, as can be seen in the nice black line across the lower right quarter of the image, but even with fairly low res maps and a small kernel the reduction in aliasing makes things look nicer. Hooray!


The second screenshot shows a half-finished unsmoothed SSAO post process. It's using a deferred rendering setup, with a few render targets for diffuse, normal, depth and lighting information at the moment, although for this screenshot only the depth info is used of course. Lots to do here, and I'd like to get a scene with more interesting visual fluff to show off the AO effect better...

Anyway, hopefully that helped balance up the wordiness of the previous post.

Friday, 15 August 2008

Baby Steps


No big changes, but:
  • Hex floor generation cleaned up
  • Block-edge normals much less broken
  • Mipmap brokenness caused by discontinuous texture coordinates fixed
  • Shadow res bumped up (shadows are currently a huge rendering bottleneck, hence terrible frame rate)
  • Shadow acne removed with a teeny epsilon
The mipmap fixes have also introduced a LoD bias, but I quite like the way it looks. Textures do repeat too much at this scale though, and there's little to break up the tiling. Will be looking at potential fixes for this soon.

My big low-res chasm-filling geometry seems to have wandered off as well, not sure why. Eh, it'll come back when it's hungry...

Wednesday, 30 July 2008

Hexy texture madness



Testing out the sub-texture stuff with normal maps and shadows. Right hand images apply textures on a per-hex basis, whereas the others just have random perlin smeariness.

Interpolation between hexes is still enborkinated, so the hex edges display some very rough geometry and there're no smooth variations. Also, the ugliness of the shadows is getting to me...

Thursday, 8 March 2007

Progress! Of a sort...

A bit further on; some experimentation with Blender (one of the most agressively counter-intuitive programs I've ever used) and lots of frustration eventually lead to very slightly more interesting dungeon walls. After a bit of fiddling with the data, they even cast nice shadows.

Given that the major view point is always going to be top-down, I figure the z-pass stencil shadow algorithm is a win, and indeed it seems to work well even on my feeble home PC.

My current problem is the combination of line-of-sight with stencil shadows, and whether an ambient pass makes sense. On the one hand, the shadows accurately represent the area of the dungeon visible from the character's position, and most especially obscure creatures or items lurking out of sight. On the other, the player can see more of the dungeon from his or her elevated viewpoint, and simply not rendering the areas of the dungeon the character cannot see leads to unnatural pitch black shadows, and this makes navigation a little harder by obfuscating useful landmarks or features.

Given that traditional tilewise LOS will need to be implemented for gameplay purposes, I think a combination of hiding monsters based on traditional LOS methods, and using an ambient pass to hint at the structure of the dungeon not directly visible should work well. Now I just need a few monsters and a player avatar to test my suspicions with...

Guess that means I should get back to Blender. Sigh.