Upgrade

Well. Sort of an upgrade at least.
It’s an upgrade to my deferred shading which puts it in view space. It also allows me to reconstruct the Z axis of the normal buffer in order to reduce the size of the GBuffer by one channel.
And that’s pretty much it.

So in other news I started experimenting on putting a Subsurface Scattering approximation technique into the engine pipeline which allows me to render light pass-through on organic objects such as vegetation or skin.
I’m in other words not sure whether this is worth having or not.
Surely it could make quite the visual difference in scenes that contain a lot of shrubbery or… Naked… Skin?
But none of those are exactly in focus for the engine right now.
The neat thing about it, I think, is that it’s integrated with the deferred shading so light pass-through works uniformly across the entire scene without need of any special behavior.

It wouldn’t see much use in a standard game, which is (I imagine) a big reason as to why it isn’t present in that many engines today, but it’s a pretty new technique for real-time rendering which is also part of the reason.

The approximated technique is essentially the same as proposed in this document which is pretty great and is pretty close to the ideas I’ve had in the past regarding real-time subsurface scattering.
My idea was less complicated and involved multiplying a scattered color (think orange/red for skin) with a dot product of the inverse light vector and surface normal, which effectively makes the pixels shine when the light is situated behind them. As you may gather this is just an additional Nā€¢L(Nā€¢-L to be precise) for the light shader and is very, very simple.
“My” approach still works for some cases, but the technique proposed by Dice emulates the light source visible through the surface too, not just the pass-through itself. It also emulates how much the surface scatters the light as it’s passing through and a lot of other neat things.

I think in the end I’ll make this a completely optional thing, just so that we won’t force games that don’t need it to still render it.

There’s another thing I’ve been thinking about, but don’t know if it would make much sense in the bigger picture.
I was thinking of letting ambient occlusion be automatically adjusted to the contrast of the scene’s lighting, so you’d get a very slight ambient occlusion term when your ambient values are high and a darker ambient occlusion when the ambient is low.
I’m not sure of all the possibilities of this yet, but I think it could be interesting in games where the ambient values range enough for people to notice.
It could eliminate one of the few gripes I have with ambient occlusion terms baked into the diffuse texture. My problem with it is that in some situations it over-darkens things.
You could even go as far as to let the ambient occlusion term be modulated by the scene ambient itself.

I’ll test things out and write some more junk on here if it proves to be somehow interesting. šŸ™‚

Advertisements

Cloth

Well. The start of it, at least.

So, now that you’ve seen what I am on about let me delve into the depths of this.

Quick notes on the video:
* Those green lines are the constraints of the cloth. It’s low resolution and doesn’t give a very wide range of motion usually found in cloth, but I’ll deal with that later.
* I think we should, as a people, already be used to a lowered framerate when capturing video- so No, this program doesn’t run just 30 frames per second. (Actually I’m not sure the compression of the video lets you see the FPS to well. It says 30 however.)

What you’re seeing is a simple, procedural animation for this banner, which hangs on a wall.
Why is this anything to get excited over?
Well, there are a ton of things that can be made with cloth animation, if not only enjoying the atmosphere it creates.
I’m planning a pretty extensive implementation of cloth and other soft body physics for my engine, mostly because of all the cool stuff one can make with it.
Right now, though, I’ve got the code for dealing with the banner above, and some pretty unfinished code for dealing with ropes that can be hung around the world.
Both are implemented using a verlet integrator.
I’m eventually hoping to move this code over to use the physics engine, since it will run faster and be more stable.
Verlet integration as it is doesn’t deal tremendously well with framerates that vary wildly.
During the course of session in most games the framerate can be very different from one area to another.
Can we blame the programmer for this framerate inconsistency?
Well. Yes.
But. Operating systems can sometimes cause framerate in games and movies to be inconsistent too.
Can we blame the OS programmer for this framerate inconsistency?
Well. I supposed you could. But then again, maybe we should just deal with the situation for what it is and stop blaming people left and right.
Deal? Deal.

