UDK Notes - Materials And Shaders
How Materials Work As Shaders In UDK
The UDK material editor, is essentially a visual system for writing shader programming.
All the work you do, becomes shader code. This is CGFX, GLSL, or HLSL shader code
(depending on platform)
You can also write code yourself. (Discussed later in the custom code section.)
This code in turn gets compiled to lower level code, and eventually machine code.
Shaders are really a way of programming the GPU of your video card. The GPU is the part of the machine that does all the real time rendering calculations. Thus, shaders allow the video card in a computer to handle many complex tasks, and video cards are super fast, this works out great.
Material Editor User Interface
Click on nodes to select them, hold ctrl and LMB drag to move them.
Ctrl+Alt+LMB drag will draw selection marquee window
Selected nodes show up as yellow
Up at the top you can click sphere, cube, and cylinder buttons to see different previews
Click a node to select it and it's properties show in the bottom left window
Change options for each node there
Selecting no nodes shows material properties
You can plug nodes together by dragging between them
Alt+LMB click to disconnect attributes
RMB on blank space, new comment
name the section
If you select a comment, and then Ctrl+LMB drag, all nodes inside the comment box will be moved
(selecting a comment selects the nodes inside it too)
The Material Node And Its Inputs
The material node is the end result of your shader. You connect all your maps into it. You can also select it and change certain properties for it in the property editor at the bottom of the material editor window.Here is a description of the most important material inputs:
Diffise is similar to color in Maya
Normal is similar to bump in Maya
Emissive is similar to incandecense in Maya
Specular is similar to specular color in maya
Specular power is similar to ecentricity on a blinn in maya
Overview of Essential Nodes
This is just a short list, for more detailed information, a great listing of all the available nodes in the materials editor, and what they do, is available in the official UDK documentation.http://udn.epicgames.com/Three/MaterialsCompendium.html
Constant
A constant is just a number
To create
Hold 1 on keyboard, and click in black space
RMB > Constants > New Constant
Find in list on top right and drag it into graph
A constant can also be used for a greyscale color
White is 1 (photoshop white, 255)
Black is 0 (photoshop black, 0)
50% Grey is 0.5 (may not appear like 127 in photoshop)
color profiles and human perception affect these things
Anything above 1 as potentially glowing, so bright a halo of light forms around
the default in UDK is to bloom (glow) bright pixels
Constant3Vector
A Constant3Vector is just 3 numbers side by side, (a group of 3 numbers)
usually a color
can also store a position, a rotation, or something else
double click to edit the color value
To create:
Hold 3 on keyboard, and click in black space
RMB > Constants > New Constant3Vector
Find in list on top right and drag it into graph
Using constant3Vectors for material properties is like just changing colors in Maya
Multiply
Multiplies one input by the other input
For color/textures works like photoshops "multiply" layer blending
You can use multiply to tint, brighten, or darken
Most common math node
To create:
Hold M on keyboard, and click in black space
RMB > Math > Multiply
Find in list on top right and drag it into graph
Make normal maps stronger weaker
multiply a normal map by a constant3
r=1,g=1,b=1
turn blue up (5) for a weaker normal map
turn blue down (0.2) for a stronger normal map
Material Instances
Material instances are easy ways to duplicate/instance existing materials
and adjust them (in real time).
To create a material instance:
RMB click on material in the content browser
Create New Material Instance (Constant)
Applied to objects just like any material
Using Math To Control Your Material And Make Adjustments To Its Look
Colors are just numbers, often the numbers are called x,y,z or red green and blue, but really, for the computer, they are just numbers.
Numbers can be adjusted easily using mathematical operations.
Thus, math operations can be very useful for changing the look of a material.
Understanding how the colors are calculated, and what math is used to do so, can be very useful. It is also very useful to have a good understanding of what impact various types of mathematical operations will have on the look of your shader.
The general math for a basic shader looks like this:
(diffuseColor * lighting) +
(specularLevel * specularColor * lighting) +
(ambientColor + glowColor + reflectionColor)
Any numerical or color based property can be controlled by a texture instead.
Some so general rules for shaders:
different light sources add (two different lights add)
different lighting components add (diffuse and spec add)
tinting, changing the color: multiply by color
level (brightness): multiply by a number
A Note On How Specular Color Is Really Faked In Real Time Rendering
In real life there is not an exact distintion between diffuse and specular lighting.Light that is more scattered is more diffuse, and less scattered light is considered more specular (shiny).
In real life, light from most surfaces is just reflections. Even the regular diffuse color is just very very scattered reflections.
However, because scattering is very complicated to simulate, in rendering we normally use an approximation for scattered "diffuse" light based on the surface normal and light direction/position/etc.
A similar approximation is used for the unscattered "specular" reflections of lights. It is based on the camera position, the surface normal, and the light direction/position/etc.
Often as arttists we have to
Other things to note:
In real life, non metals usually have white spec
we cheat as artists, and tint
metals usually are tinted
In real life, all specular is blurry reflections
UDK Working Strategy
Label things yourself with commentsinput can be a texture or something else
For tint, combine input, color and muliply
for color use Constant3 or VectorParameter
For level, combine input, number, and multiply
for number use Constant
For bump strength, combine input, color and multiply
but, for color, start with white, then only adjust blue
for more bumpiness make blue lower, eg. 0.3
fore less bumpiness make blue higher, eg 3
you can add normal maps together, after the multiply
For detail maps, use a TextureCoordinate
change the tiling
plug it into the uvs of the texture
Specular power is important
this is typically called gloss "a gloss map"
this is like eccentricity
map it, greyscale works or you might want to
pack the channels with other masks
use an "Power" node and an number to tweak exponent
often, the brighter the spec level, the smaller the highlight
Emmisive
You can use this for ambient color, glows, and for
special effects like rim lighting
Reflection should add to the emmisive as well
Emmisive color is "self illumination"
It will show up even when the lighting is total darkness
If you want a rim light effect
a Fresnel works well.
Plug the fresnel into a power node base
And plug a number into the exponent, then tweak the number
Reflections:
Use TextureSampleParameterCube
hook up your texture using the green
Change the material property, turn on "per pixel camera vector"
Real Time Cubemap Reflections:
Add a new TextureRenderTargetCube to your package
use the texture in the material the same way
as for a regular non-realtime reflection
Create an actor in the scene
Uncatagorized > SceneCaptureCubeMap
Open the properties of that actor
hook up the cubemap texture to the
Capture > Texture Target
change the far clip plane and the near clip
Texture Blending
To blend colors (or any values really) use "linear interpolate". Linear interpolate is "blend colors". The "alpha" input is the blend amount.
Simple Blending
The simplest texture blending looks like this:
Linear Interpolate
A - Texture Sample (color texture)
B - Texture Sample (color texture)
Alpha - Texture Sample (greyscale map used for
blending)
Vertex Based Blending
Linear Interpolate
A - Texture Sample (color texture)
B - Texture Sample (color texture)
Alpha - Vertex Color R
Speckled Blending By Vertex Colors
For a speckled blending (often called "height field based"
blending) plug this chain into the alpha of a linear interpolate:
Constant Clamp
In - Divide
A - Subtract
A -
Vertex Color R
B - Speckle texture (like a heightmap style greyscale)
B - Constant (or Vertex
color green for sharpness control)
The UDK particle system is called "cascade".
Create a particle system by right clicking in the content
browser and choosing
"new particle system". Double click to edit it.
You need to have your own material on it. You can click on
the "required" block in cascade, and in the properties section,
open the emitter section, to find the material properties.
Apply your own material here by pushing the green arrow after
selecting the material to use in the content browser. I
recommend a translucent material with a texture for the opacity.
To make your material translucent, click on the material
block in the material graph. In the properties section of the
window (lower left) you will see several headings. In the
"Materials Heading" > Find "Blend Mode" > use
"BLEND_Translucent"
Plug a texture into the materials "Opacity" input to control
the transparency. (Opacity is the opposite of
transparency.)
Transparency and Distorion in UDK
Transparency and distorion can be used for surfaces like:
Water
Glass
Ice
These things are cheated/faked quite a bit in game engines.
Most games engines don't do raytracing, so you can't get
accurate refractions.
We can simulate refractions with "distorion".
Distortion is a cheap effect that gives results that are visually similar to refraction.
Distortion simply moves the pixels in 2D underneath the transparent object.
We can also use refraction environment maps instead of distortion.
These are similar to reflection environment maps.
In real life, things like water have no real "color".
Meaning, no diffuse color.
Combination of:
-Reflections
-Refractions
Blended via some kind of function based on the viewer, and the surface normal. (Frenel and IOR affects this.)
Looking head on shows more refractions
Looking at a glancing angle show more reflections
To make a transparent material:
Start by making it BLEND_Tranlucent
Use a frenel for the opacity
Adjust the Frenels "exponent" to control the hardness of the edge
Use multiplies, adds, and constants to adjust the opacity
Plug a constant 2 into the distortion
Material
Diffuse
Constant3 - Green
Opacity
Add
Constant - 0.09
Multiply
Constant - 0.4
Frenel - Exp of 5
To bend in the proper direction:
Make a Camera Vector node
Make a Transform node (will say vector transform in graph)
Change the vector transforms Destination property to "View"
A Glass Material That Accounts For Normal Direction
Material
Diffuse
Constant3 - Green
Opacity
Add
Constant - 0.09
Multiply
Constant - 0.4
Frenel - Exp of 5
Distortion
Multiply
Multiply
Frenel - Exp of 1.3
Constant2 - 3, 7
Mask - R,G
Transform - Source Tangent Destination World
Camera Vector
Note that for a Fresnel node to take the normals into account, you need to plug the normal map into the input of the Fresnel node.
Unsorted Notes About UDK Materials and Shaders
Custom Shader Nodes:
You can provide your own name, such as: Tint And Level
You can then provide your own inputs.
Open the inputs section
Push the "+" button to add inputs.
Then name them. The exact name will be used in code, so:
name them starting lower case, no funny characters
useCamelCaseLikeThis
Push the button to edit the code:
add some programming on what should be returned, such as:
return inTexture*tint;
===========
Some example code for a relief mapping shader in UDK, through the use of a custom node:
float3 p;
float3 v;
float3 viewDirFix;
viewDir = normalize(viewDir);
p = float3( uv, 0 );
v = normalize( viewDir * -1 );
v.z = abs(v.z);
//depth bias
float depthBias = 1.0 - v.z;
depthBias *= depthBias;
depthBias *= depthBias;
depthBias= 1.0 - depthBias * depthBias;
v.xy *= depthBias;
v.xy*= strength;
const int linearSearchSteps = 20;
const int binarySearchSteps = 10;
v /= v.z * linearSearchSteps;
int i;
for( i=0;i<linearSearchSteps;i++ )
{
float tex = tex2D( heightMap, p.xy).a;
if ( p.z<tex) p+=v;
}
for( i=0;i<binarySearchSteps;i++ )
{
v *= 0.5;
float tex = tex2D( heightMap, p.xy).a;
if (p.z < tex) p += v;
else p -= v;
}
return p.xy;
===========
Ask about:
specular shape texture later
noise affecting UVs later
material instances to recycle generic materials with new maps/colors
materials with 2D realtime reflection
Uses For Emmisive Color:
Glow (self-illumination)
Reflections
Refractions (not usually)
For skies and background elements that aren't lit