【译】【Shader库】在多个光源下的Phong Shader(GLSL)

发表于2016-03-28
评论1 1.2k浏览

想免费获取内部独家PPT资料库?观看行业大牛直播?点击加入腾讯游戏学院游戏程序行业精英群

711501594


译者注:
  PhongShader是三维电脑图形的绘图技巧之一,它的光照模型分为三个阶段:漫反射-镜面反射和环境光。更多可用的Shader(译为着色器,专业术语后面不翻译)在这里:Geeks 3D Shaderlibrary.
  这是一个基于我老版本的Phong光照模型开发出来光照Shader,这个Shader支持一些光照(高达8个)。这里有这个Shader的两个版本,第一个版本是工作在NVIDIA和ATI显卡上的。第二个版本是则更加的灵活,可以允许多个光照作为统一的变量。这个统一的变量使用了一个for()循环(在顶点和像素Shader中),目前只有NVIDIA GeForce和ATI Radeon HD 5000 才能支持这个Shader. 这里有一个BUG,那就是在早期的Radeon卡(HD 4K 3K 2K)中执行第二个Shader.


  你可以下载一个GeeXLab demo 来实时的观察这个Shader
  解压这个安装包到你先要的地方,你可以从Start_Demo_ATI_NVIDIA.bat来开始这个ATI/NVIDIA的示例和通过点击Start_Demo_NVIDIA_only.bat 来运行NVIDIA和ATI HD 5000 demo
  一些测试结果:
 · §  Core 2 Duo E8400 / GeForce GTS 250(Fw191.07) / WinXP SP2: 2800 FPS (800×600)and 800 FPS (1920×1200)
 · §  AMD X2 3800+ / Radeon HD 4850(Cat9.9) / WinXP SP2: 2850 FPS (800×600)and 1350 FPS (1920×1080)


  第一个Shader介绍(针对NVIDIA和ATI)
 · 开发语言:OpenGL2-GLSL
 · 类型:Lighting
 · 输入:无(一些光照是硬编码:查看NUM_LIGHT定义)
 · 输出:颜色缓存
 · Shader代码:
[Vertex_Shader]
varying vec3 normal, eyeVec;
#define MAX_LIGHTS 8
#define NUM_LIGHTS 3
varying vec3 lightDir[MAX_LIGHTS];
void main()
{
gl_Position = ftransform();
normal = gl_NormalMatrix * gl_Normal;
vec4 vVertex = gl_ModelViewMatrix * gl_Vertex;
eyeVec = -vVertex.xyz;
 int i;
 for (i=0; i<NUM_LIGHTS; ++i)
lightDir[i] =
vec3(gl_LightSource[i].position.xyz - vVertex.xyz);
}
[Pixel_Shader]
varying vec3 normal, eyeVec;
#define MAX_LIGHTS 8
#define NUM_LIGHTS 3
varying vec3 lightDir[MAX_LIGHTS];
void main (void)
{
vec4 final_color =
gl_FrontLightModelProduct.sceneColor;
vec3 N = normalize(normal);
 int i;
 for (i=0; i<NUM_LIGHTS; ++i)
 {
vec3 L = normalize(lightDir[i]);
 float lambertTerm = dot(N,L);
 if (lambertTerm > 0.0)
 {
final_color +=
gl_LightSource[i].diffuse *
gl_FrontMaterial.diffuse *
lambertTerm;
vec3 E = normalize(eyeVec);
vec3 R = reflect(-L, N);
 float specular = pow(max(dot(R, E), 0.0),
gl_FrontMaterial.shininess);
final_color +=
gl_LightSource[i].specular *
gl_FrontMaterial.specular *
specular;
 }
 }
gl_FragColor = final_color;
}
  第二个Shader介绍(只针对NVIDIA和ATI Redeon HD 5000)
 · 语言:OpenGL2-GLSL
 · 类型:Lighting
 · 输入:Int型的numLight 表示Light的数量、最大值为8
 · 输出:颜色缓存
 · Shader代码:
[Vertex_Shader]
varying vec3 normal, eyeVec;
#define MAX_LIGHTS 8
varying vec3 lightDir[MAX_LIGHTS];
uniform int numLights;
void main()
{
gl_Position = ftransform();
normal = gl_NormalMatrix * gl_Normal;
vec4 vVertex = gl_ModelViewMatrix * gl_Vertex;
eyeVec = -vVertex.xyz;
 int i;
 for (i=0; i<numLights; ++i)
lightDir[i] =
vec3(gl_LightSource[i].position.xyz - vVertex.xyz);
}
[Pixel_Shader]
varying vec3 normal, eyeVec;
#define MAX_LIGHTS 8
varying vec3 lightDir[MAX_LIGHTS];
uniform int numLights;
void main (void)
{
vec4 final_color =
gl_FrontLightModelProduct.sceneColor;
vec3 N = normalize(normal);
 int i;
 for (i=0; i<numLights; ++i)
 {
vec3 L = normalize(lightDir[i]);
 float lambertTerm = dot(N,L);
 if (lambertTerm > 0.0)
 {
final_color +=
gl_LightSource[i].diffuse *
gl_FrontMaterial.diffuse *
lambertTerm;
vec3 E = normalize(eyeVec);
vec3 R = reflect(-L, N);
 float specular = pow(max(dot(R, E), 0.0),
gl_FrontMaterial.shininess);
final_color +=
gl_LightSource[i].specular *
gl_FrontMaterial.specular *
specular;
 }
 }
gl_FragColor = final_color;
}
  对于比较懒的人来说,这里有一个单灯光Shader(在ATI和NVIDIA上工作):
  Shader代码:
[Vertex_Shader]
varying vec3 normal, eyeVec, lightDir;
void main()
{
gl_Position = ftransform();
normal = gl_NormalMatrix * gl_Normal;
vec4 vVertex = gl_ModelViewMatrix * gl_Vertex;
eyeVec = -vVertex.xyz;
lightDir =
vec3(gl_LightSource[0].position.xyz - vVertex.xyz);
}
[Pixel_Shader]
varying vec3 normal, eyeVec, lightDir;
void main (void)
{
vec4 final_color =
gl_FrontLightModelProduct.sceneColor;
vec3 N = normalize(normal);
vec3 L = normalize(lightDir[0]);
 float lambertTerm = dot(N,L);
 if (lambertTerm > 0.0)
 {
final_color +=
gl_LightSource[0].diffuse *
gl_FrontMaterial.diffuse *
lambertTerm;
vec3 E = normalize(eyeVec);
vec3 R = reflect(-L, N);
 float specular = pow(max(dot(R, E), 0.0),
gl_FrontMaterial.shininess);
final_color +=
gl_LightSource[0].specular *
gl_FrontMaterial.specular *
specular;
 }
gl_FragColor = final_color;
}
  原文链接:http://www.geeks3d.com/20091013/shader-library-phong-shader-with-multiple-lights-glsl/
  版权声明:原文作者未做权利声明,视为共享知识产权进入公共领域,自动获得授权;

原文链接

著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

游戏学院公众号二维码
腾讯游戏学院
微信公众号

提供更专业的游戏知识学习平台