Vertex and Pixel Shaders: Making the world safe for Computer Graphics Adrian Perez 15-463: Computer Graphics 2 February 27th, 2001

Download Report

Transcript Vertex and Pixel Shaders: Making the world safe for Computer Graphics Adrian Perez 15-463: Computer Graphics 2 February 27th, 2001

Vertex and Pixel Shaders:
Making the world safe for Computer Graphics
Adrian Perez
15-463: Computer Graphics 2
February 27th, 2001
Administrivia
 Homework
1 will be handed back on
Thursday
 Midterm is next Tuesday
 Review for midterm is this Thursday.
Talk Outline
 Motivation
for vertex/pixel shaders
 Vertex Shaders
 Implementation
in DX8
 Examples
 Pixel
Shaders
 Implementation
in DX8
 Examples
 Integration
with other areas of DX8
But First…holy war update
 Direct3D
won. Get over it.
 OpenGL cannot accommodate the
speed at which the graphics industry is
moving now.
 All
of the extentions to do things like vertex
and pixel shading are vendor-specific.
 Direct3D
stopped sucking a few
versions ago anyway.
Transformation and Lighting
 The
way D3D used to be was fixedfunction
 Unlit
primitives (objectspace
position/normal/material/uv’s)
 Lit primitives (objectspace
position/color/uv’s)
 Transformed-and-lit primitives
(screenspace position/color/uv’s)
Transformation and Lighting
 The
Good
 Provided
a mechanism for people to roll
their own T&L (back when everybody did
so)
 The
Bad
 Restrictive
in function. You were bound to
D3D’s lighting model and transformation
paradigm; not a terribly big deal for awhile
Transformation and Lighting

Games these days want more control over
the hardware



Important because otherwise, every game is going
through the same code path, making them look
very similar
Especially important since hardware is getting unfucking-believably fast
Microsoft and nVidia realized that a more
generic way for applications to perform
transformation and lighting was needed
Enter Vertex Shaders

A Vertex Shader is essentially assembly
language for the T&L engine


Subset of most ASM languages: no branching, for
example
If hardware T&L is available, the op-codes
are just downloaded to the chip and run
natively
 The op-codes are interpreted by a
surprisingly fast software implementation if
T&L hardware isn’t available
Enter Vertex Shaders

The Good




Amazingly powerful
You are not bound to provide it any specific data
as input, as you are writing the handling code
Much more precision – everything is in floating
point
The Bad


Hard to debug and grok
We’re right back in assembly hacking land
Vertex Shader Registers

Input Registers

Output Registers
Name Count
R/W
Name Count
R/W
an
1 scalar
W only
oDn
2 vectors
W only
c[n]
96 vectors
R/W
oFog
1 scalar
W only
rn
12 vectors
R/W
oPos
1 vector
W only
vn
16 vectors
R only
oPts
1 scalar
W only
oTn
4 vectors
W only
note: all vectors are 4 floats
Vertex Shader Instructions
add
dp3
dp4
dst
expp
lit
logp
mad
max
min
mov
mul
rcp
rsq
Sum
Three-components dot-product
Four-component dot-product
Distance vector
Exponential 10-bit precision
Lighting coefficients
Logarithm 10-bit precision
Multiply and add
Maximum
Minimum
Move
Multiply
Reciprocal
Reciprocal square root
sge
slt
sub
def
vs
exp
frc
log
m3x2
m3x3
m3x4
m4x3
m4x4
Set on greater or equal than
Set on less than
Subtract
Define Constants
Version and Type
Exponential base2 full precis.
Fraction
Logarithm base 2 full precision
3×2 vector matrix multiply
3×3 vector matrix multiply
3×4 vector matrix multiply
4×3 vector matrix multiply
4×4 vector matrix multiply
Vertex Shader Semantics

Shaders are defined in a separate source file.
They are ‘compiled’ into bytecode (at runtime,
if you wish) and then the bytecode can be
loaded onto the card.
 When you render, you choose a vertex
