Shader Language (Cg, © nVIDIA)

Transcription

Shader Language (Cg, © nVIDIA)
Shader Language (Cg, © nVIDIA)
2
Graphics Pipeline
Geometry
Picture
Graphics Pipeline
Geometry
Transform
Light
Clip
Setup
Blend
Rasterize
Texture
Z-test
Framebuffer
Picture
Graphics Pipeline
Vertex
Connectivity
Vertex
Shader
Primitive
Assembly
Textures
Texture
Clip &
Setup
Blend
Rasterize
Fragment
Shader
Raster OPs
Framebuffer
Picture
Graphics Pipeline
Vertex
Connectivity
Vertex
Shader
Primitive
Assembly
Textures
Texture
Clip &
Setup
Blend
Rasterize
Fragment
Shader
Raster OPs
Framebuffer
Picture
Bottlenecks

Too many operations


Parallelize
Too many memory accesses

Parallelize
SCREEN
TILE
XBAR
GEOMETRY
OPERATIONS
FRAGMENT
OPERATIONS
SCREEN
TILE
SCREEN
TILE
Parallelization

Distribute computation to processors



Work allocation
Distribute texture to memory banks
Tile Screen-pixels into memory banks


Do all processors have access to all memory
Distribute access/Replicate data
Graphics Pipeline III
Vertex
Textures
Connectivity
Vertex
Shader
Rasterize
Primitive
Assembly
Geometry
Shader
Fragment
Shader
Clip &
Setup
Texture
Blend
Raster OPs
Framebuffer
Picture
Declaring Programs in Cg

Cg program entry function can have
any name:
<return-type> <program-name>
(<parameters>) [:<semantic-name>]{
/* ... */
}
Program Inputs and Outputs

GPUs operate on streams of data:
A stream of vertices
A stream of primitives
A stream of fragments

A Cg-program is executed repeatedly
on a GPU: once for each element of
data.
Program Inputs and Outputs

Two kinds of program inputs:
Varying inputs: specified with each
element of the stream.
 Eg.: color, normal per vertex or interpolated
texture coordinates for fragments
Uniform inputs: specified seperately from
the stream
 Changes at lower frequency
 Eg.: transformation matrix for a vertex
program.
Varying Inputs

Binding semantics

Associates a meaning with the parameter
POSITION
NORMAL
BINORMAL
BLENDINDICES

BLENDWEIGHT
TANGENT
PSIZE
TEXCOORD0-TEXCOORD7
Binding semantics may implicitly
specify the mapping of inputs to
particular hardware registers, or tie
output of one program to the input of
the next
struct myinputs{
float3 myPosition
:
float3 myNormal
:
float3 myTangent
:
float refractiveIndex :
};
POSITION;
NORMAL;
TANGENT;
TEXCOORD3;
outdata foo(myinputs inData,
float otherInData: TEXCOORD4)
{
// In program scope, the parameters are
// referred to as 'inData.myPosition',
//'inData.myNormal', and so on.
}
Varying Outputs from VS



Outputs of a program are available to
a subsequent program as varying
inputs.
Program must agree on the data being
passed between them.
→ Binding semantics
Output binding semantics:
POSITION
COLOR0-COLOR1
PSIZE
FOG
TEXCOORD0-TEXCOORD7
// Vertex Program
struct myvf {
float4 pout
:
float4 diffusecolor
float4 uv0
:
float4 uv1
:
};
myvf foo(/*...*/){
myvf outstuff;
/* .. */
return outstuff;
}
POSITION;
: COLOR0;
TEXCOORD0;
TEXCOORD1;
// Fragment Program
struct myvf {
float4 diffusecolor : COLOR0;
float4 uv0
: TEXCOORD0;
float4 uv1
: TEXCOORD1;
};
fragout bar(myvf indata){
float4 x = indata.uv0;
/* .. */
}
Varying Outputs from PS



Required to output a vector with COLOR
semantics
Some profiles support a DEPTH output
As structure, as out parameters, or directly
void main(out float4 color : COLOR,
out float depth : DEPTH){
/*...*/
color = diffusecolor;
depth = /*...*/;
}
float4 main() : COLOR {
/* ... */
return diffusecolor;
}
Data Types

Basic Data types:
float, half, int, fixed, bool, sampler*

Built-in vector data types:

Support for matrices (up to 4x4) :
float4
bool4
float3 float2 float1
bool3
bool2
bool1
float1x1 matrix1;
float4x2 matrix3;
float2x3 matrix2;
float4x4 matrix4;
Data Types



Type conversions C-like
Structs
Arrays (no pointer syntax):
float4x4 mymatrix[5];
Note: float M[4][4] != float4x4 M
Statements and Operators

Control Flow:
Function calls and the return statement
if/else
while
for

Function definitions and overloading:
function
function
function
function
blah1(out float x); // x is output-only
blah2(inout float x); // input/output
blah3(in float x);
// input only
blah4(float x);
// input only
// (default)
bool same(float a, float b);
bool same(bool a, bool b);
Statements and Operators

Arithmetic Operators:
+, -, *, /
Can be used on vectors as well as on
scalars
Eg.: a * float3(A, B, C) * float3(D, E,
F) equals float3(a*A*D, a*B*E, a*C*F)

Matrix operands are not supported.
Use the mul() functions:
matrix-column vector: mul(M, v);
row vector-matrix: mul(v, M);
matrix-matrix: mul(M, N);
Statements and Operators


