Developer diary

Shadow mapping, part 6

Cleaning

I had some problems on other levels, everything was pitch black… after trying to correct that for a few hours I finally decided to clean up everything… and the problem disappeared, I guess there was something bad happening in my code :)

Here’s a video of the start of the second level of Alien Blitz

 

Combining old & new

And now for some new tests I wanted to try to combine the old render and the new one, basically I will first render exactly as before, and add shadows on top of it (removing the new lights calculation, just using shadows). So wall shadows will be rendered twice (old + new).

Old / old + new :

capture_2014-12-19_21-03-16_0815_Alien_Blitz_ capture_2014-12-19_21-02-34_0526_Alien_Blitz_

Just re-rendering second level :

capture_2014-12-19_21-00-48_0421_Alien_Blitz_

So basically it’s the same as before except there are more shadows and they are more accurate. The down side is that everything is a bit darker, but not as much as I was expecting.

 

Aliasing

In previous videos/screenshots I was using a 1024px depth map, so there was not that much aliasing, but I think for performance reasons the quality should be selectable. But at lower resolutions aliasing appear.

256 / 512 / 1024 px depth maps :

capture_2014-12-20_12-26-00_0432_Alien_Blitz_ capture_2014-12-20_12-26-17_0173_Alien_Blitz_ capture_2014-12-20_12-26-38_0822_Alien_Blitz_

(Aliasing is not very visible on the thumbnails)

This test case is probably the worst that could happen, the light is just a little higher than ground a few meters away. I tried various PCF techniques (adapted to cube maps) but nothing really worked. One possible way to solve this could be to use a bigger viewport for shadow frame buffer.

512px depth map, x1 viewport / x2 viewport :

capture_2014-12-20_12-32-15_0487_Alien_Blitz_ capture_2014-12-20_12-32-31_0972_Alien_Blitz_

Using a x2 viewport makes small artifacts blend, this is indeed nicer, I couldn’t see a difference with x4 so it’s not included

I also tried mixing PCF in the different processing steps, but got nothing really good.

So I think I will stick to something like :

  • No shadows : same as current
  • Low quality : 256px depth map, x1 viewport
  • Medium quality (default) : 512px depth map, x2 viewport
  • High quality : 1024px depth map, x2 viewport

And I might change some levels to avoid problems in low quality (for example adding a small wall around the path might help in above case)

Updated video, with new render & medium quality shadows

 

Android

I had some problems on Android, textures were not read properly, nothing was working. The problem was quite stupid, it’s just that I wasn’t binding my textures correctly, I guess it worked on desktop because MAX_TEXTURES might be higher.

Now shadow mapping seems to work exactly the same on my Nexus 7 as on PC, but still nothing on my Nexus 10 (black screen, empty depth map, empty shadow buffer), still needs some debugging.
Anyway it’s way too slow to do anything (even with caching), but I just want to make sure I can get it to work in case I do a tutorial later.

Read more

Loading...Loading...

Shadow mapping, part 5

Correcting far

The problem I had previously on the far was because of the pack/unpack functions I was using to store depth data on all the rgba values, now I will just use an alpha texture for lights depth map. So I will loose precision, but in a third person view it doesn’t really matter.

capture_2014-12-19_13-27-04_0323_Alien_Blitz_

All far values work now

 

Correcting multiple lights

My problem with multiple lights was just a small bug in my multi render pass, no idea why it was working on my nvidia card and not on my intel card.

The shadow map :

screenshot200

The render :

capture_2014-12-19_13-38-21_0142_Alien_Blitz_

Of course as there are lots of lights there’s not so much shadows.

 

Colored lights

Adding basic colors is pretty straight forward from here, the shadows & render :

screenshot212 capture_2014-12-19_14-00-28_0090_Alien_Blitz_

Comparing to the current render :

capture_2014-12-14_15-53-51_0733_Alien_Blitz_

There’s still some work to do to get a similar result, mainly because in the current solution I do a lot of smoothing. But the advantage of shadow mapping is that even sprites have a shadow…

After just a few modifications, and trying to smooth a bit (2nd image)

capture_2014-12-19_16-04-50_0762_Alien_Blitz_ capture_2014-12-19_16-05-05_0799_Alien_Blitz_

It doesn’t change that much :)

 

Tests on PC

I ran 2 tests on different configurations and checked the FPS, using the sample level (7 lights)

Tests :

  1. Render everything every frame
  2. Cache depth map, render shadow map, blend shadow map