shader to use
 Fixed-function pipeline is still available (as a
hard-coded vertex shader)
Vertex Shader Examples
Vertex Shader Examples
#include "Constants.h"
// v0 -- position
// v1 -- normal
// v2 -- tex coord
vs.1.0
// compute world space position
dp4 r1.x, v0, c[CV_WORLD_0]
dp4 r1.y, v0, c[CV_WORLD_1]
dp4 r1.z, v0, c[CV_WORLD_2]
dp4 r1.w, v0, c[CV_WORLD_3]
// transform position
dp4 oPos.x, v0, c[CV_WORLDVIEWPROJ_0]
dp4 oPos.y, v0, c[CV_WORLDVIEWPROJ_1]
dp4 oPos.z, v0, c[CV_WORLDVIEWPROJ_2]
dp4 oPos.w, v0, c[CV_WORLDVIEWPROJ_3]
// vector from point to eye
add r2, c[CV_EYE], -r1
// transform normal
dp3 r0.x, v1, c[CV_WORLD_IT_0]
dp3 r0.y, v1, c[CV_WORLD_IT_1]
dp3 r0.z, v1, c[CV_WORLD_IT_2]
// normalize normal
dp3 r0.w, r0, r0
rsq r0.w, r0.w
mul r0, r0, r0.w
// normalize e
dp3 r2.w, r2, r2
rsq r2.w, r2.w
mul r2, r2, r2.w
// e dot n
dp3 oT1.x, r0, r2
// l dot n
dp3 oT0.x, r0, c[CV_LIGHT_DIRECTION]
Vertex Shader Examples
Vertex Shader Examples
; Distorts vertices in eye-space to give a fish-eye lens effect
#include "trees.h"
#define FACTOR_KPLUS1
c[CV_CONSTANTS].x
#define XYZW_MAX_XZRATIO x
#define XYZW_FACTOR_K
y
#define XYZW_ZERO
z
#define XYZW_ONE
w
vs.1.0
; Transform position to view space
dp4 r0.x, v0, c[CV_WORLDVIEW_0]
dp4 r0.y, v0, c[CV_WORLDVIEW_1]
dp4 r0.z, v0, c[CV_WORLDVIEW_2]
dp4 r0.w, v0, c[CV_WORLDVIEW_3]
; scale x and y, set z and w to 0
mul r1, r0, c[CV_FISHEYEINFO].xxzz
; compute normalized distance from camera (camera in viewspace is alwasy at (0,0,0))
; r1.x = sqrt(x^2 + y^2)/z
dp3 r1.x, r1, r1
rsq r1.y, r1.x
mul r1.y, r1.y, r0.z
rcp r1.x, r1.y
; and take the absolute value
max r1.x, r1.x, -r1.x
; compute (k*d + 1)
mad r1.z, r1.x, c[CV_FISHEYEINFO].XYZW_FACTOR_K,
c[CV_FISHEYEINFO].XYZW_ONE
; compute (k+1)/(k*d + 1) -- this is the reciprocal formula of the
; above referenced web-page because our distances are
; generally not less than 1.0!
rcp r1.z, r1.z
mul r1.xy, FACTOR_KPLUS1, r1.z
; only scale the original x, y with this factor
mul r0.xy, r0, r1
; transform new position to clip space
dp4 oPos.x, r0, c[CV_PROJ_0]
dp4 oPos.y, r0, c[CV_PROJ_1]
dp4 oPos.z, r0, c[CV_PROJ_2]
dp4 oPos.w, r0, c[CV_PROJ_3]
; Draw using supplied tree color
mov oD0.xyzw, v1
mov oT0.xy, v2
Vertex Shader Examples
One Last Example…
One Last Example…
vs.1.0
; Projected Textures
; Adrian Perez
; 2/27/01
; Constants:
; c0-c3 - World+View+Projection matrix
; c4-c7 - Texture matrix 1
; c8 - Color
; c9 - 1.0
; c10 - -0.5's for adjusting the texture coordinate
; c11 - Texture position 1 (worldspace)
; c12-c15 - world->model matrix
; Transform position
m4x4 oPos, v0, c0
; r3: the light positoin in worldspace
mov r3, c11
; Set r0 to the clip-space view from the texture light
m4x4 r0, v0, c4
; Normalize r5 with r6
mul r5.xyz, r5.xyz, r6.xyz
; Fill r1 with 1's
mov r1, c9
; Compute two recriprocals to do perspective correction
rcp r1.xy, r0.z
; r6: Compute a dot product to find the diffuse light
dp3 r6.x, r5, v3
; Apply reciprocals
mul r2, r0, r1
; subtract 0.5's to adjust the texture coordinates
add r2.xy, r2.xy, c10.xy
; r4: the light position in modelspace
m4x4 r4, r3, c12
; r5: subtract the model-space position to get a light vector
sub r5, r4, v0
; r8: store the temp length
dp3 r8.w, r5, r5
; r6: reciprocal square root of the scalar
rsq r6.xyzw, r8
; modulate r6 by the diffuse color
mul r6, r6.xxxx, c8
; Write out the color and texture
mov oD0, r6
mov oT0, r2
Pixel Shaders
 Same
