【译】【Shader库】在多个光源下的Phong Shader(GLSL)
发表于2016-03-28
译者注:
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/
版权声明:原文作者未做权利声明,视为共享知识产权进入公共领域,自动获得授权;