GPU编程:《The Cg Tutorial》学习之动画:搏动效果
为了实现动画效果,应用程序必须随着时间而发生一些变化。典型的做法是设置一个全局变量,记录时间的变化。
我们可以在CPU中计算动画更新数据,然后传给GPU。但是,更有下效率的做法是将尽可能多的动画计算在GPU中用顶点程序来完成。这样平衡了CPU和GPU的资源,使CPU能够处理诸如碰撞检测、人工智能等更复杂的计算。
我们下面要绘制一个物体:实心球体,它的表面将会不停的凸出和凹进,即搏动效果。我们要做的是随时间改变顶点的位置,它朝着法向量方向发生变化。
我们采用了光照,这样能更好的看清效果。
代码示例:
顶点Cg程序:
[cpp] float3 computeLighting(float3 lightPosition,
float3 lightColor,
float3 eyePosition,
float3 globalAmbient,
float3 Kd,
float3 Ks,
float shininess,
float3 P,
float3 N)
{
//compute diffuse lighting
float3 L = normalize(lightPosition - P);
float diffuseLight = max(dot(N,L),0);
float3 diffuseResult = Kd * diffuseLight * lightColor;
//compute specular lighting
float3 V = normalize(eyePosition - P);
float3 H = normalize(L + V);
float3 specularLight = lightColor * pow(max(dot(N,H),0),shininess);
if(diffuseLight < 0)
specularLight = 0;
float3 specularResult = Ks * specularLight;
return globalAmbient + diffuseResult + specularResult;
}
void main_v(float4 position : POSITION,
float3 normal : NORMAL,
out float4 oPosition : POSITION,
out float4 color : COLOR,
uniform float4x4 modelViewProj,
uniform float time,
uniform float frequency,
uniform float scaleFactor,
uniform float3 globalAmbient,
uniform float3 Kd,
uniform float3 Ks,
uniform float shininess,
uniform float3 eyePosition,
uniform float3 lightPosition,
uniform float3 lightColor
)
{
//bulge magnitude
float displacement = scaleFactor * 0.5 *
sin(position.y * frequency * time) + 1;
//bulge direction
float4 displacementDirection = float4(normal.x,normal.y,normal.z,0);
//new position in object-space
float4 newPosition = position + displacementDirection * displacement;
//new position in clip-space
// Get OpenGL state matrices
modelViewProj = glstate.matrix.mvp;
oPosition = mul(modelViewProj,newPosition);
color.xyz = computeLighting(lightPosition,lightColor,eyePosition,
globalAmbient,Kd,Ks,shininess,newPosition.xyz,normal);
color.w = 1;
}
float3 computeLighting(float3 lightPosition,
float3 lightColor,
float3 eyePosition,
float3 globalAmbient,
float3 Kd,
float3 Ks,
&
补充:软件开发 , 其他 ,