The recipient of every major "Best RPG of the Year" award, The Elder Scrolls: Daggerfall revolutionizes the world of role-playing games, creating a new standard in 3D graphics and role-playing expansiveness. The second chapter in The Elder Scrolls, Daggerfall contains, literally, hundreds of hours of gameplay. Prepare to experience your new obsession.

Starting off in Daggerfall can overwhelm the senses. No other game has such a huge world to explore. Travel around a land mass twice the size of Great Britain, exploring dungeons, castles, tombs, and even alternative dimensions. Just to walk from one end of the world to the other will take over 2 full weeks in real-time (we actually tested this!) Converse with over 750,000 characters that inhabit this world. Daggerfall is a game that sets new boundaries with over 200 hours of gameplay. It's no wonder that it took almost 3 years to develop this epic game.

You can literally do anything you want and go anywhere you want. Join a guild and climb in rank to become a respected member of a Knightly Order. Become a spy and infiltrate the royal ranks, and even rebel against your own king. Become a thief who slips in and out of the shadows and steals the rare treasures of the world. There are six different endings, if you choose to play out the main story quest, but ultimately the life you choose to live will be a unique experience that no other gamer will encounter.

Image RSS Feed Latest Screens
Daggerfall Art Back Daggerfall Screens Daggerfall Screens
Blog RSS Feed Report abuse Latest News: Improved Terrain Tiling

About Daggerfall Tools for Unity with 0 comments by Interkarma on Dec 19th, 2014

To date, I have used a brute-force approach when tiling textures in cities and terrains. Each texture tile is mapped to a quad of vertices where each corner describes a UV coordinate allowing its texture to be drawn normally, rotated, flipped, or both rotated and flipped. This saves a great deal of texture space as only one version of texture is required to achieve four variations.

While it saves on texture memory (great for a 1996 game), this system has some inherent problems, not least of which is the number of vertices being used. For example, a full 8x8 block terrain has a total of 128x128 quad tiles with 4 vertices each. That's a total of 65536 vertices just to handle the ground plane of a big city like Daggerfall or Wayrest. This is larger than Unity's maximum mesh size, so everything needs to be split up into chunks. As cities are completely flat, wouldn't it be great if we could just render all these tiles onto a single quad, using only 4 vertices for an entire city?

Happily, this is not only possible, we can solve a few other problems with tiled textures in the process. All through the magic of custom shaders.

The first step is to change how the ground atlas is stored. Rather than just reference a single texture and modify using UVs, we're going to pre-transform each texture in all 4 possible configurations (normal, rotated, flipped, rotated+flipped). This removes the need for UV changes and saves time in the fragment shader, and allows for some extra packing to happen as you'll see shortly. The new tile set atlas looks like below (note that Unity texture [0,0] is bottom-left).

Atlas1

In order to reference these tiles in the fragment shader, we also create a tile map texture. This texture packs an index into the red channel that is basically a number 0-255 corresponding to a tile in the atlas above. This texture must be point-sampled to ensure no corruption of indices occurs. The tile map for Daggerfall city is below.

Tilemap

Now the shader has an atlas of tiles and indices referencing which tile to use. The following bit of code will read index from tile map then render out correct texture tile from the atlas.

int index = tex2D(_TilemapTex, i.texcoord0).x * _MaxIndex;
int xpos = index % _TilesetDim;
int ypos = index / _TilesetDim;
float2 uv = float2(xpos, ypos) / _TilesetDim;
float xoffset = frac(i.texcoord0.x * _TilemapDim) / _TilesetDim;
float yoffset = frac(i.texcoord0.y * _TilemapDim) / _TilesetDim;
uv += float2(xoffset, yoffset);
return tex2D(_MainTex, uv);

The result is a fully tiled city quad using just 4 vertices.

TilemapInAction

This works great, and it's fast. If we were just using point filtering with no mipmaps, our job would be done already. Unfortunately linear filtering adds one set of problems and mipmaps add another. The first problem is texture colours bleeding in from adjacent tiles due to how linear filtering works. Image below demonstrates problem, note the dirt texture being sample at edge of water.

Bleeding