From my experience so far the worst artifacts happen when framerate drops suddenly, but picks up again which usually makes the cloth object jerk violently.
In my test case and more serious case this isn’t a very big problem. The cloth simulates wind as is and it’s usually not that noticeable when it actually struggles.
I guess I should be thankful for the simplicity of my case.
I’m therefore not sure that the situation warrants any real action right now. But I think I might try to code some kind of damper or threshold for it.

Now that we’re aware of the first problem, here’s another one:
This type of cloth isn’t able to collide with anything (I’ll explain soon that this is not entirely true) because it would mean I’d have to deal with two essentially equivalent collision worlds and that’s just ridiculous. I will never do that.
So what I have in place instead is a simple, optional way to restrict the cloth from penetrating the wall that’s behind it. We can therefore mount these cloth objects on a wall (such as the banner in the video) and not have to worry about it sinking into the wall.
So technically, the cloth object is rather simple, but this variance in behavior is actually enough to make it useful.

For a start, this is more than I could’ve expected and it actually doesn’t suck terribly so I’m good for now. šŸ™‚

Edit: Guess I fudged on the promise from the last post about showing off the AO generator with some cooler models.
Truth be told the AO doesn’t get that exciting on said cooler models. So I, in my mind, voted against making a new post about it. Also I failed my first attempt at implementing a blur algorithm for it so that sucks too. But as soon as I get the blurring working I’ll make a new post with some cool models and AO, and you can see for yourself that it doesn’t make a whole lot of difference.
I have some other pressing matters to attend to, namely animation, so I’ll be working on that right now and not the AO.

Ambient Occlusion

OK. So this is “cool” enough to share.

I was thinking last night about ways to improve the visuals of larger object in a game scenario, such as architectural details or even entire buildings.
One thing in particular that I lack for these types of structures is ambient occlusion.

For models that use a single texture that is non-tiling- adding ambient occlusion is no problem at all. We can just multiply an ambient occlusion texture onto the color texture. Standard stuff, easy peasy.
But what if we have a side or the facade of a building? Which also happens to use tiling textures or even multiple textures for a single model?
This is where per vertex ambient occlusion is a valid option.

Before I go on any further I’d like to address an obvious question.
Why don’t I use screen space ambient occlusion?

The answer is simple: I don’t really like it.
Let me elaborate: In almost every game I’ve seen it used it looks pretty terrible.
I feel it requires way too much maintenance and tweaking to really be worth it. I like the concept, and future real time ambient occlusion techniques will surely be better. But for right now, I’ll stick to manual approaches like the one I’ll be talking about.

So. Per vertex ambient occlusion.
This should be no mystery to anyone who is familiar with the terms by themselves.
Basically what it is, however, is a set of data that’s stored for every vertex of a model, containing a brightness or color shift for that vertex.
We can then modulate the color of a shaded pixel on a model by this value.

With this simple approach, we can get cheap and fairly accurate ambient occlusion for any model.
A while back I wrote a simple ambient occlusion generator that worked on a per texel basis.
I remember that that approach was slow and was sorely limited by the texturing of the model that was being processed.
Think about it, these are the exact points I bring up in the beginning of this post.
We can’t have tiling textures and we can’t have shared parts of the texture.

Anyway. The knowledge I gained back then was enough to let me work this thing out without thinking twice.

There’s of course the drawback of tessellation. This approach does not go over well with very low-polygon models.
The data per vertex gets interpolated across faces, which means a huge triangle will get severely darkened if only one of its vertices is occluded.
This is not a real problem since my engine isn’t that hampered by triangle count, we can easily cram some extra triangles on there without trouble.

As with any ambient occlusion we get better results the more samples we use. More samples means we get a wider range of shading for any given vertex. We therefore get smoother results.
There’s also the possibility of blurring the shading across vertices to smooth things out even further if necessary.


Here’s a thing without anything special. It’s not very exciting and it’s hard to tell what’s what.


And here’s the same thing but with a simple ambient occlusion term. It’s easier to tell what shape this thing actually has.

