Skip to content

Latest commit

 

History

History
174 lines (104 loc) · 6.62 KB

README.md

File metadata and controls

174 lines (104 loc) · 6.62 KB

Extending Lode's Raycaster

The code comes from Lode Vandevenne's tutorial Raycasting III: Sprites.

The purpose of systematically apply some enhancements and document them along the way.

The rest of the original tutorials are here Lode's Computer Graphics Tutorial

Step 1

commit 71797ccd2dc8cd6d633d8ef4bb3a4e2ccc1cc242

screens/step1.gif

The first step just fixes some compiler warnings.

I also didn't feel comfortable distributing this project with the Wolfenstein 3D textures (since they ), so I replaced them with some CC0-licensed graphics from Dungeon Crawl Stone Soup (DCSS)

The Dungeon Crawl Stone Soup graphics are from here: https://opengameart.org/content/dungeon-crawl-32x32-tiles

Step 2: Better vertical strips

screens/step2.gif

The second step doesn't lead to a difference graphically, but internally it draws all the vertical wall strips and the sprites using only integer arithmetic.

Step 2a

commit e0f5cbbc6e2bb3011b210c3a2a2a779c6896769a

Convert the code that draws the vertical strips to use integer only arithmetic.

The integer arithmetic trick is based on the DDA algorithm from this article

Step 2b

commit 8039f41cc5cb93458bb6b80109ac77edf3ab47be

Then you can use the same trick to draw the vertical strips of the sprites.

Step 2c

commit 34993e41b08c4ec51b0b936ae5d99afa2d5f9ac5

While you're at it, you can do the same for the horizontal part of the sprite loop.

Step 3: Skybox

commit c1d6246654886222c54d7fccdcbda7f228669b99

Here I disable the ceiling and draw a skybox.

With a Skybox

Step 4: Fog effects

commit bb0c927871fbf0d17798a698c4c453b262d15436

We fade each pixel to a fog colour, based on its distance from the viewer

Fog effects

Step 5: Doors

commit f5980c0319457d9fc188d3ac40d5f0643f586973

Here we implement doors that can open an close when the player interacts with them.

Closed Door Open Door

To draw doors, if a ray strikes a tile with a door, we take half a step backwards, and check whether we're still in the tile with the door. If we are, we use the distance of the half step, otherwise we resume casting the ray to draw what is beside or behind the door.

Door diagram

Step 6: Look up and down

commit 0ef7d398abb09a70e6952e61d83cc6d2b70f29b7

We implement looking up and down (with the Q and A keys) by shifting the view plane up and down.

Look Down Look Up

Step 7: Jump and crouch

commit 61224aa5a8c08def242fb696b6947d0d12ffd35b

We now implement jumping and crouching by shifting the drawStart and drawEnd variables up and down according to the viewer's height.

Crouching

Step 8: Walls with Transparency

commit 1940b5c13ca01b096249729e97733f27571d1c9f

We implement thin walls that can have transparent pixels that you can see through.

Doorway with transparent pixel Fence with transparent pixels

A 1D Z-buffer doesn't suffice anymore, so we replace it with a 2D depth buffer.

Step 9: Glass windows

commit 4ccf019721f557c539c28d33fb2d0b6bc9a5b84a

We implement glass windows. They're similar to the walls from the previous step, but we blend the pixels on them with the pixels that are behind them.

Glass Window A broken stained glass window

Step 9 Part II: Fixing sprites behind glass

Unfortunately, the way we've been drawing sprites up until now means that they are not visible when they're behind glass windows.

The problem: Sprites behind glass are invisible

The problem is that we draw sprites after we've drawn the glass, by which point the Z-buffer tells us that there is something in front of the sprite and the sprite shouldn't be drawn.

To get around this, we make a couple of changes:

Sprites behind glass window

Step 10: Push Walls

In this part we implement push walls that move backward when the user interacts with them. These can be used to implement secret passages in your levels.

A push wall

Step 11: Diagonal Walls

In this step, we implement walls that run diagonally across the grid.

Some diagonal walls

Intersection between a ray and a diagonal wall