idea as vertex shaders, but they
control how textures and colors are
combined per-pixel
 Currently there is no hardware that
implements them
 The GeForce3 (when it comes out) will
do them, so will the XBox
Pixel Shaders
 The
Good
 Explicit
control of texture combining
 Lots of Nifty Tricks (EMBM)
 The
Bad
 Designed
for a more general piece of
hardware; a lot of the functionality of the
GeForce3 is not exposed
Pixel Shader Registers
Name
I/O
Min. Number
Max/Inst
Source
cn
Read-only
8
2
API call
rn
Read/write
2
2
Written
tn
Read/write
4
1
Textures
vn
Read-only
2
1
Vertex Colors
Pixel Shader Instructions
add Add
cnd Conditional
dp3 Three-Component Vector DotProduct
lrp Linear Interpolation Blend
mad Multiply and Add
mov Copy Source Into Destination
mul Modulate
sub Loads the difference of the two
colors in the source operands.
tex No Modification
texbem
Bump Environment Map
texbeml Bump Environment Map
with Luminance
texcoord Texture Coordinate
texkill Mask Out Pixel
texm3x2pad Input to 3×2 Matrix
Multiply
texm3x2tex 3×2 Matrix Multiply
Result
texreg2ar Remapping Alpha and
Red Components
texreg2gb Remapping Green and
Blue Components
texm3x3pad Input to 3×3 Matrix
Multiply
texm3x3spec Specular Reflection
and Environment Mapping
texm3x3tex 3×3 Matrix Multiply
Result
texm3x3vspec Specular
Reflection/Environment Mapping
without Constant Eye Vector
Pixel Shader Examples
 Unfortunately,
right now the only way to
develop pixel shader apps is to use the
Reference Rasterizer. So source on
how to use it is pretty scarce
 The documentation is also pretty
cryptic, it’s not nearly as wellengineered as vertex shaders are
Pixel Shader Examples
Pixel Shader Examples
Other Cool Shit in DX8

N-Patches




Subdivision scheme that requires no adjacency
information. You provide a set of vertices and
vertex normals, and it renders a smooth mesh.
Neat: You send the base level mesh down to the
card, and your vertex shader gets fed the
subdivided vertices.
This is one good way to get around the fact that
you can’t create new vertices in a shader
Bezier surfaces

Yea, yea… they’re not as cool as N-Patches
N-Patches
Other Cool Shit in DX8
 Volume
Textures
 Holy
crap these things fucking rock
 Finally, an elegant way to handle
explosions and rocket flares

Plus a million other tricks
 Third
texture coordinate, they behave
almost exactly like 2D textures
Other Cool Shit not in DX8
 Shadow
Mapping
 Supported
by the GeForce3, but the
functionality is not exposed by DX8.
 And yes, it is exposed in OpenGL. (sigh…)
Conclusion
 DirectX
8.0 is the fucking bomb.
Questions?
? ? ?