Now, I’m aware that the results aren’t that appealing. But as I mentioned above, there are several things one can do to make the results more pleasant.
It’s also important to remember that cases like this won’t often happen in a game where there’s something that only has an entirely flat texture applied. Textures mask a lot of errors in shading and is in this case a very useful thing. We can in many cases just ignore processing the data further.
But blurring the result is definitely a step up when it comes to this. And that is the next thing I will get into. I’ll also make sure to get some more exciting models to show off, that thing above isn’t very appealing, is it?

Back to it. šŸ™‚

Engine Demo

Hey there.

I’m just going to point out that there may be a slight radio silence on this blog while I work on this demo. I’m trying to crank it out as fast as I can so that I can share what it’s about as soon as possible.
I will also have to make sure I do it justice, because as we know there’s a chance of overlooking errors and stuff when you work as fast as you can.

So I will likely not post on this blog until it’s finished… Unless I find something super cool.

šŸ™‚

Update

So yeah, I’ve been working on the performance and not so surprisingly most of the trouble I’m having are in fact remnants of past “fixes” and some other code that’s poorly planned.
For example, my resource manager class that I use was up until now not able to load materials correctly. What the material then ended up doing was to load itself uniquely every time it’s being used. The resource manager’s job is to make sure we don’t load resources that are redundant. Cloned resources are most of the time redundant.
This wasn’t a performance problem per se, but contributed to the loading times and memory consumption.
It also failed to deal with binary models correctly. It just loaded a new model into memory every time. This was due to the fact that I automatically detect what a model is, so that I can reject or load it. I have since then switched the system to deal solely with binary models, it’s stable enough right now.

I finally implemented the code that stops spotlights from shading objects that are not really affected by it. I’m using a rather experimental approach in which I use a type of voxelization system to determine the spotlight volume in 3d space. I use that volume to find the affected geometry. This isn’t really necessary, and I’ll admit partially to that it’s just because it’s cool.
But works alright at the moment anyway, so I’ll leave it in for the time being.
The resolution of the voxel lattice is pretty coarse and doesn’t even closely give a perfect representation of the spotlight cone, but it provides a rather simple solution for this (I think) and I don’t need that accurate results.
This bought me a pretty big performance boost, and that’s what’s most important right now.
I say it’s partially because it’s cool, and the other partial reason is that for a system that is mostly concerned with AABBs I’m not really interested in putting in code to deal with cone intersections for these AABBs, voxels are in fact AABBs by nature in my implementation, so there you go. Simple.
The shortcoming with AABBs for most things is of course that for angled objects it wastes space, but I buy into the idea that it’s worth the speed.
I understand I could use the physics engine for a lot of these collision tests and such, and I’ll get to that soon enough, but I’ll try my own implementation for a while first.

This is pretty much it for right now.

Performance

… is pretty crappy at this point.
Overlooking the obvious performance sink found in some unfinished things around the engine, there are some other performance problems that I’ve noticed now that are quite severe.
I don’t exactly know what it is that’s causing this drop in framerate, but I am half suspecting that it’s the number of draw calls that gets to me.
This is expected, and is as far as I can tell only remedied through instancing or batching of geometry.
I will get into the latter.
For static geometry it’s a good thing to batch several geometrical surfaces into one, bigger model.
At this point it’s cheaper to push polygons in my engine than it is to draw an object a lot of times.
I haven’t yet worked out exactly how I will handle the batching of geometry on an implementation level as it’s not something I’ve done before. But it shouldn’t be that hard. And since it only concerns static geometry it doesn’t necessarily incur a performance drop (I should hope not, I’m aiming for the opposite of that), since we batch the geometry at startup.
My engine doesn’t need to handle a lot of dynamic entities, so this is a very good concept for me.

The other thing I notice is that I need a way to split the game world into chunks, so that I can skip checking visibility for a lot of things when in fact none of them would be visible.
Ordinary frustum culling does a good job at this, but for scenes that have a high object density this becomes a bottleneck; the scene manager has to traverse the scene hierarchy and decide what objects are to be rendered.
If we split the world into chunks, we can skip drawing an entire room packed with objects if we find out the confines of the room aren’t even visible to the user.
This is a rather simple scene manager thing, but it’s something my engine doesn’t do at this point, so I’m going to put that in.