There are a few of ways to fix this, but one of the most robust is to manually wrap textures around to their opposite side in the atlas. This means that when the linear filter samples outside the tile area, texture wrapping will be simulated. The new atlas shows this concept with each tile wrapped 50% on all sides. Note: This solution works for tiling textures, but not for non-tiling textures where texture clamping needs to be simulated instead. The atlas generator is yet to support both wrapped and clamped tiles.

Atlas2

With a new atlas format, our fragment shader needs updating to sample interior part of each texture.

// Get offset to tile in atlas
int index = tex2D(_TilemapTex, i.texcoord0).x * _MaxIndex;
int xpos = index % _TilesetDim;
int ypos = index / _TilesetDim;
float2 uv = float2(xpos, ypos) / _TilesetDim;

// Offset to fragment position inside tile
float xoffset = frac(i.texcoord0.x * _TilemapDim) / _GutterSize;
float yoffset = frac(i.texcoord0.y * _TilemapDim) / _GutterSize;
uv += float2(xoffset, yoffset) + _GutterSize / _AtlasSize;

// Return fragment
return tex2D(_MainTex, uv);

These additions fix linear sampling to all but remove bleeding for tiling textures. Compare this image to the earlier version.

BleedingFixed

With texture bleeding taken care of, the next challenge is dealing with mipmaps. The graphics card has no understanding of our atlas, so tile wrapping makes it sample from the wrong mip level, which creates a whole new problem with cracks as shown below (you might need to open image to full size to see the cracking discussed).

MipMapCracks

Fixing this problem requires manually calculating the mip level in fragment shader. Fortunately there's a lot of references online for dealing with this. Rather than just naively return the texture sample using tex2d, we need to use tex2dlod instead. Below is change to final line of code.

// Manually set mip level and return fragment
float mipLevel = GetMipLevel(i.texcoord0, _AtlasSize);
return tex2Dlod(_MainTex, float4(uv.xy, 0, mipLevel));

And the GetMipLevel() function.

float GetMipLevel(float2 iUV, float2 iTextureSize)
{
float2 dx = ddx(iUV * iTextureSize.x);
float2 dy = ddy(iUV * iTextureSize.y);
float d = max(dot(dx, dx), dot(dy,dy));
return 0.5 * log2(d);
}

With this new code, our mip cracking problem has vanished.

MipMapCracksFixed

And there we have it. A super-fast method of tile mapping from an atlas which defeats both texture bleeding and mip sampling problems, and only needs a single quad mesh.

There's still more work to do, mainly around atlas generation. I need to handle wrapped tiles and clamped tiles differently, and manually pack mip levels to improve overall quality. I will get back to this in the new year with my performance review. On the subject of performance, these concepts can be expanded to reduce draw calls for the terrain system and city environments. This is just the first spoke in a big wheel of optimizations.

This last screenshot is of the material inside Unity editor, which shows how everything hangs together.

ShaderInEditor

References
I could not have pulled this off without the help of several people much smarter than myself. All the links below were used in formulating this solution.

Connor Hollis - Fast Tilemap Shader
connorhollis.com/fast-tilemap-shader/

IceFall Games - Terrain Engine
mtnphil.wordpress.com/2011/09/22/terrain-engine/

nVidia - Improve Batching Using Texture Atlasing
developer.nvidia.com/sites/default/files/akamai/tools/files/Texture_Atlas_Whitepaper.pdf

0 FPS - Texture atlases wrapping and mip-mapping
0fps.net/2013/07/09/texture-atlases-wrapping-and-mip-mapping/

Media RSS Feed Latest Video
Downloads RSS Feed Latest Downloads
DaggerXL Version 0.199
Daggerfall

DaggerXL Version 0.199

Jun 27, 2012 DaggerXL Demo 11 comments

Contains XL Engine Launcher, version 0.199 of DaggerXL and build 9.50 of DarkXL.

Version 0.198 Released - Bug Fix Build
Daggerfall

Version 0.198 Released - Bug Fix Build

Mar 9, 2011 DaggerXL Demo 7 comments

Version 0.198 is mainly a bug fix build. One fun feature,though, is that random monsters are no longer just bears - though they still aren't correct.

DaggerXL Version 0.197
Daggerfall

DaggerXL Version 0.197

Mar 8, 2011 DaggerXL Demo 0 comments