Results (first number is test 1, second is test 2) :

  • Recent laptop, Integrated Intel card : 26/60
  • Recent laptop, Nvidia card : 53/60
  • Old computer (6 years old), Nvidia card : 60/60

I’m surprised my old computer has such a good result, but even in some recent games it performs better than my laptop (Borderlands Pre Sequel for example), but it can’t render all the effects on these games (old graphical card)

In the first test the depth map is computed each frame, I didn’t try to optimize anything (my shaders are certainly full of bottlenecks), in a final version it should cache the depth map and re-render it only if something is moving in its range. So it would save A LOT of time, I think it will always render at 60fps on these configurations with proper optimizations and caching.

Sadly my netbook is broken, it needs a new memory kit, so I can’t test on it.

 

Futur

I prefer the old rendering, maybe I could do a mix between old and new, to get dynamic shadows but keep the light colors.

I don’t know yet if it will be included on PC version, I will continue working on it for now, and we will see.

 

Tutorial

I think I’ll try to do a clean tutorial with all I learned, basically it will cover

  • Point lights and directional lights
  • Cubemap frame buffers
  • Multiple lights
  • Multi pass rendering (forward rendering)
  • Everything using Libgdx, and Android/iOs/PC compatible

It will not cover caching of lights, everything will be rendered each frame. Because this is a very specific work that depends on your game engine.

The problem I have is I’m pretty sure there are better ways to do it, but at least it works ;)

Read more

Loading...Loading...

Shadow mapping, part 4

Deferred rendering

My fear in previous post were justified, in order to use deferred rendering I need to use OpenGL Multiple Render Targets (MRT), and this is not available in Libgdx as it uses OpenGL 2.0

I tried enabling OpenGL 3 but I think it’s just some preliminary work as it justs crashes the game, something to do with shaders apparently.

Basically from what I understand :

  • MRT is used on frame buffer to render to multiple textures instead of just one (you get access to an array of gl_FragColor in the fragment shader instead of just one)
  • A few textures are saved containing data : colors, positions, normals,…
  • Then next passes will use these textures to just render on the screen space using what was previously calculated, and each pass blends a new light.

This saves a lot of calculations as no unnecessary lights calculations are made, only what is visible on screen is computed.

 

Multi pass rendering

So I tried something else, render the terrain multiple times

  • First time just rendering the terrain without lighting
  • Render one more time per light, each time blending the shadows from the light

The bad thing is that the fragment shader is called multiple times, so it’s not very efficient…

I first tried with a simple approach, just adding a soft shadow on each light

capture_2014-12-18_13-29-20_0506_Alien_Blitz_

I have lots of problems when lights have a limited range, I don’t know why. So I set a very high range for the moment

capture_2014-12-18_18-49-58_0476_Alien_Blitz_

Of course this is not at all a correct result, but at least I can now see that all lights and frame buffers are taken into account.

Now to correct the process :

  • Render all lights (viewed from the usual camera) on a Frame Buffer, each new render just adds its data above the previous one
  • Render the terrain full light, and multiply each fragment with the color from the frame buffer

Basically the frame buffer contains:

screenshot112

And the render becomes :

capture_2014-12-18_21-31-05_0299_Alien_Blitz_

This seems a bit better but I still run into troubles when adding more lights…

In the above example there are 3 lights activated, if I activate the one in the center of the big room the render becomes :

capture_2014-12-18_21-31-34_0105_Alien_Blitz_

It seems the new lights takes the frame buffer of the right light… which doesn’t make sense… it needs more investigation.
*edit* it works better with my nvidia card instead of the integrated intel one, so I must be hitting a limit somewhere

Read more

Loading...Loading...

Shadow Mapping, part 3

Better use of Cubemap

In my previous post I didn’t fully understand the use of cube maps, and I was just generating the render as if the point light was 5 lights… But code can be a lot easier as OpenGL natively supports Cubemap and the glsl code to check if a point is in shadow or not is actually a lot easier.

Another mistake was to not consider top depth for lights, in most cases they are useless, except when a light is near a wall. In this case the light will “see” the wall when looking up.

Sadly it does not seem Libgdx supports cube map frame buffer, so I copied the FrameBuffer class and modified it to include cube maps.

The code can be download here: FrameBufferCubeMap.java

It might be very dirty, I don’t know… first time getting this deep into OpenGL, FrameBuffer… and I adapted it from C++ source… but it seems to work :)

You need to bind each side of the cubemap differently when rendering to this frame buffer, and don’t forget to change the up of the camera