Now, there’s the issue of occlusion culling. I need a way to let my engine skip drawing rooms that are behind walls and such and therefore not visible to the user.
There are several possible algorithms to deal with this, but for my engine I’m thinking of rolling a custom routine. I think this routine will be less automated, but hopefully can be made more aggressive in that it really cuts away stuff we can’t see.
This is a real necessity for me because I’m looking to handle indoor scenarios well.
And some of the existent techniques to handle this are best suited for game worlds that are made out of CSG, something that I don’t use at all.

I’ll get to work implementing some of this stuff and put results on here about how the performance (hopefully) increases.

Also, there are of course some effects (like FXAA and soft shadows) and subsystems (like physics simulation) that suck up performance, and are things that I generally can’t help.

Edit:
Oh boy.
OK. The very first thing I mention in this post is that I have some unknown performance problems. Well, I DO know what the problem is and it has been fixed. The problem was that I was generating AABB’s for every single thing in the scene every frame. (It wasn’t the drawcalls like I suspected.)
How does something like this happen? Good question, and if I find the answer to that I’ll tell you.
No but seriously, it was sort of a ghetto fix I made a while back just so that I could get the damn thing to work.
But in a real situation there’s no need to generate an AABB more than once for something that is static. Static in the sense that it will never move or animate as far as the player is concerned.
And why did this incur such a performance impact? Well, because the AABB has to be created using the OOB as a base. I therefore have to first apply the matrix transform of the object onto the OOB, then create the AABB using the modified vertex positions.
Doing this for every object in the scene every frame is out of the question, not to mention completely and utterly pointless in my situation.
This is performed on the CPU, mind you.

Some updates

Hello.

I’ve been fixing up the particle system some, to allow the features I never had the energy to do a while ago when I posted that video with the gargoyle face and stuff.
There’s still a lot missing that are necessary for a full featured particle system, but the basic stuff is working fine.
Except I’m going to have to redesign the system itself a little.
Right now it’s divided into particle effects and emitters.
The idea is you attach particle effects onto emitters and create effects in that manner.
But the way it’s designed it doesn’t actually allow more than one particle effect per emitter, or even multiple emitters sharing a particle effect. A little design flaw there. oops.

I experimented a little with color grading as a post processing effect.
So far I think it’s a cool thing, even though I’m not a huge fan of it in general. It’s a fickle matter, it takes a lot of consideration and fine tuning to get right.
There’s also the issue of banding artifacts, which I understand is commonplace with color grading. I’ll have to experiment a little with different stuff to alleviate it to some degree. The banding really looks terrible in some cases, definitely not something you’d expect to see in modern engines.
In case someone wants to get a reference as to why I get this banding artifact: It’s because the loaded texture that contains the color information is just 8 bits per channel, meaning we don’t have a lot of resolution to stretch that to the rendered bit depth which is far higher.

It’s come to the point where I’m going to start implementing the ‘final’ step of my custom 3d file format.
The binary step. (oooh, aaah) But really, it’s too slow to parse text and the format is robust enough not to crash every second time I use it so. It’s that time.
The format is not that amazing really. It just supports the bare minimum of what I need, so there’s no awesome animation support like curves, morph targets and stuff like that in it ( …yet).
I’m not really planning to use this format forever. It was sort of my own idea that I would eventually switch to something else, to Collada perhaps. (*whisper* if the damned exporter support was better.)
I would use FBX, but I’m rather put off by the options of parsing. Either parse the text based file or use Autodesk’s FBX parsing library. I’m not even sure the schematic is public so you could parse the binary yourself.
Anyway It’s too heavy for my (rather) lightweight framework, but I might take a closer look at one point.

Uuh… I think that’s about it. I’m doing a ton of other stuff too, but nothing significant to write about.