Boolean and comparison operators
Swizzle Operator (.)
Allows the components (x,y,z,w or r,g,b,a)
of a vector to be rearranged
Elements can be repeated or omitted.
float3(a,b,c).zyx
float4(a,b,c,d).xxyy
float2(a,b).yyxx
float4(a,b,c,d).w
yields
float3(c,b,a)
yields float4(a,a,b,b)
yields float4(b,b,a,a)
yields
d
Statements and Operators

Texture lookup functions require at
least 2 parameters:
Texture sampler:
 Type: sampler, sampler1D, sampler2D,
sampler3D, samplerCUBE, samplerRECT.
 Combination of a texture image with a filter,
clamp, wrap or similar configuration.
 Provided by the application as uniform
parameters.
Texture coordinate:
 A scaler, 2/3/4-vector, depending on the
texture lookup.
Statements and Operators

Example:
void applytex( uniform sampler2D
mytexture,
float2 uv
:
TEXCOORD0,
out float4 outcolor :
COLOR) {
outcolor = tex2D(mytexture, uv);
}

Wide variety of texture-lookup
functions:
tex2D, texRECT, texCUBE, tex2Dproj,
texRECTproj, texCUBEproj, ...
Setting up Cg



Cg toolkit:
http://developer.nvidia.com/object/
cg_toolkit.html
Link your program with the libraries:
Cg and CgGL
Include the core Cg runtime API:
#include <Cg/cg.h>
#include <Cg/cgGL.h>

Initialize Cg (after initializing OpenGL)
Initializing Cg

First, create a context:
CGcontext context = cgCreateContext();

Add the shader to the context:
CGprofile myProfile = cgGLGetLatestProfile
(CG_GL_VERTEX);
CGprogram myProgram = cgCreateProgram(
context, CG_SOURCE, "myProgram.cg",
myProfile, "main", args);

Pass the resulting object code to 3D API:
cgGLLoadProgram(myProgram);
Program Parameters

Get a handle to the parameter:
Cgparameter myParameter =
cgGetNamedParameter(myProgram,
"myParameter")

Set the parameter value:
cgGLSetParameter4fv(myParameter,
value);
Executing a Program

Enable a program's corresponding
profile:
cgGLEnableProfile(myProfile);

Bind a program:
cgGLBindProgram(myProgram);
Only one vertex and one fragment
program can be bound at a time for a
particular profile.
Releasing Resources

Free resources allocated for a
program:
cgDestroyProgram(myProgram);

Free resources allocated for a context:
cgDestroyContext(context);
GLSL
sampler InputImage;
float4 main(float2 topLeft : TEXCOORD0, float2 left :
TEXCOORD1,
float2 bottomLeft : TEXCOORD2, float2 top :
TEXCOORD3,
float2 bottom : TEXCOORD4, float2 topRight :
TEXCOORD5,
float2 right : TEXCOORD6, float2 bottomRight :
TEXCOORD7): COLOR
{
// Take all eight taps
float4 tl = tex2D (InputImage, topLeft);
float4 l = tex2D (InputImage, left);
float4 bl = tex2D (InputImage, bottomLeft);
float4 t = tex2D (InputImage, top);
float4 b = tex2D (InputImage, bottom);
float4 tr = tex2D (InputImage, topRight);
float4 r = tex2D (InputImage, right);
GLSL
// Compute dx using Sobel operator:
// -1 0 1
// -2 0 2
// -1 0 1
float dX = -tl.a - 2.0f*l.a - bl.a + tr.a + 2.0f*r.a
+ br.a;
// Compute dy using Sobel operator:
// -1 -2 -1
// 0 0 0
// 1 2 1
float dY = -tl.a - 2.0f*t.a - tr.a + bl.a + 2.0f*b.a
+ br.a;
// Compute cross-product and renormalize
float4 N = float4(normalize(float3(-dX, -dY, 1)),
tl.a);
// Convert signed values from -1..1 to 0..1 range
and return
return N * 0.5f + 0.5f;
}
HLSL
void main( in a2v IN, out v2p OUT ) {
// input parameters include view project matrix ModelViewProj,
// view inverse transpose matrix ModelViewIT,
// and light vector LightVec.
OUT.Position = mul(IN.Position, ModelViewProj);
// multiply position with view project matrix
float4 normal = mul(IN.Normal, ModelViewIT);
normal.w = 0.0;
normal = normalize(normal);
float4 light = normalize(LightVec);
float4 eye = float4(1.0, 1.0, 1.0, 0.0);
float4 vhalf = normalize(light + eye);
// transform normal from model-space to view-space, store normalized
// light vector, and calculate half angle vector. float4(1.0, 1.0, 1.0, 0.0)
// is a vector constructor to initialize vector float4 eye. .xyzz, a swizzle
// operator, sets the last component w as the z value.
HLSL
float diffuse = dot(normal, light);
float specular = dot(normal, vhalf);
specular = pow(specular, 32);
// calculate diffuse and specular components with dot
// product and pow function.
float4 diffuseMaterial = float4(0.5, 0.5, 1.0, 1.0);
float4 specularMaterial = float4(0.5, 0.5, 1.0, 1.0);
// set diffuse and specular material.
OUT.Color = diffuse * diffuseMaterial + specular * specularMaterial;
}
struct a2v { float4 Position : POSITION; float4 Normal : NORMAL; };
// Normal item is added for color computing.
struct v2p { float4 Position : POSITION; float4 Color : COLOR0; };