Académique Documents
Professionnel Documents
Culture Documents
� Texture Mapping �
�������������������
�������������������������������������������Ŀ
� THIS FILE MAY NOT BE DISTRIBUTED �
� SEPARATE TO THE ENTIRE PC-GPE COLLECTION. �
���������������������������������������������
Contents:
0. warnings
1. terminology and equations
2. the basics
Perfect texture mapping
DOOM essentials
Wraparound textures
Non-rectangular polygons
3. the hazards
going off the texture map
divide by 0
it'll never be fast enough
4. the complexities
handling arbitrarily-angled polygons
lighting
slow 16-bit VGA cards
mipmapping
-=-=-=-=-=-
| Note: I am not providing any references as I simply
| derived the math myself and worked out the various
| techniques for myself (the 32-bit ADC trick was
| pointed out to me in another context by TJC,
| author of the Mars demo) over the last two years
| (since Wolfenstein 3D and Underworld came out).
-=-=-=-=-=-
TEXTURE
TEXUE
TXR 0. Warnings
X
TEXTURE
TEXUE
TXR 1. Terminology and Equations
X
TEX
TE Terms
T
texture: A texture is a pixelmap of colors which is mapped
onto a polygon using "texture mapping". The size
of the polygon has nothing to do with the size (the
number of pixels) in the texture map.
texture space:
polygon space:
polygon coordinate space:
Since a texture is flat, or two-dimensional, the relation
of the texture to the 3D world can be described with a
special coordinate space known by one of these names.
Because it is only 2D, the space can be characterized with
the location of the texture space in 2D, and two 3D vectors
which represent the axes of the coordinate space. Sometimes
called "uv" space, because the name of the coordinates are
usually u & v.
TEX
TE Notation
T
TEX
TE Equations
T
Oa = Nx*Pz - Nz*Px
Ha = Nz*Py - Ny*Pz
Va = Ny*Px - Nx*Py
Ob = Mx*Pz - Mz*Px
Hb = Mz*Py - My*Pz
Vb = My*Px - Mx*Py
Oc = Mz*Nx - Mx*Nz
Hc = My*Nz - Mz*Ny
Vc = Mx*Ny - My*Nx
a = Oa + i*Ha + j*Va
b = Ob + i*Hb + j*Vb
c = Oc + i*Hc + j*Hc
u = a/c
v = b/c
TEXTURE
TEXUE
TXR 2. The Basics
X
Slower
Sometimes hard to see polygon edges
TEX
TE Perfect Texture Mapping
T
P = V[0]
M = V[1] - V[0] { note these are vector subtractions }
N = V[3] - V[0]
Now, iterate across each row. For each pixel in the polygon
whose screen coordinates are <i,j>, apply the rest of the math
described in section 1; that is, compute a, b, and c, and from
them compute <u,v>.
[ loop #1 ]
for every j which is a row in the polygon
screen = 0xA0000000 + 320*j
for i = start_x to end_x for this row
a = Oa + (Ha * i) + (Va * j)
b = Ob + (Hb * i) + (Vb * j)
c = Oc + (Hc * i) + (Vc * j)
u = 256 * a / c
v = 256 * b / c
screen[i] = texture_map[v][u]
endfor
endfor
TEX
TE Prepare to meet thy DOOM
T
[ loop #2 ]
a = Oa + Va*j
b = Ob + Vb*j
c = Oc + Vc*j
a += start_x * Ha
b += start_x * Hb
c += start_x * Hc
[ loop #3 ]
__setup from loop #2__
u = 256 * a / c
v = 256 * b / c
du = 256 * Ha / c
dv = 256 * Hb / c
for i = start_x to end_x
screen[i] = texture_map[v][u]
u += du
v += dv
endfor
TEX
TE ...wrapped around your finger...
T
A E u=0 u=1
o--------o-___________ B v=0 11112222
|111112222 ---------o 11112222
|111112222 | 33334444
|111112222 | 33334444
|333334444 | v=1
|333334444 |
|333334444 ___________---------o
o--------o- C
D F
[ loop #4 ]
mask = 127, 63, 31, 15, whatever.
for (i=0; i < len; ++i) {
temp = table[(v >> 16) & mask][(u >> 16) & mask];
u += du;
v += dv;
}
mov al,mask
mov ah,mask
mov mask2,ax ; setup mask to do both at the same time
P1 P2
x B _______ C x
/ \
/ \
A / \
\ / D
\ /
\ _______ /
x F E
P3
u=0 u=1
------------
v=0 |..XXoooooo..
|.XXXXoooooo.
|XXXXXXoooooo
|.XXXXXXoooo.
v=1 |..XXXXXXoo..
TEXTURE
TEXUE
TXR 3. The Hazards
X
TEX
TE Cl-cl-cl-close to the Edge
T
At some time when you're texture mapping, you'll
discover (perhaps from the screen, perhaps from a
debugger) that your U & V values aren't within the
0..1 range; they'll be just outside it.
TEX
TE Out of This Domain -- Zero's Paradox
T
What do we do then?
TEX
TE Do the Dog
T
If you care about not slowing down too much in the above
case, or you want to do an "indoor" renderer with lots of
hidden surfaces, you'll find that with texture mapping,
you can ill-afford to use the painter's algorithm.
You pay a noticeable cost for every pixel you texture
map. If you end up hiding 80% of your surfaces (i.e. there
are five "layers" everywhere on the screen), you end up
"wasting" 80% of the time you spend on texture mapping.
The essential idea is to only texture map each screen pixel once.
To do this, you do some sort of "front-to-back" painting, where
you draw the nearest surface first. Any pixel touched by this
surface should never be considered for drawing again.
TEXTURE
TEXUE
TXR 4. The Complexities
X
TEX
TE Arbitrarily-Angled Polygons
T
r += s;
s += t;
R = r
S = s + t
T = 2*t
A cheat:
TEX
TE Light My Fire
T
Here's a flat-shading inner loop. I'm doing this code off the
top of my head, so it may have bugs, but it's trying to show
at least one way you might try to do this. Since I use BP,
I put variables in the FS segment, which means DS points
to the texture, GS to the lighting table.
mov ch,fs:light
adc ax,ax
loop8 shr ax,1 ; restore carry
mov cl,[bx] ; get first sample, setting up cx for color lookup
adc edx,esi ; update v-high and u-low
adc ebx,ebp ; update u-high and v-low
mov bh,dl ; move v-high into tmap lookup register
mov ah,[bx] ; get second sample, save it in ah
adc edx,esi
adc ebx,ebp
mov dh,bl ; save value of bl
mov bx,cx ; use bx to address color map
mov al,gs:[bx] ; lookup color for pixel 1
mov bl,ah ; switch to pixel 2
mov ah,gs:[bx] ; lookup color for pixel 2
mov es:[di],ax ; output both pixels
mov bl,dh ; restore bl from dh
mov bh,dl
adc ax,ax ; save carry so we can do CMP
add di,2
cmp di,fs:last_di ; rather than having to decrement cx
jne loop8
TEX
TE The Postman Always Rings Twice
T
TEX
TE Mipmapping (or is it Mip-Mapping?)
T
TEXTURE
TEXUE
TXR Where Do We Go From Here?
X
o Better lighting
o Colored lighting (requires complex lookup tables)
o Phong shading (interpolation of normals--one sqrt() per pixel!)
o Higher resolution (640x400, or 640x400 and anti-alias to 320x200)
o A lot more polygons
o Bump mapping (can be done today with huge amounts of precomputation)
o Curved surfaces