Shader Programming on GPU (Cg: C for graphics) 2008년도 1학기 서강대학교 공과대학 컴퓨터공학과 임 인 성 교수 Professor Insung Ihm Dept. of Computer Sci. & Eng. Sogang University, Seoul, Korea 1 (c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 2008학년도 1학기
Shader Programming on GPU
(Cg: C for graphics)
2008년도 1학기
서강대학교 공과대학 컴퓨터공학과
임 인 성 교수
Professor Insung Ihm
Dept. of Computer Sci. & Eng.
Sogang University, Seoul, Korea
1(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 2008학년도 1학기
Cg (C for graphics)
• Introduction
– C-like high-level shading language for GPUs
– API- and platform-independent
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 2
Courtesy of M. Kilgard
Cg 1.4
Cg Toolkit User’s Manual: A Developer’s Guide to
Programmable Graphics (Release 1.4, September 2005)
• Cg’s Programming Model for GPU
– GPUs consist of programmable processors and other non-programmable units.
– Programmable processors
• Vertex processor
• Pixel processor
• Geometry processor (Cg 2.0)
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 3
Cg Language Profile
• Unlike CPUs, GPU programmability has not quite yet reached the same
level of generality.
• Cg uses the concept of language profile that defines a subset of the full
Cg language that is supported on a particular hardware platform of API.
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 4
- Cg 2.0
Program Inputs and Outputs
• Varying inputs versus uniform
inputs
– Varying inputs
• Used for data that is specified with
each element of the stream of input
data.
– Uniform inputs
• Used for values that are specified
separately from the main stream of
input data, and don’t change with
each stream element.
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 5
varying
uniform
vertex stream VS primitive stream GS (Cg 2.0) primitive stream Rasterization
pixel stream PS pixel stream FB
• Recall that GPU is a (massively parallel) streaming processor!
– How to specify the input and output data of each shader program
• What kind of attributes are associated with a stream element?
– Example: vertex (arbvp1)
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 6
Vertex Shader
All vertex programs must declare and set a vector output that uses the POSITION binding semantic.
– Example: pixel (arbfp1)
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 7
Pixel Shader
• Interoperability between vertex programs and fragment programs
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 8
Varying outputs from a Vertex Program
Varying inputs to Fragment Programs
COLOR0
COLOR0COLOR0
COLOR0
Rasterization
The value associated with the
POSITION binding semantic may not
be read in the fragment program (no
more true in G80).
What Cg shader codes look like?// This is C5E2v_fragmentLighting from "The Cg Tutorial“
// (Addison-Wesley, ISBN0321194969) by Randima Fernando
// and Mark J. Kilgard. See page 124.
// vertex.cg
void C5E2v_fragmentLighting(float4 position : POSITION,
float3 normal : NORMAL,
out float4 oPosition : POSITION,
out float3 objectPos : TEXCOORD0,
out float3 oNormal : TEXCOORD1,
uniform float4x4 modelViewProj) {
oPosition = mul(modelViewProj, position);
objectPos = position.xyz;
oNormal = normal;
}
// fragment.cg
void C5E3f_basicLight(float4 position : TEXCOORD0,
float3 normal : TEXCOORD1,
out float4 color : COLOR,
uniform float3 globalAmbient,
uniform float3 lightColor,
uniform float3 lightPosition,
uniform float3 eyePosition,
uniform float3 Ke,
uniform float3 Ka,
uniform float3 Kd,
uniform float3 Ks,
uniform float shininess) {
float3 P = position.xyz;
float3 N = normalize(normal);
// Compute emissive term
float3 emissive = Ke;
// Compute ambient term
float3 ambient = Ka * globalAmbient;
// Compute the diffuse term
float3 L = normalize(lightPosition - P);
float diffuseLight = max(dot(L, N), 0);
float3 diffuse = Kd * lightColor * diffuseLight;
// Compute the specular term
float3 V = normalize(eyePosition - P);
float3 H = normalize(L + V);
float specularLight = pow(max(dot(H, N), 0), shininess);
if (diffuseLight <= 0) specularLight = 0;
float3 specular = Ks * lightColor * specularLight;
color.xyz = emissive + ambient + diffuse + specular;
color.w = 1;
}
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 9
matrix type
vector type
scalar type
control flow: if/else,while, for, return
swizzle operator
Cg standard lib. Ftn.
write mask operator
A Phong Shading Example in Cg
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 10
• 이 예제 프로그램에서는
– Vertex program
• 꼭지점의 좌표를 OC에서 CC로 기하 변환을 하고 (POSITION),
• EC에서의 꼭지점 좌표와 법선 벡터를 텍스춰 좌표를 위핚 두 레지스터에 넣
어 보냄 (TEXCOORD0, TEXCOORD1).
– Fragment program
• 입력으로 래스터화 과정에서 보간을 통하여 얻어진 해당 픽셀을 통하여 보이
는 물체 지점에 대핚 EC 좌표와 법선 벡터를 받아들여,
• EC를 기준으로 주어진 광원 정보 및 물질 정보를 사용하여 퐁의 조명 모델 계
산을 수행.
• Cg Toolkit User’s Manual: A Developer’s Guide to Programmable Graphics, Release 1.4.1, NVIDIA, March 2006.
• Cg Toolkit Reference Manual: A Developer’s Guide to Programmable Graphics, Release 1.4.1, NVIDIA, March 2006.
• The Cg Tutorial: The Definitive Guide to Programmable Real-Time Graphics, R. Fernando et al., NVIDIA, 2003.
The OpenGL Part
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 11
static void CheckCgError(void) {CGerror err = cgGetError();
if (err != CG_NO_ERROR) {printf("\n%s\n", cgGetErrorString(err));printf("%s\n", cgGetLastListing(Context));exit(1);
}}
void init_Cg(void) {printf("Creating context...");Context = cgCreateContext();cgSetErrorCallback(CheckCgError);printf("Completed.\n");
printf("Compiling vertex program...");VertexProgram =
cgCreateProgramFromFile(Context, CG_SOURCE, "vp.cg", VertexProfile, NULL, NULL);
printf("Completed.\n");
printf("Compiling fragment program...");FragmentProgram =
cgCreateProgramFromFile(Context, CG_SOURCE, "fp.cg", FragmentProfile, NULL, NULL);
printf("Completed.\n");
static CGcontext Context;
static CGprogram VertexProgram, FragmentProgram;
static CGprofile VertexProfile = CG_PROFILE_VP40;
static CGprofile FragmentProfile = CG_PROFILE_FP40;
Create a Cg context that all shaders will use.
Do this after OpenGL is initialized.
Compile a Cg program by adding it to a context.
A Cg profile indicates a subset of the full Cg
language that is supported on a particular
hardware platform or API.
VertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
cgGLSetOptimalOptions(VertexProfile);
CheckCGError();
Get the best available vertex profile for the
current OpenGL rendering context.
Ask the compiler to optimize for the specific HW
underlying the OpenGL rendering context.
Coded by 김원태, updated by 손성진Profile: arbvp1, arbfp1 이상, 또는 vp40, fp40 이상
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 12
/* Get parameters */
NormalFlag = cgGetNamedParameter(FragmentProgram, "nv_flag");
cgGLSetParameter1f(NormalFlag, nv_flag);
printf(“Completed. \n”);
/* Create the vertex & fragment programs */
printf("Loading Cg program...");
cgGLLoadProgram(VertexProgram);
cgGLLoadProgram(FragmentProgram);
printf("Completed.\n");
cgGLEnableProfile(VertexProfile);
cgGLEnableProfile(FragmentProfile);
cgGLBindProgram(VertexProgram);
cgGLBindProgram(FragmentProgram);
}
static Cgparameter NormalFlag;
Retrieve a parameter of a shader directly by name.
Get a handle to the parameter in this way.
Set the value of scalar and vector parameters.
Bind the shaders to the current state.
Pass the compiled object codes by loading the shaders.
Enable the shaders before executing a program in OpenGL.
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 13
void exit_program(void) {
cgDestroyProgram(VertexProgram);
cgDestroyProgram(FragmentProgram);
cgDestroyContext(Context);
exit(1);
}
void draw_object(void) {
int i, j, loop;
MyPolygon *ptr;
glPushMatrix();
glRotatef(angle, 0.0, 1.0, 0.0);
glRotatef(xrot, 0.0, 1.0, 0.0);
glRotatef(yrot, 1.0, 0.0, 0.0);
if(draw_flag != COW) {
glTranslatef(0.0, -1.0, 0.0);
glRotatef(-90.0, 1.0, 0.0, 0.0);
}
…i = 0;
while(i++ < loop) {
glBegin(GL_POLYGON);
for (j = 0; j < ptr->nvertex; j++) {
glNormal3fv(ptr->normal[j]);
glVertex3fv(ptr->vertex[j]);
}
glEnd();
ptr++;
}
glPopMatrix();
}
Free all resources allocated
for the shaders.
Free all resources allocated
for the context.
Cg Vertex Shader
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 14
struct _output {
float4 position: POSITION;
float4 pEC: TEXCOORD0;
float3 nEC: TEXCOORD1;
};
_output main(float4 position: POSITION,
float4 normal: NORMAL,
uniform float4x4 ModelViewProj : state.matrix.mvp,
uniform float4x4 ModelView : state.matrix.modelview,
uniform float4x4 ModelViewIT : state.matrix.modelview.invtrans) {
_output OUT;
OUT.position = mul(ModelViewProj, position); // to CC
OUT.pEC = mul(ModelView, position); // position on EC
OUT.nEC = mul(ModelViewIT, normal).xyz; // normal on EC
return OUT;
}
Set by glVertex*();
Set by glNormal*();
<- * +
1
2
-3
5
3
0
2
4
1
7
2
-1
4
2
1
1
R1 R2 R3R4
MAD R4, R1, R2, R3;
A vector type with x, y, z,
and w fields
A 4x4 matrix type with 16 elements
A Cg standard library function
Binding Semantics for arbvp1 vertex program Profile
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 15
Vertex Shader
Cg Standard Library Functions
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 16
• mul(X,Y)
Cg Pixel Shader
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 17
struct _output {
float3 color: COLOR;
};
_output main(float4 position: TEXCOORD0, // position on EC
float3 normal: TEXCOORD1, // normal on EC
uniform int nv_flag,
uniform float4 global_ambient : state.lightmodel.ambient,
uniform float4 light_position : state.light[0].position,
uniform float4 light_ambient : state.light[0].ambient,
uniform float4 light_diffuse : state.light[0].diffuse,
uniform float4 light_specular : state.light[0].specular,
uniform float4 mat_ambient : state.material.ambient,
uniform float4 mat_diffuse : state.material.diffuse,
uniform float4 mat_specular : state.material.specular,
uniform float mat_shininess : state.material.shininess) {
_output OUT;
if (nv_flag == 1) { OUT.color = normal; }
else {
OUT.color = global_ambient * mat_ambient;
float3 N = normalize(normal);
float3 L = normalize(light_position – position);
float NdotL = dot(N, L);
void set_material (void) {glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);
}
void set_light (void) {glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient_color);glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diff_spec_color);glLightfv(GL_LIGHT0, GL_SPECULAR, light_diff_spec_color);glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
}
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 18
if(NdotL >= 0.0) {
OUT.color += mat_ambient * light_ambient;
float3 V = normalize(-position);
float3 H = normalize(L + V);
float NdotH = dot(N, H);
float4 lighting = lit(NdotL, NdotH, mat_shininess);
float3 diffuse = mat_diffuse * lighting.y;
float3 specular = mat_specular * lighting.z;
OUT.color += (light_diffuse * diffuse) + (light_specular*specular);
}
}
return OUT;
}
Binding Semantics for arbfp1 fragment program Profile
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 19
Pixel Shader
Cg Standard Library Functions
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 20
• dot(a,b)
• normalize(v)
• lit(ndot1, ndoth, m)
A Simple Texture Mapping Example in Cg
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 21
struct _output {
float4 position: POSITION;
float2 texcoord: TEXCOORD0;
float4 pEC: TEXCOORD1;
float3 nEC: TEXCOORD2;
};
_output main(float4 position: POSITION,
float4 normal: NORMAL,
float2 texcoord: TEXCOORD0,
uniform float4x4 ModelViewProj : state.matrix.mvp,
uniform float4x4 ModelView : state.matrix.modelview,
uniform float4x4 ModelViewIT : state.matrix.modelview.invtrans){
_output OUT;
OUT.position = mul(ModelViewProj, position); // to CC
OUT.pEC = mul(ModelView, position); // position on EC
OUT.nEC = mul(ModelViewIT, normal).xyz; // normal on EC
OUT.texcoord = texcoord;
return OUT;
}
Vertex Shader
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 22
struct _output {
float3 color: COLOR;
};
_output main(float2 texcoord: TEXCOORD0,
float4 position: TEXCOORD1, // position on EC
float3 normal: TEXCOORD2, // normal on EC
uniform sampler2D decal,
uniform int tex_flag,
uniform float4 global_ambient : state.lightmodel.ambient,
uniform float4 light_position: state.light[0].position,
uniform float4 light_ambient : state.light[0].ambient,
uniform float4 light_diffuse : state.light[0].diffuse,
uniform float4 light_specular: state.light[0].specular,
uniform float4 mat_ambient : state.material.ambient,
uniform float4 mat_diffuse : state.material.diffuse,
uniform float4 mat_specular : state.material.specular,
uniform float mat_shininess : state.material.shininess) {
_output OUT;
OUT.color = global_ambient * mat_ambient;
float3 N = normalize(normal);
float3 L = normalize(light_position –
position);
float NdotL = dot(N, L);
Pixel Shader
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 23
if(NdotL >= 0.0) {
OUT.color += mat_ambient *
light_ambient;
float3 V = normalize(-position);
float3 H = normalize(L + V);
float NdotH = dot(N, H);
float4 lighting = lit(NdotL, NdotH,
mat_shininess);
float3 diffuse = mat_diffuse *
lighting.y;
float3 specular = mat_specular *
lighting.z;
OUT.color += light_diff * diffuse;
if (tex_flag == 1) {
float3 decalcolor = tex2D(decal,
texcoord);
OUT.color *= decalcolor;
// 'GL_MODULATE' part
}
OUT.color += light_specular *
specular;
}
return OUT;
}
- 나머지 OpenGL 부분은 해당 프로그램 참조
// During init_OpenGL
void set_textures(void) {
read_texture();
glGenTextures(1, &tex_name);
glBindTexture(GL_TEXTURE_2D, tex_name);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV,
GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
tex_br.ns, tex_br.nt, 0, GL_RGB,
GL_UNSIGNED_BYTE, tex_br.tmap);
}
OpenGL
Normal Map and Normal-Map Space
• Generating normal from height fields
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 24
zij = z(i, j)
x
y
x
y
x
yz
Bump Mapping a Torus
• Parametric surfaces
• Torus
• Tangent, binormal, and normal vectors
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 25
y
z
M N
s
z
N
T
B
x
y
t
1
1
(s,t)S(s,t)
Shading Normal-Map Space
• Transformation from object space to normal-map space
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 26
yo
xo
zo
yn
xn
zn
VnVo
z
N
T
B
x
y
S(s,t)
xo
yo
zo
yo
xo
zo
ynxn
zn
Vn Vo
A Bump Mapping Example
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 27
범프 매핑 기법 적용 전과 후
일반 이미지 맵과 범프 맵
왜 범프 맵의 색상이 푸른 색일까?
Vertex Shader
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 28
struct _output {
float4 oposition: POSITION;
float2 oTexCoord: TEXCOORD0;
float3 lightDirection: TEXCOORD1;
float3 eye_direction: TEXCOORD2;
};
_output main(float2 parametric: POSITION,
//torus param
uniform float3 lightPosition,
// Object-space
uniform float3 eyePosition,
// Object-space
uniform float4x4 modelViewProj,
uniform float2 torusInfo,
uniform float decalflag) {
_output OUT;
const float pi2 = 6.28318530; // 2 * Pi
// Stetch texture coordinates CCW
// over torus to repeat normal map in 6
by 2 pattern
float M = torusInfo[1];//1.5
float N = torusInfo[0];//1.0
OUT.oTexCoord = parametric *
float2(6, 2);//texture coordinate
if(decalflag == 0) {
if(OUT.oTexCoord.y > -1.0) {
OUT.oTexCoord.y = -OUT.oTexCoord.y;
}
}
// Compute torus position from its
parameteric equation
float cosS, sinS;
sincos(pi2 * parametric.x, sinS, cosS);
float cosT, sinT;
parametric.y = -parametric.y;
sincos(pi2 * parametric.y, sinT, cosT);
//Make torus position with torus
info.(meridian_slices,core_slices)
//x=(M+Ncos(2*pi*t))cos(2*pi*s)
//y=(M+Ncos(2*pi*t))sin(2*pi*s)
//z=Nsin(2*pi*t)
float3 torusPosition = float3((M+N*cosT)
*cosS, (M+N*cosT)*sinS, N*sinT);
OUT.oposition = mul(modelViewProj,
float4(torusPosition, 1));
//CC position of vertex
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 29
// Compute per-vertex rotation matrix
float3 dPds = float3(-sinS*(M+N*cosT),
cosS*(M+N*cosT), 0);
float3 norm_dPds = normalize(dPds);
//T vector
float3 normal = float3(cosS*cosT,
sinS*cosT, sinT);//N vector
float3 dPdt = cross(normal, norm_dPds);
//B vector
if(decalflag == 0)
if(OUT.oTexCoord.y > -1.0) dPdt = -dPdt;
float3x3 rotation =
float3x3(norm_dPds, dPdt,normal);
// Rotate obj.-space vectors to tex-space
float3 eyeDirection = eyePosition
– torusPosition;
float3 tmp_lightDirection = lightPosition
- torusPosition;
OUT.lightDirection = mul(rotation,
tmp_lightDirection);
eyeDirection = mul(rotation,
eyeDirection);
OUT.eye_direction=eyeDirection;
return OUT;
}
Pixel Shader
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 30
struct _output {
float3 color: COLOR;
};
float3 expand(float3 v) {
return (v-0.5)*2;
}
_output main(
float2 normalMapTexCoord: TEXCOORD0,
float3 lightDirection: TEXCOORD1,
float3 eyedirection: TEXCOORD2,
uniform float3 ambient,
uniform sampler2D decalMap,
uniform sampler2D normalMap) {
_output OUT;
float3 decalColor;
float3 V = eyedirection;
float3 L = lightDirection;
L = normalize(L.xyz);
V = normalize(V.xyz);
float3 normalTex = tex2D(normalMap,
normalMapTexCoord).xyz;
// Fetch and expand range-compressed normal
float3 normal = expand(normalTex);
//(0,1) ==> (-1,1)
normal.xyz = normalize(normal.xyz);
decalColor = tex2D(decalMap,
normalMapTexCoord.xy);
float3 temp_1 = dot(normal,L); //N dot L
float3 temp_2 = dot(normal,V); //N dot V
OUT.color = ambient + decalColor * temp_1
+ pow(temp_2,25);
return OUT;
}
From Pixar RenderMan Shader to Cg Shader
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 31
windowhighlight()
이 렌더맨 쉐이더를 Cg 쉐이더로 변환해보자.
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 32
/* Copyrighted Pixar 1989 */
/* From the RenderMan Companion p.357 */
/* Listing 16.20 Surface shader providing a paned-window highlight*/
/*
* windowhighlight(): Give a surface a window-shaped specular highlight.
*/
surface
windowhighlight(
point center = point "world" (0, 0, -4), /* center of the window */
in = point "world" (0, 0, 1), /* normal to the wall */
up = point "world" (0, 1, 0); /* 'up' on the wall */
color specularcolor = 1;
float Ka = .3, Kd = .5, xorder = 2, /* number of panes horizontally */ yorder = 3, /* number of panes vertically */
panewidth = 6, /* horizontal size of a pane */ paneheight = 6, /* vertical size of a pane */
framewidth = 1, /* sash width between panes */
fuzz = .2;) /* transition region between pane and sash */
{
uniform
point in2, /* normalized in */
right, /* unit vector perpendicular to in2 and up2 */
up2, /* normalized up perpendicular to in */
corner; /* location of lower left corner of window */
point path, /* incident vector I reflected about normal N */
PtoC, /* vector from surface point to window corner */
PtoF; /* vector from surface point to wall along path */
float offset, modulus, yfract, xfract;
point Nf = faceforward( normalize(N), I );
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 33
/* Set up uniform variables as described above */
in2 = normalize(in); right = up ^ in2; up2 = normalize(in2^right); right = up2 ^ in2;
corner = center - right*xorder*panewidth/2 - up2*yorder*paneheight/2;
path = reflect(I, normalize(Nf)); /* trace source of highlight */
PtoC = corner - Ps;
if (path.PtoC <= 0) {/* outside the room */ xfract = yfract = 0; }
else {
/*
* Make PtoF be a vector from the surface point to the wall by adjusting the length of the reflected vector path.
*/
PtoF = path * (PtoC.in2)/(path.in2);
/*
* Calculate the vector from the corner to the intersection point, and
* project it onto up2. This length is the vertical offset of the
* intersection point within the window.
*/
offset = (PtoF - PtoC).up2;
modulus = mod(offset, paneheight);
if( offset > 0 && offset/paneheight < yorder ) { /* inside the window */
if( modulus > (paneheight/2))/* symmetry about pane center */
modulus = paneheight - modulus;
yfract = smoothstep(/* fuzz at the edge of a pane */
(framewidth/2) - (fuzz/2), (framewidth/2) + (fuzz/2), modulus);
}
else {
yfract = 0;
}
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 34
/* Repeat the process for horizontal offset */
offset = (PtoF - PtoC).right;
modulus = mod(offset, panewidth);
if( offset > 0 && offset/panewidth < xorder ) {
if( modulus > (panewidth/2))
modulus = panewidth - modulus;
xfract = smoothstep( (framewidth/2) - (fuzz/2), (framewidth/2) + (fuzz/2), modulus);
}
else {
xfract = 0;
}
}
/* specular calculation using the highlight */
Ci = Cs * (Kd*diffuse(Nf) + Ka*ambient()) + yfract*xfract*specularcolor ;
}
Cg 2.0
– Example: vertex (gp4vp)
• Vertex Attribute Input Semantics
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 35
Cg-2.0_Jan2008_ReferenceManual.pdf
• Output Semantics
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 36
– Example: geometry (gp4gp)
• Primitive Instance Input Semantic
• Vertex Instance Input Semantic
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 37
• Vertex Attribute Input Semantics
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 38
• Output Semantics
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 39
– Example: pixel (gp4fp)
• Interpolated Input Semantic
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 40
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 41
• Interpolation Semantic Modifiers
• Per-primitive Input Semantics
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 42
• Output Semantics
2008학년도 1학기(c)2008 서강대학교 컴퓨터공학과 임인성 (Insung Ihm) 43