Per Fragment Lighting :逐片元光照
在OGLSL中,你可以使用opengl 光照状态组件。实现预设的光照模型可以与标准OPENGL状态兼容。
使用光照状态:
你可以使用所有的opengl光照状态和一些衍生的状态,下面的代码也可以在OGLSL说明书中找到。
光源参数:
你可以使用内置的一致变量 "gl_LightSource"在你的opengl程序中定义光源参数。在C++程序中你可以用简单地用"glLight*"来定义
.
struct gl_LightSourceParameters { vec4 ambient; // Acli vec4 diffuse; // Dcli vec4 specular; // Scli vec4 position; // Ppli vec4 halfVector; // Derived: Hi vec3 spotDirection; // Sdli float spotExponent; // Srli float spotCutoff; // Crli // (range: [0.0,90.0], 180.0) float spotCosCutoff; // Derived: cos(Crli) // (range: [1.0,0.0],-1.0) float constantAttenuation; // K0 float linearAttenuation; // K1 float quadraticAttenuation;// K2 }; uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights]; |
材质参数:
你可以在你的C++程序中使用 gl_FrontMaterial 和 gl_BackMaterial调用"glMaterial*" 函数来设置材质属性。
struct gl_MaterialParameters { vec4 emission; // Ecm vec4 ambient; // Acm vec4 diffuse; // Dcm vec4 specular; // Scm float shininess; // Srm }; uniform gl_MaterialParameters gl_FrontMaterial; uniform gl_MaterialParameters gl_BackMaterial; |
从光源和材质中派生出来的状态:
struct gl_LightModelProducts { vec4 sceneColor; // Derived. Ecm + Acm * Acs }; uniform gl_LightModelProducts gl_FrontLightModelProduct; uniform gl_LightModelProducts gl_BackLightModelProduct; struct gl_LightProducts { vec4 ambient; // Acm * Acli vec4 diffuse; // Dcm * Dcli vec4 specular; // Scm * Scli }; uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights]; uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights]; |
着色器代码:
顶点着色器:
varying vec3 N; varying vec3 v; void main(void) { v = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal); gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; } |
片元着色器
varying vec3 N; varying vec3 v; void main (void) { vec3 L = normalize(gl_LightSource[0].position.xyz - v); vec3 E = normalize(-v); // we are in Eye Coordinates, so EyePos is (0,0,0) vec3 R = normalize(-reflect(L,N)); //calculate Ambient Term: vec4 Iamb = gl_FrontLightProduct[0].ambient; //calculate Diffuse Term: vec4 Idiff = gl_FrontLightProduct[0].diffuse * max(dot(N,L), 0.0); // calculate Specular Term: vec4 Ispec = gl_FrontLightProduct[0].specular * pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess); // write Total Color: gl_FragColor = gl_FrontLightModelProduct.SceneColor + Iamb + Idiff + Ispec; } |
Questions问题:
1. Implement lighting for n lights, where n = gl_MaxLights. (note: there is no good solution for this question with current drivers yet)
2. This implementation uses point lights only. Add spot light support.