...
frameBufferCube.begin(GL20.GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
camera.up.set(0, -1, 0);
...
frameBufferCube.begin(GL20.GL_TEXTURE_CUBE_MAP_POSITIVE_X);
camera.up.set(0, -1, 0);
...
frameBufferCube.begin(GL20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
camera.up.set(0, 0, -1);
...
frameBufferCube.begin(GL20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
camera.up.set(0, -1, 0);
...
frameBufferCube.begin(GL20.GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
camera.up.set(0, -1, 0);
...
frameBufferCube.begin(GL20.GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
camera.up.set(0, 0, 1);
...

 

And now the traditional screenshots

Here is what happens if you don’t change the up property of the camera :

capture_2014-12-16_14-45-40_0548_Alien_Blitz_

 

The up property is not the same for negative/positive Y as the ones I saw on the Internet, don’t know why :

capture_2014-12-16_15-04-55_0665_Alien_Blitz_

 

After correction and adding the bias back

capture_2014-12-16_15-06-54_0310_Alien_Blitz_ capture_2014-12-16_15-07-04_0616_Alien_Blitz_

 

This seems to be a lot quicker than previous method.

 

Multiple lights

Now, trying to render multiple lights, my first approach was to

  • Have one framebuffer per light
  • Generate shadow map for each light on its own framebuffer
  • Generate the final scene, using arrays of samplerCube (for each light) in the fragment shader

capture_2014-12-16_15-31-49_0332_Alien_Blitz_

Problem is it seems only the last shadow texture is used, and I have lots of troubles getting array of samplerCube in the shader.

As of now I can’t seem to get anything to work, so I guess I’m not using the right technique. I’ve read about deferred shading, but I don’t know yet how it works (nor if it can be done with Libgdx / GL 2.0)

Read more

Loading...Loading...

Shadow Mapping, part 2

Removing artifacts

Removing artifacts near the light is simply done by adding a bias to the depth test, it is good enough in our case

capture_2014-12-14_15-13-53_0960_Alien_Blitz_

I’ve also added back unrealistic shadows on wall: walls on the right/left or down/top have an automatic different shadow applied, it makes gaps easier to see (you can see the small holes on the top-right of the image now, they were previously invisible).

It could be done using global illumination, but this method is a lot quicker (just testing the normal of a surface) and works nicely in Alien Blitz.

 

“Our case”

I will now make some assumptions, in order to get a good visual aspect over rendering speed ratio. It is very specific to Alien Blitz:

  • Most lights have a small range, except sun lights that will probably have a specific code
  • Bullets should not have a realistic shadow, the old one is best as it allows player to easily guess the height of a missile (I’ve tested both, unrealistic shadow is really better for gameplay)
  • View is quite far away, no need for high quality shadows (a FPS view would require such shadows)
  • There can be lots of lights on screen, so they should be computed quickly

These points explain some choices I will make from now on, if at some point I want to develop a first person view game I will have to change lots of code.

 

Testing different shadow map sizes

64px:

screenshot38

capture_2014-12-14_15-16-24_0336_Alien_Blitz_

 

256px:

screenshot39

capture_2014-12-14_15-16-41_0168_Alien_Blitz_

 

1024px:

screenshot40

capture_2014-12-14_15-17-06_0711_Alien_Blitz_

 

64px is obviously too small, 256px should be enough for most lights, and 1024px for high range lights (sun)

There are some artifacts above walls, I will have to correct them with PCF but maybe just as an option (3 quality options for shadows : low without PCF & 256px maps, medium with PCF & 512px maps, high with PCF & 1024px maps, or something like that)

 

Real level test

I’ve changed my code a bit so that light used for shadow mapping is the closest to the player, that allows me to quickly run some tests on actual levels.

capture_2014-12-14_15-31-34_0441_Alien_Blitz_

It really feels good, currently shadows are very big, but when all lights will use shadow mapping it should feel better I think, otherwise I will have to make some changes on lights (higher and looking at the ground)

 

More complex test case

For next modifications I will need a more complex test case, with more lights, colors and such. Here it is (it also let me test that the old code was still working)

capture_2014-12-14_15-53-51_0733_Alien_Blitz_

I should have used this king of effect (different light colors in the same room) in the game, it looks nice :)

 

Point lights / Omni-directional lights

Omni-directional lights require to use a cubemap, basically the scene is rendered 6 times : left/right/up/down/bottom/top

Of course in Alien Blitz top rendering is useless

The idea is just to render the scene 6 times, changing camera looking direction and viewport position/size each time.

Here is the resulting map

screenshot53

I will assume a light does not cast a shadow on itself, it will make things easier (hence the full black image in the bottom-right, the top-right is supposed to store the top view map, but it is unused here)

Time to render this new map now:

capture_2014-12-14_18-45-57_0151_Alien_Blitz_

There are some artifacts on the edges of the 5 generated maps (it can be see on the left/down diagonal), other than that it seem quite fine.

 

What’s next?

I am now considering managing multiple lights, but I’m afraid I will come on some difficulties:

  • Depending on the video card there can be some huge limitations (221 max uniforms vectors, 16 textures, on one of my video cards)
  • I still get 60fps, but I think it is already beginning to be heavy on the gpu (my laptop is increasing fan speed, that’s a good indicator)

Most examples on the Internet are very simple: directional light, one light only,… so I will have to find some better sources on how to manage multiple lights and do lot of tests.

And of course I need to handle colors now.

Read more

Loading...Loading...

Testing shadow mapping

In Alien Blitz lights are computed using a mix between a 2d light texture and some custom code to get smooth lights are avoid artifacts on walls.

It’s a good solution as it is requires some time when loading level but it is quite quick afterwards.

I’ve decided to try to implement shadow mapping, I don’t know if I will apply it to Alien Blitz, maybe just the PC version. We will see… but it is still a good exercise and I’d love to see what it could look like.

I’ve not at all completed the task, but I’ve decided to post some “Work in progress” screenshots.

The scene

I’ve made a custom level, with just some basic walls and one light, here is the current result

capture_2014-12-12_18-15-01_0474_Alien_Blitz_

Light point of view

In order to generate the shadow map we need to set a camera on the light itself (what the light can “see”). For testing purposes it is easier to actually use the game camera first.

For the first tests I’ve decided to use a directional light, point lights need to generate 6 textures (surrounding cube), so I will do that later. This light “looks at” and follows the player

capture_2014-12-12_18-58-36_0973_Alien_Blitz_

Depth map

And now the shaders need to be changed to only get a depth map

capture_2014-12-12_20-06-50_0364_Alien_Blitz_

(the UI elements are added after the 3d rendering, so they will not be saved when using a framebuffer later)

The black & white are inverted in this screenshot, else the wall in the back would be almost invisible/pitch black.

Using a frame buffer

Next step is to revert view to its original state and use a frame buffer to render the light’s camera.

screenshot1

Black and whites are now correctly rendered, I’ve changed the FOV on the camera to be able to view the pillar with the 1:1 ratio (1024×1024)

(I’ve saved the texture using the screenshot code from libgdx, it just needs to be called before ending the frame buffer)

Applying shadow/depth map

Removing previous lighting

capture_2014-12-13_12-15-39_0107_Alien_Blitz_

First try

 

capture_2014-12-13_12-31-28_0440_Alien_Blitz_

Something is happening, it doesn’t crash, and lines move when player moves, we’re getting there

 

After some correction

capture_2014-12-13_15-12-24_0604_Alien_Blitz_

Hmmm it looks like letters and signs… Oops forgot to bind the texture, so it’s using another one (the one used by the font apparently)

 

capture_2014-12-13_15-28-37_0042_Alien_Blitz_

Something is obviously off

 

capture_2014-12-13_15-30-09_0483_Alien_Blitz_

Hey! it looks like there’s a small mecha there…

 

capture_2014-12-13_15-40-17_0790_Alien_Blitz_

Ok, there’s obviously a mecha there, and it moves accordingly. Good, but there are way too much artifacts…

 

capture_2014-12-13_16-25-05_0090_Alien_Blitz_

After a bunch of tests and corrections, pillars’ shadows seem correctly placed, but the light does not go far away (should illuminate walls), there doesn’t seem to be any shadow for the mecha and there are still artifacts…

 

capture_2014-12-13_16-29-50_0694_Alien_Blitz_

Some more tests, still a lot of artifacts but I’m beginning to like what is displayed…

 

capture_2014-12-13_16-32-22_0829_Alien_Blitz_

Haa a lot better, let’s remove the right part

 

capture_2014-12-13_16-34-57_0287_Alien_Blitz_

Nice, I also have the “expected” artifacts near the center of the light. They are normal artifact due to distortion, they are to be expected at this point (and corrected afterwards of course).

 

A small video

What’s next ?

This was a simple example with lots of limitations

  • Shadows are computed each frame
  • Only one light
  • No light color
  • Badly written code

So there’s lots of code to do… but it’s a start and I’m pleased I’ve been able to get some shadow mapping so fast.

Read more

Loading...Loading...

Alien Blitz 3d released on iOs, Alien Mayhem

Alien Blitz released on iOs

Just a quick note, the new Alien Blitz in 3d has been released on iOs. I will publish a full PR and update this website soon. I don’t have a lot of time these days

5.5-20monsters

 

Alien Mayhem

Work to be done for Alien Mayhem is too big, I changed the engine too much last time I worked on it…

The only solution would be to start over, just keeping a few things (wave generator, levels). I don’t plan on working on it yet, maybe later if Alien Blitz has some kind of success.

Read more

Loading...Loading...

Alien Blitz: cleanup, Alien Mayhem: integrating

Alien Blitz: cleanup

Made lots of small changes to the potential future version of Alien Blitz on PC, mainly because they were standing in my todo-list for too long and I needed to clean it up:

  • Aim assist is now configurable (not used when using mouse to aim, only when using keyboard-only or controller)
  • Improved options, made a nice list box to select resolution
  • Camera is a bit farther on PC, and a bit slower to adapt (works better on PC like that)
  • Barrels explode more quickly on PC (as it doesn’t matter if it makes more calculation in a short time)
  • Some bug correction specific to the PC version

 

Alien Mayhem: integrating

I’ve decided to give a try to adapting Alien Mayhem to the new engine, without forking it… I guess I have some work to do now:

capture_2014-10-24_15-27-02_0810_Java_AlienMayhem_core_src_com_microbasic_am_generi

Only 849 errors left to correct… (most of them are just messing with imports, but some are more tricky)

Read more

Loading...Loading...

Alien Blitz 3d – release began, Alien Mayhem ?

Alien Blitz – release began

I’ve finally began releasing the new version of Alien Blitz, it is now available on Google Play and this website (if coming from Desura). I will update it soon on Indie Game Stand, but I’d like to write a small newsletter for this first with a link to the greenlight page.

I’m performing some last tests on iOs, I have some problem debuging with new iOs 8, but the game seems to work fine… So I will send it soon for review…

The update will be live soon on Amazon also, but no one bought it there, so there’s no rush…

bossfights

There will be a specific news when all is released.

 

Alien Mayhem

I had a game based on Alien Blitz 2d called Alien Mayhem (technical name, not the final name) that I never released (I wanted to finish other stuff on Alien Blitz first) but which was almost completed.

It was a mix between a tower defense and Alien Blitz, so:

  • Waves of enemies
  • Turrets to buy, place and upgrade
  • Weapons to upgrade
  • Combo system (kill fast)
  • Player you control
  • Player has to help turrets, go on the field and shoot
  • Player has to pick up money where enemies died
  • Player has some special abilities

And some other features:

  • 11 heroes to unlock
  • 51 maps + 3 tutorial maps
  • Random waves mode

Capture d'écran - 28012014 - 17_39_44

It was supposed to be a free to play, with the story mode free (20 maps, 5 heroes IIRC) and more maps + random waves + more heroes + no ads to be unlocked with a unique fee.

Capture d'écran - 28012014 - 17_42_22

Technically the game was working on a fork of Alien Blitz, so it doesn’t include any of the new features (such as 3d), and it was using an HTML / JavaScript UI for menus.

So if I want to publish it I need to implement the features I added in this game back in current Alien Blitz engine (and not fork it, to hard to maintain), add the missing models (new monsters and new sprites), re-do the UI from scratch (thankfully it wasn’t too complex), and check if I can get all libraries to work on both Android and iOs (ads is ok, Game Center / Google Games is ok, IAP I don’t know)

Capture d'écran - 28012014 - 17_29_50

I am not 100% sure I will work on it, but it seems like a good idea as gameplay was solid and a lot of the work is already done…

Read more

Loading...Loading...

Alien Blitz: easier, bug correction

Easier (mobile)

I made the game easier on mobile version, monsters have 3/4 health and deal 3/4 damage… I did this mostly because it’s harder to play and move on a virtual stick and because most people don’t expect a mobile game to be too hard.

But if you want more challenge just use the hard difficulty mode, or try to reach the secret level of episode 1 quickly to enable nightmare mode.

 

Bug correction

Some more bug correction: it was possible in some circumstances to have negative money after buying upgrades and some monsters could have a negative level.

The good news is that next release should be really bug free, the bad news is that it is being constantly reported.

 

tonsofbullets

 

 

Read more

Loading...Loading...
Page 1 of 3012345...102030...Last »