The current pre-alpha version of DaggerXL - version 0.197. Please note that this is still a work in progress and that many features need to be implemented...

DaggerXL Version 0.195
Daggerfall

DaggerXL Version 0.195

Mar 7, 2011 DaggerXL Demo 1 comment

luciusDXL made this, obviously. I'm just re-uploading it here because the other file server was going down a lot.

DaggerXL Version 0.181
Daggerfall

DaggerXL Version 0.181

May 18, 2010 DaggerXL Demo 0 comments

The current pre-alpha version of DaggerXL - version 0.181. Please note that this is still a work in progress and that many features need to be implemented...

Daggerfall - Full Game
Daggerfall

Daggerfall - Full Game

Jul 10, 2009 Daggerfall Full Version 25 comments

Bethesda has released their second Elder Scrolls game, Daggerfall, as freeware. The classic RPG is notable for its enormity – being large and ambitious...

Post comment Comments  (10 - 20 of 32)
Akalonor
Akalonor Jun 30 2010, 1:46am says:

:O I have Windows 7 with 32 bit , and apparently the file won't install, it says the application is for a different windows version :S ;( How do I fix that ?

+2 votes     reply to comment
Dervich
Dervich Apr 2 2011, 6:42pm replied:

I have 64 bit but sorry I cant remember how but its possible, don't go and buy something you don't need

+2 votes     reply to comment
kjfytfkytfyt
kjfytfkytfyt Mar 16 2011, 8:35pm replied:

Get a different version of windows, yours is too new, look at the date this was released...

+2 votes     reply to comment
Lymphatic
Lymphatic Mar 23 2011, 2:04am replied:

You can run it on DOSBox. That's how I play it in Linux.

+3 votes     reply to comment
jonteh
jonteh Jan 2 2010, 10:44am says:

i love this game best eldarscrolls game

+6 votes     reply to comment
G4B3
G4B3 Jul 22 2009, 9:25pm says:

Freeware! Awesome!

+3 votes     reply to comment
l0p
l0p Jul 11 2009, 2:48pm says:

I ALWAYS WANTED THIS GAME

-1 votes     reply to comment
Darthlex
Darthlex Jul 11 2009, 10:59am says:

Holy! - It's Freeeeeeeware! yay for classics! ^_^

+2 votes     reply to comment
Kedgeree
Kedgeree Jul 10 2009, 11:13am says:

After reading the summary, Bethesda certainly deserved the reward they got from this game.

+3 votes     reply to comment
Undying_Zombie
Undying_Zombie Nov 15 2007, 5:18pm says:

The only reason why they did not call it Drow is due to that has a copyright on it by Wizards of the Coast ( or who ever owns it now )

+2 votes     reply to comment
mazgon
mazgon Nov 23 2006, 8:41am says:

loloolololololololololololol

-1 votes     reply to comment
Post a Comment
click to sign in

You are not logged in, your comment will be anonymous unless you join the community today (totally free - or sign in with your social account on the right) which we encourage all contributors to do.

2000 characters limit; HTML formatting and smileys are not supported - text only

Icon
Daggerfall
Platform
Windows
Developer & Publisher
Bethesda Softworks
Engine
XnGine
Contact
Send Message
Official Page
Bethsoft.com
Release Date
Released Jul 30, 1996
Game Watch
Track this game
Share
Community Rating

Average

9.4

56 votes submitted.

You Say

-

Ratings closed.

Style
Genre
Role Playing
Theme
Fantasy
Players
Single Player
Project
AAA
Boxshot
Boxshot
Sequels
The Elder Scrolls V: Skyrim, Released Nov 10, 2011
Logo
Oblivion, Released Mar 19, 2006
Logo
Morrowind, Released Apr 25, 2002
Logo
Daggerfall, Released Jul 30, 1996
Logo
Arena, Released Mar 1, 1994
Logo
Twitter

Latest tweets from

It can take up to a few hours for tweets to begin appearing.

Embed Buttons

Promote Daggerfall on your homepage or blog by selecting a button and using the embed code provided (more).

Daggerfall Daggerfall
Daggerfall
Statistics
Rank
2,416 of 26,493
Last Update
1 year ago
Watchers
52 members
Mods
2
Files
8
News
17
Features
3
Reviews
3