# lecture9

Document Sample

```					Illumination and Shading

Lights
Diffuse and Specular Illumination
BasicEffect
Setting and Animating Lights
Shaders and HLSL
Lambertian Illumination
Pixel Shaders
Textures

CSE 473 Dr. Charles B. Owen
1                                 Fundamentals of 3D Game Development
Lights               Lights in a computer graphics
system mirror real-world lights
Many things are
possible, but
usually lights are
points in space
or vectors

CSE 473 Dr. Charles B. Owen
2                         Fundamentals of 3D Game Development
An Effect controls how a primitive is drawn on
Models and Effects                the screen. It sets colors, textures, etc.

Model
Name
ParentBone
Bones                               Meshes
(ModelBone)                         (ModelMesh)                   BoundingSphere

MeshParts
Effects                         Vertices
(ModelMeshPart)

Vertex Indexes
Effect
(Triangles)

CSE 473 Dr. Charles B. Owen
3                                           Fundamentals of 3D Game Development
Our DrawModel function
private void DrawModel(GraphicsDeviceManager graphics, Model model, Matrix world)
{
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);

foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index] * world;
effect.View = game.Camera.View;
effect.Projection = game.Camera.Projection;
}
mesh.Draw();
}
}

CSE 473 Dr. Charles B. Owen
4                                             Fundamentals of 3D Game Development
The XNA graphics pipeline
Multiply by                                      Effect
World Matrix

Multiply by
View Matrix                                  Vertex
Shader
Compute Color
Vertex position
Vertex normal                              Multiply by
Texture coordinate                      Projection Matrix
Vertex color
other stuff sometimes…
Homogenize and
Clip

Pixel Shader                  Shade

CSE 473 Dr. Charles B. Owen
5                                     Fundamentals of 3D Game Development
We’ll often use reflection and illumination
Some Terms                           just about interchangeably.

Illumination – What gives a surface its color. This is what our effect will
compute.

Material – Description of the surface. Will include one or more colors.
These are parameters set in the effect.

Reflection – The reflection of light from a surface. This is what we will
simulate to compute the illumination.

Shading – Setting the pixels to the illumination

CSE 473 Dr. Charles B. Owen
6                                           Fundamentals of 3D Game Development
BasicEffect is a common starting point!
BasicEffect in XNA

BasicEffect is the only “out of
the box” effect in XNA

You’ll likely never use it in a real game!
We nearly always need more
functionality than BasicEffect provides

CSE 473 Dr. Charles B. Owen
7                                            Fundamentals of 3D Game Development
Plus some misc stuff like fog
BasicEffect supports                      and vertex lighting

Material properties
Diffuse and Specular colors
Emissive color
Texture

Three directional lights
Diffuse Color
Specular Color
Direction (vector)

CSE 473 Dr. Charles B. Owen
8                                  Fundamentals of 3D Game Development
Directions are which way light moves
EnableDefaultLighting()                                (opposite of OpenGL) and must be
public void EnableDefaultLighting()                normalized vectors.
{
this.LightingEnabled = true;
this.AmbientLightColor = new Vector3(0.05333332f, 0.09882354f, 0.1819608f);
Vector3 vector = new Vector3(1f, 0.9607844f, 0.8078432f);
this.DirectionalLight0.DiffuseColor = vector;
this.DirectionalLight0.Direction = new Vector3(-0.5265408f, -0.5735765f, -0.6275069f);
this.DirectionalLight0.SpecularColor = vector;
this.DirectionalLight0.Enabled = true;
this.DirectionalLight1.DiffuseColor = new Vector3(0.9647059f, 0.7607844f, 0.4078432f);
this.DirectionalLight1.Direction = new Vector3(0.7198464f, 0.3420201f, 0.6040227f);
this.DirectionalLight1.SpecularColor = Vector3.Zero;
this.DirectionalLight1.Enabled = true;
vector = new Vector3(0.3231373f, 0.3607844f, 0.3937255f);
this.DirectionalLight2.DiffuseColor = vector;
this.DirectionalLight2.Direction = new Vector3(0.4545195f, -0.7660444f, 0.4545195f);
this.DirectionalLight2.SpecularColor = vector;
this.DirectionalLight2.Enabled = true;
}

CSE 473 Dr. Charles B. Owen
9                                                     Fundamentals of 3D Game Development
Elements of Illumination at a point

N – The surface normal
L – Vector to the light
V – Vector to the eye
R – Reflection direction

CSE 473 Dr. Charles B. Owen
10                              Fundamentals of 3D Game Development
Reflection

What we need is the amount
of light reflected to the eye

Objects the same “color” may
reflect light very differently

This consists of several components…
CSE 473 Dr. Charles B. Owen
11                                         Fundamentals of 3D Game Development
Three Parts of Illumination
Ambient Reflection
Background light in the world
Simulates light bouncing from
surfaces

Diffuse Reflection
Deep color of the surface
Gives objects their color

Specular Reflection
Shiny reflections
Causes bright highlights on objects.

CSE 473 Dr. Charles B. Owen
12                                     Fundamentals of 3D Game Development
Small amount of light that is assumed to hit
Ambient Illumination   all surfaces. Simulates the idea of light
bouncing around the room.

CSE 473 Dr. Charles B. Owen
13                           Fundamentals of 3D Game Development
BasicEffect light ambient color
basicEffect.AmbientLightColor = new Vector3(0.0533f, 0.0988f, 0.182f);

Color values are RGB in a vector.
Each value ranges from 0 to 1.

The contribution due to ambient light will typically be very small, since it’s
assumed to hit everything in the scene. Sometimes a bit of a blue tint helps
make this more realistic.

CSE 473 Dr. Charles B. Owen
14                                                  Fundamentals of 3D Game Development
Diffuse Reflection
• Diffuse reflection - light reflected in all directions
equally (or close to equally)
– Most objects have a component of diffuse reflection (other
than pure specular reflection objects like mirrors)

Diffuse reflection is what
makes the blue ball blue!

CSE 473 Dr. Charles B. Owen
15                                 Fundamentals of 3D Game Development
Diffuse Illumination

CSE 473 Dr. Charles B. Owen
16                     Fundamentals of 3D Game Development
Diffuse light color

basicEffect.DirectionalLight0.DiffuseColor = new Vector3(0.5f, 0.5f, 0.5f);
basicEffect.DirectionalLight1.DiffuseColor = new Vector3(0.9647059f, 0.7607844f, 0.4078432f);
basicEffect.DirectionalLight2.DiffuseColor = new Vector3(0.3231373f, 0.3607844f, 0.3937255f);

Consider this to be the color of the light. Be careful not to cause too much
light! There is a tendency to make all of the lights in a scene (1, 1, 1). This
will usually make the scene too bright.

Example with three lights all
set to (1,1,1)

CSE 473 Dr. Charles B. Owen
17                                                 Fundamentals of 3D Game Development
Materials are assumed to have two
Specular Illumination   colors: a diffuse color and a specular
color.

Diffuse Only

Specular Contribution
CSE 473 Dr. Charles B. Owen
18                      Fundamentals of 3D Game Development
Specular Reflection
• Specular reflection - If the light hits the surface and is
reflected off mostly in a reflection direction, we have
specular reflection.
– There is usually some diffusion.
– A perfect specular object (no diffusion at all) is a mirror.
– Most objects have some specular characteristics

Specular reflection makes bright
highlights on objects.

CSE 473 Dr. Charles B. Owen
19                                    Fundamentals of 3D Game Development
Diffuse and                       Diffuse illumination is view independent.
Specular illumination is view dependent.
Specular colors
• Typically the colors reflected for diffuse and specular
reflection are different
– Diffuse – Generally the surface appearance
– Specular – The color of bright highlights, often more white
then the surface color

CSE 473 Dr. Charles B. Owen
20                                  Fundamentals of 3D Game Development
Usually you will make the light specular
Specular Light Color                            color equal to the diffuse color. The
surfaces reflect differently, but the light is
just one color. When we do our own
illumination we’ll dispense with the
separate specular light color.

basicEffect.DirectionalLight0.SpecularColor = new Vector3(0.5f, 0.5f, 0.5f);
basicEffect.DirectionalLight1.SpecularColor = Vector3.Zero;
basicEffect.DirectionalLight2.SpecularColor = basicEffect.DirectionalLight2.DiffuseColor;

CSE 473 Dr. Charles B. Owen
21                                                     Fundamentals of 3D Game Development
Somewhat better bedroom lighting
public void BetterBasic(BasicEffect effect)
{
effect.LightingEnabled = true;
effect.AmbientLightColor = new Vector3(0.05333332f, 0.09882354f, 0.1819608f);

effect.DirectionalLight0.DiffuseColor = new Vector3(0.7f, 0.7f, 0.7f);
effect.DirectionalLight0.SpecularColor = effect.DirectionalLight0.DiffuseColor;
effect.DirectionalLight0.Direction = new Vector3(0, -1, 0);
effect.DirectionalLight0.Enabled = true;

effect.DirectionalLight1.DiffuseColor = new Vector3(0.6f, 0.6f, 0.6f);
effect.DirectionalLight1.SpecularColor = effect.DirectionalLight1.DiffuseColor;
effect.DirectionalLight1.Direction = Vector3.Normalize(new Vector3(-1, -1, -1));
effect.DirectionalLight1.Enabled = true;

effect.DirectionalLight2.DiffuseColor = new Vector3(0.5f, 0.5f, 0.5f);
effect.DirectionalLight2.SpecularColor = effect.DirectionalLight2.DiffuseColor;
effect.DirectionalLight2.Direction = Vector3.Normalize(new Vector3(-1, -1, 1));
effect.DirectionalLight2.Enabled = true;
}

CSE 473 Dr. Charles B. Owen
22                                                       Fundamentals of 3D Game Development
Setting Lighting
protected void DrawModel1(GraphicsDevice graphics, Camera camera, Model model, Matrix world)
{
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);

foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
BetterBasic(effect);
effect.World = transforms[mesh.ParentBone.Index] * world;
effect.View = camera.View;                   public void BetterBasic(BasicEffect effect)
effect.Projection = camera.Projection;       {
effect.LightingEnabled = true;
}                                                effect.AmbientLightColor = new Vector3(0.05333332f, 0.09882354f, 0.1819608f);
mesh.Draw();
}                                                  effect.DirectionalLight0.DiffuseColor = new Vector3(0.7f, 0.7f, 0.7f);
effect.DirectionalLight0.SpecularColor = effect.DirectionalLight0.DiffuseColor;
}                                                                  effect.DirectionalLight0.Direction = new Vector3(0, -1, 0);
effect.DirectionalLight0.Enabled = true;

This is the basic way to set                                        effect.DirectionalLight1.DiffuseColor = new Vector3(0.6f, 0.6f, 0.6f);
effect.DirectionalLight1.SpecularColor = effect.DirectionalLight1.DiffuseColor;
lighting in XNA. But, if your                                       effect.DirectionalLight1.Direction = Vector3.Normalize(new Vector3(-1, -1, -1));
effect.DirectionalLight1.Enabled = true;
lighting does not change, this is
effect.DirectionalLight2.DiffuseColor = new Vector3(0.5f, 0.5f, 0.5f);
very inefficient.                                                   effect.DirectionalLight2.SpecularColor = effect.DirectionalLight2.DiffuseColor;
effect.DirectionalLight2.Direction = Vector3.Normalize(new Vector3(-1, -1, 1));
effect.DirectionalLight2.Enabled = true;
}

CSE 473 Dr. Charles B. Owen
23                                                                       Fundamentals of 3D Game Development
This sets the lights right after the
Setting it only once                                   model is loaded. Once set, they
stay set until you change them.

public override void LoadContent(ContentManager Content)
{
Bedroom = Content.Load<Model>("Bedroom");

foreach (ModelMesh mesh in Bedroom.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
BetterBasic(effect);
}
}
}

CSE 473 Dr. Charles B. Owen
24                                                 Fundamentals of 3D Game Development
Note that I’m rotating the light direction.
Animated Lights
private float angle = 0;

public override void Update(GameTime gameTime)
{
if (Lighting == LightingType.Disco)
{
angle += (float)(gameTime.ElapsedGameTime.TotalSeconds * Math.PI * 2);

foreach (ModelMesh mesh in Bedroom.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
Matrix L = Matrix.CreateRotationY(angle);
effect.DirectionalLight2.Direction = L.Backward;
}
}
}
Simple enough, just move, then update.
}

CSE 473 Dr. Charles B. Owen
25                                                       Fundamentals of 3D Game Development
You can call this to change the
Other Options                                 lighting only when it is done.

private void SetLighting()
{
foreach (ModelMesh mesh in Bedroom.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
SetTheLightingFunction(effect);
}
}
}

CSE 473 Dr. Charles B. Owen
26                                            Fundamentals of 3D Game Development
It is time we started creating
BasicEffect S**ks                                our own effects!
For most applications, BasicEffect is a poor choice.

Its pretty big as effects go, with a
bunch of options. Effects load into
the graphics card as you render.

Its not that efficient, since it does a
lot of work you don’t always need.

The lights are directional (vectors),
we often need lights at a position in
space.

CSE 473 Dr. Charles B. Owen
27                                      Fundamentals of 3D Game Development
Replacing at runtime can be the best choice
Replacing an Effect                  while getting the effect working!

This lecture will replace the effect at runtime. Step assignment will replace
the effect at content processing time (generally the better choice).

CSE 473 Dr. Charles B. Owen
28                                         Fundamentals of 3D Game Development
This is the default effect Visual
My First Effect: FirstEffect.fx                                 Studio will create when you do
New/Effect. It does nothing except
float4x4 World;                                            set pixels to red.
float4x4 View;
float4x4 Projection;              VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
struct VertexShaderInput            VertexShaderOutput output;
{
float4 Position : POSITION0;       float4 worldPosition = mul(input.Position, World);
};                                    float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
struct VertexShaderOutput
{                                     return output;
float4 Position : POSITION0;   }
};
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
return float4(1, 0, 0, 1);
}

technique FirstShader
{
pass Pass1
{
VertexShader = compile vs_1_1 VertexShaderFunction();
PixelShader = compile ps_1_1 PixelShaderFunction();
}
}

CSE 473 Dr. Charles B. Owen
29                                                          Fundamentals of 3D Game Development
What this does

Anywhere there is something
to draw, it draws red

Always something to draw other
than through the window.

CSE 473 Dr. Charles B. Owen
30                                    Fundamentals of 3D Game Development
firstEffect = Content.Load<Effect>("FirstEffect");
How to use this…
foreach (ModelMesh mesh in Bedroom.Meshes)
{
Loading/Installing                           foreach (ModelMeshPart part in mesh.MeshParts)
in LoadContent()                             {
part.Effect = firstEffect;
}
Drawing                               }

protected void DrawModel(GraphicsDevice graphics, Camera camera, Model model, Matrix world)
{
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);

foreach (ModelMesh mesh in model.Meshes)
{
foreach (Effect effect in mesh.Effects)
{
effect.Parameters["World"].SetValue(transforms[mesh.ParentBone.Index] * world);
effect.Parameters["View"].SetValue(camera.View);
effect.Parameters["Projection"].SetValue(camera.Projection);
}
mesh.Draw();
}
}

CSE 473 Dr. Charles B. Owen
31                                                        Fundamentals of 3D Game Development
Setting the effect parameter sets the
What does what…                                    equivalent value inside the effect.

effect.Parameters["World"].SetValue(transforms[mesh.ParentBone.Index] * world);
effect.Parameters["View"].SetValue(camera.View);
effect.Parameters["Projection"].SetValue(camera.Projection);

Sets

float4x4 World;
float4x4 View;
float4x4 Projection;

CSE 473 Dr. Charles B. Owen
32                                                 Fundamentals of 3D Game Development
The process

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;                                                  The Vertex Shader runs first
float4 worldPosition = mul(input.Position, World);                        It converts object vertex
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
coordinates into projected
coordinates.
return output;
}

Once per vertex

The Pixel shader runs next.                             float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
It computes the actual pixel                                return float4(1, 0, 0, 1);
color                             }

Once per pixel

CSE 473 Dr. Charles B. Owen
33                                                                    Fundamentals of 3D Game Development
Adding a Material Property

// This is the surface diffuse color       I added this line to the veretx
float3 DiffuseColor = float3(0, 0, 0);     shader

And changed the pixel
shader to this
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
return float4(DiffuseColor, 1);
}

CSE 473 Dr. Charles B. Owen
34                                               Fundamentals of 3D Game Development
Setting this Effect
private void SetDiffuseColorEffect()
{
foreach (ModelMesh mesh in Bedroom.Meshes)
{
foreach (ModelMeshPart part in mesh.MeshParts)
{
BasicEffect bEffect = part.Effect as BasicEffect;
part.Effect = diffuseColorEffect.Clone(part.Effect.GraphicsDevice);

part.Effect.Parameters["DiffuseColor"].SetValue(bEffect.DiffuseColor);
}
}
}

The default content processing supplied a BasicEffect object with the color
set in it. We’re creating our own effect and setting the color to match what
was loaded.

Note the “Clone”. This makes a copy of the effect. Since we’re putting a
material property into it, we need a unique copy here.
CSE 473 Dr. Charles B. Owen
35                                                         Fundamentals of 3D Game Development
Each pixel is simply set to the material
What this does   diffuse color. No lighting is included, yet.

CSE 473 Dr. Charles B. Owen
36                     Fundamentals of 3D Game Development
I’ve moved our computation to the vertex shader
Now let’s do                                    (why?). Ambient illumination is simply the light
real lighting                                   ambient color times the surface diffuse color.
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
float4x4 World;
float4x4 View;                                      float4 worldPosition = mul(input.Position, World);
float4x4 Projection;                                float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
// This is the surface diffuse color
float3 DiffuseColor = float3(0, 0, 0);              float3 color = LightAmbient * DiffuseColor;
output.Color = float4(color, 1);
// Light definition
float3 LightAmbient = float3(0.07, 0.1, 0.1);       return output;
}
struct VertexShaderInput
{                                               float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
float4 Position : POSITION0;                 {
};                                                 return input.Color;
}
struct VertexShaderOutput
{                                               technique FirstShader
float4 Position : POSITION0;                 {
float4 Color : COLOR0;                         pass Pass1
};                                                {
VertexShader = compile vs_1_1 VertexShaderFunction();
PixelShader = compile ps_1_1 PixelShaderFunction();
}
}

CSE 473 Dr. Charles B. Owen
37                                                                   Fundamentals of 3D Game Development
Note that the VertexShaderOutput
Some Things                                                    now has a color.

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;

float4 worldPosition = mul(input.Position, World);
float4x4 World;                                     float4 viewPosition = mul(worldPosition, View);
float4x4 View;                                      output.Position = mul(viewPosition, Projection);
float4x4 Projection;
float3 color = LightAmbient * DiffuseColor;
// This is the surface diffuse color                output.Color = float4(color, 1);
float3 DiffuseColor = float3(0, 0, 0);
return output;
// Light definition                             }
float3 LightAmbient = float3(0.07, 0.1, 0.1);
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
struct VertexShaderInput                        {
{                                                  return input.Color;
float4 Position : POSITION0;                 }
};
technique FirstShader
struct VertexShaderOutput                       {
{                                                 pass Pass1
float4 Position : POSITION0;                   {
float4 Color : COLOR0;                           VertexShader = compile vs_1_1 VertexShaderFunction();
};                                                  PixelShader = compile ps_1_1 PixelShaderFunction();
}
}

CSE 473 Dr. Charles B. Owen
38                                                                   Fundamentals of 3D Game Development
What this looks like

Inset has brightness artificially increased in Photoshop
CSE 473 Dr. Charles B. Owen
39                                    Fundamentals of 3D Game Development
Now for Diffuse Illumination
What we need to know
 Light location in space
 Light color

float3 Light1Location = float3(5, 221, -19);
float3 Light1Color = float3(1, 1, 1);

CSE 473 Dr. Charles B. Owen
40                                       Fundamentals of 3D Game Development
Diffuse Reflection Characteristics
Since the intensity is the same in every direction, the
only other characteristic is the angle between the light
and the surface normal. The smaller this angle, the
greater the diffuse reflection:

CSE 473 Dr. Charles B. Owen
41                            Fundamentals of 3D Game Development
Diffuse reflection decreases intensity by the
Lambert’s Law   cosine of the angle between the light and
surface normal.
w                                 w

L N
L     N


w’

cos  w / w'
w  w' cos

CSE 473 Dr. Charles B. Owen
42                      Fundamentals of 3D Game Development
Computation
Let L be a normalized vector pointing at the light.
Let N be the surface normal.

L N   is the cosine of the angle between the light and the surface normal

Two cases:
L      N
L N  0      Light hits the surface


N

L  N  0 Light is behind the surface

L
CSE 473 Dr. Charles B. Owen
43                                              Fundamentals of 3D Game Development
HLSL code

// Light definition
float3 LightAmbient = float3(0.07, 0.1, 0.1);
float3 Light1Location = float3(5, 221, -19);
float3 Light1Color = float3(1, 1, 1);

struct VertexShaderInput
{
float4 Position : POSITION0;                        We need to know the normal
float3 Normal : NORMAL0;
};

struct VertexShaderOutput
{
float4 Position : POSITION0;
float4 Color : COLOR0;
};

CSE 473 Dr. Charles B. Owen
44                                              Fundamentals of 3D Game Development
Vertex Shader
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)                Light1Location
{
VertexShaderOutput output;

// We need the position and normal in world coordinates
float4 position = mul(input.Position, World);
float3 normal = normalize(mul(input.Normal, World));

// Ambient lighting hitting the location
float3 color = LightAmbient;

// Compute direction to the light
float3 Light1Direction = normalize(Light1Location - position);

// Add contribution due to this light
color += saturate(dot(Light1Direction, normal)) * Light1Color;

// Multiply by material color
color *= DiffuseColor;
position
output.Color = float4(color.x, color.y, color.z, 1);

float4 viewPosition = mul(position, View);
output.Position = mul(viewPosition, Projection);

return output;
}

CSE 473 Dr. Charles B. Owen
45                                                                    Fundamentals of 3D Game Development
What is missing?
What this looks like

CSE 473 Dr. Charles B. Owen
46                              Fundamentals of 3D Game Development
Texture Mapping
Mapping a picture onto the
surface of a triangle.

CSE 473 Dr. Charles B. Owen
47                                Fundamentals of 3D Game Development
OpenGL uses s,t instead of u,v.
The texture coordinate system
v                 u,v coordinate system

1.0

u
0,0                       1.0

CSE 473 Dr. Charles B. Owen
48                         Fundamentals of 3D Game Development
Texture coordinates
d         c

b
a

v

1.0

u
0,0           1.0
CSE 473 Dr. Charles B. Owen
49                               Fundamentals of 3D Game Development
Using Tiling
d         c

b
a

v

3.0

u
0,0           3.0
CSE 473 Dr. Charles B. Owen
50                               Fundamentals of 3D Game Development
Texture Coordinates Example
(0,6,0)                                 (4,6,0)

(x, y, z)

(0,0,0)                           (4,0,0)

CSE 473 Dr. Charles B. Owen
51                            Fundamentals of 3D Game Development
Back to HLSL – Adding a texture variable
I’ll move the multiplication by the
// The texture we use                  Diffuse Color to the pixel shader.
texture Texture;

Not everything in our scene is texture mapped. If it is texture mapped, we
use the texture color as the diffuse color. If not, we use the set diffuse color.
We have two different ways we will compute the color.

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
return input.Color * float4(DiffuseColor, 1);;
}

CSE 473 Dr. Charles B. Owen
52                                                   Fundamentals of 3D Game Development
Slightly modified version, now.
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;

// We need the position and normal in world coordinates
float4 position = mul(input.Position, World);
float3 normal = normalize(mul(input.Normal, World));

// Ambient lighting hitting the location
float3 color = LightAmbient;

// Compute direction to the light
float3 Light1Direction = normalize(Light1Location - position);

// Add contribution due to this light
color += saturate(dot(Light1Direction, normal)) * Light1Color;

// Multiply by material color
color *= DiffuseColor;                                float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
output.Color = float4(color, 1);                         return input.Color * float4(DiffuseColor, 1);
}
float4 viewPosition = mul(position, View);
output.Position = mul(viewPosition, Projection);

return output;
}

CSE 473 Dr. Charles B. Owen
53                                                                      Fundamentals of 3D Game Development
We need something called a “sampler”

sampler Sampler = sampler_state
{
Texture = <Texture>;

MinFilter = LINEAR;          This just parameterizes how we get
MagFilter = LINEAR;          pixels from our texture. Wrap
means tiling will be used. LINEAR
AddressU = Wrap;
AddressV = Wrap;             means linear interpolation. We’ll do
AddressW = Wrap;             some other options later.
};

CSE 473 Dr. Charles B. Owen
54                                     Fundamentals of 3D Game Development
And, we need to have the texture coordinates
struct VertexShaderInput
{
float4 Position : POSITION0;
float3 Normal : NORMAL0;
float2 TexCoord : TEXCOORD0;
};

struct VertexShaderOutput
{
float4 Position : POSITION0;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};

And add this to the vertex shader function:

output.TexCoord = input.TexCoord;

CSE 473 Dr. Charles B. Owen
55                                                Fundamentals of 3D Game Development
Techniques                                               Here is the technique we had before.

We have two ways things will be treated. We could create two
different effects. But, it’s often easier to create one effect with
two different “techniques”.

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
return input.Color * float4(DiffuseColor.x, DiffuseColor.y, DiffuseColor.z, 1);
}

technique NoTexture
{
pass Pass1
{
VertexShader = compile vs_1_1 VertexShaderFunction();
PixelShader = compile ps_1_1 PixelShaderFunction();
}
}

CSE 473 Dr. Charles B. Owen
56                                                       Fundamentals of 3D Game Development
Techniques                                             This is the other technique

float4 PixelShaderTexturedFunction(VertexShaderOutput input) : COLOR0
{
return input.Color * tex2D(Sampler, input.TexCoord);
}

technique Textured
{
pass Pass1
{
VertexShader = compile vs_1_1 VertexShaderFunction();
PixelShader = compile ps_1_1 PixelShaderTexturedFunction();
}
}

CSE 473 Dr. Charles B. Owen
57                                                 Fundamentals of 3D Game Development
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
return input.Color * float4(DiffuseColor.x, DiffuseColor.y, DiffuseColor.z, 1);
}

float4 PixelShaderTexturedFunction(VertexShaderOutput input) : COLOR0
{
return input.Color * tex2D(Sampler, input.TexCoord);
}

technique NoTexture
{                                                                              All in one place so
pass Pass1
{                                                                            you can see it.
VertexShader = compile vs_1_1 VertexShaderFunction();
PixelShader = compile ps_1_1 PixelShaderFunction();
}
}

technique Textured
{
pass Pass1
{
VertexShader = compile vs_1_1 VertexShaderFunction();
PixelShader = compile ps_1_1 PixelShaderTexturedFunction();
}
}

CSE 473 Dr. Charles B. Owen
58                                                               Fundamentals of 3D Game Development
Loading This Effect
private void SetLambertianTextureEffect()
{
foreach (ModelMesh mesh in Bedroom.Meshes)
{
foreach (ModelMeshPart part in mesh.MeshParts)
{
part.Effect = effectsOrig[part];

BasicEffect bEffect = part.Effect as BasicEffect;
part.Effect = lambertianTextureEffect.Clone(part.Effect.GraphicsDevice);

part.Effect.Parameters["DiffuseColor"].SetValue(bEffect.DiffuseColor);
part.Effect.Parameters["Texture"].SetValue(bEffect.Texture);

if (bEffect.Texture != null)
{
part.Effect.CurrentTechnique = part.Effect.Techniques["Textured"];
}
else
{
part.Effect.CurrentTechnique = part.Effect.Techniques["NoTexture"];
}
}
}
}
CSE 473 Dr. Charles B. Owen
59                                                              Fundamentals of 3D Game Development
What we get

CSE 473 Dr. Charles B. Owen
60            Fundamentals of 3D Game Development
The complete effect – Variables and types
float4x4 World;
float4x4 View;
float4x4 Projection;

// This is the surface diffuse color
float3 DiffuseColor = float3(0, 0, 0);

texture Texture;

// Light definition
float3 LightAmbient = float3(0.07, 0.1, 0.1);
float3 Light1Location = float3(5, 221, -19);
float3 Light1Color = float3(1, 1, 1);

struct VertexShaderInput
{
float4 Position : POSITION0;
float3 Normal : NORMAL0;
float2 TexCoord : TEXCOORD0;
};

struct VertexShaderOutput
{
float4 Position : POSITION0;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};

sampler Sampler = sampler_state
{
Texture = <Texture>;

MinFilter = LINEAR;
MagFilter = LINEAR;

AddressU = Wrap;
AddressV = Wrap;
AddressW = Wrap;
};

CSE 473 Dr. Charles B. Owen
61                                               Fundamentals of 3D Game Development
The complete effect – Vertex shader
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
output.TexCoord = input.TexCoord;

// We need the position and normal in world coordinates
float4 position = mul(input.Position, World);
float3 normal = normalize(mul(input.Normal, World));

// Ambient lighting hitting the location
float3 color = LightAmbient;

// Compute direction to the light
float3 Light1Direction = normalize(Light1Location - position);

// Add contribution due to this light
color += max(dot(Light1Direction, normal), 0) * Light1Color;

output.Color = float4(color.x, color.y, color.z, 1);

float4 viewPosition = mul(position, View);
output.Position = mul(viewPosition, Projection);

return output;
}

CSE 473 Dr. Charles B. Owen
62                                                                             Fundamentals of 3D Game Development
The complete effect = Pixel Shader and Techniques
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
return input.Color * float4(DiffuseColor.x, DiffuseColor.y, DiffuseColor.z, 1);
}

float4 PixelShaderTexturedFunction(VertexShaderOutput input) : COLOR0
{
return input.Color * tex2D(Sampler, input.TexCoord);
}

technique NoTexture
{
pass Pass1
{
VertexShader = compile vs_1_1 VertexShaderFunction();
PixelShader = compile ps_1_1 PixelShaderFunction();
}
}

technique Textured
{
pass Pass1
{
VertexShader = compile vs_1_1 VertexShaderFunction();
PixelShader = compile ps_1_1 PixelShaderTexturedFunction();
}
}

CSE 473 Dr. Charles B. Owen
63                                                                                    Fundamentals of 3D Game Development
What more is there?

Question: How would we change the color of the scene?

Question: How would we add more lights?

One more basic function:
We’ll do collision detection and deformable
 Specular illumination
characters next, then come back to some
Lots of special effects:             other fun stuff in effects.
 Shadows
 Deformable characters
 Fading
 Bump mapping (or normal mapping)

CSE 473 Dr. Charles B. Owen
64                                         Fundamentals of 3D Game Development

```
DOCUMENT INFO
Shared By:
Categories:
Stats:
 views: 9 posted: 3/10/2010 language: English pages: 64