第五章第二节(2012下)
基于每个片元的光照计算III
// fragment shader // per-fragment interpolated values from the vertex shader in vec3 fN; in vec3 fL; in vec3 fE; uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct; uniform mat4 ModelView; uniform vec4 LightPosition; uniform float Shininess;
在OpenGL应用程序中计算
color4 light_ambient,light_diffuse,light_specular; point4 light_position; color4 reflect_ambient,reflect_diffuse,reflect_specular; color4 color_out,ambient,diffuse,specular; vec4 v0,v1,v2; //设有三个顶点 vec4 product(vec4 a,vec4 b) { return vec4(a[0]*b[0],a[1]*b[1],a[2]*b[2],a[3]*b[3])}; vec4 n=normalize(cross(v1-v0,v2-v1)); vec4 origin=vec4(0.0,0.0,0.0,1.0); point4 v=(v0+v1+v2)/3.0;//三角形的中心 vec4 view_direction=v-origin;
13
前面与后面
�默认状态下只是把对象的前面进行明暗处
理,对于凸对象这种处理结果是正确的 �如果设置进行两面光照,那么OpenGL就会 对曲面的双面进行明暗处理 �每一面都可以具有自己的属性,在着色器 中处理
14
发射项
�在OpenGL中可以用材料的发射项来模拟一个
光源 �该项的颜色不受任何其它光源或者变换的影响
光照模型中的各项是匹配的 �反射率 �w项表示透明度
vec4 ambient = vec4(0.2, 0.2, 0.2, 1.0); vec4 diffuse = vec4(1.0, 0.8, 0.0, 1.0); vec4 specular = vec4(1.0, 1.0, 1.0, 1.0); GLfloat shine = 100.0
和对象一起移动光源: 所有的变换在光源位置和对象定义 之前调用 � 固定对象,移动光源: 先定义对象,进行变换后,再定 义光源位置 � 固定光源,移动对象: 先定义光源位置,进行变换后,再 定义对象 � 分别移动光源和对象: 采用矩阵堆栈
�
11
材料属性
�材料属性也是OpenGL状态的一部分,与简单
在顶点着色器中实现光照计算 I
// vertex shader in vec4 vPosition; in vec3 vNormal; out vec4 color; //vertex shade // light and material properties uniform vec4 AmbientProduct, DiffuseProduct, SpecularProduct; uniform mat4 ModelView; uniform mat4 Projection; uniform vec4 LightPosition; uniform float Shininess;
在顶点着色器中实现光照计算III
// Compute terms in the illumination equation vec4 ambient = AmbientProduct; float Kd = max( dot(L, N), 0.0 ); vec4 diffuse = Kd*DiffuseProduct; float Ks = pow( max(dot(N, H), 0.0), Shininess ); vec4 specular = Ks * SpecularProduct; if( dot(L, N) < 0.0 ) specular = vec4(0.0, 0.0, 0.0, 1.0); gl_Position = Projection * ModelView * vPosition; color = ambient + diffuse + specular; color.a = 1.0; }
vec4 vec4 vec4 vec4 diffuse0 =vec4(1.0, 0.0, 0.0, 1.0); ambient0 = vec4(1.0, 0.0, 0.0, 1.0); specular0 = vec4(1.0, 0.0, 0.0, 1.0); light0_pos =vec4(1.0, 2.0, 3,0, 1.0);
基于每个片元的光照计算II
void main() { fN = vNormal; fE = vPosition.xyz; fL = LightPosition.xyz; if( LightPosition.w != 0.0 ) { fL = LightPosition.xyz - vPosition.xyz; } gl_Position = Projection*ModelView*vPosition; }
在顶点着色器中实现光照计算IV
// fragment shader in vec4 color; void main() { gl_FragColor = color; }
基于每个片元的光照计算 I
// vertex shader in vec4 vPosition; in vec3 vNormal; // output values that will be interpolatated per-fragment out vec3 fN; out vec3 fE; out vec3 fL; uniform mat4 ModelView; uniform vec4 LightPosition; uniform mat4 Projection;
3
OpenGL 明暗处理
�
� � �
需要
法向量 材料属性 光源
-
-
弃用基于状态的明暗处理函数 (glNormal, glMaterial, glLight) 在应用中计算或传送属性给着色器来计 算
4
单位化
�用向量的点乘来计算余弦值 �单位向量的计算的计算可简单 �向量的单位化
可能被变换改变 � 特别注意:放大缩小变换会改变向量长度
OpenGL的明暗处理
第二节 光照模型的着色器实现
1
目标
�OpenGL明暗处理方法介绍
顶点与片元明暗处理 � 执行位置
�
�讨论多边形明暗处理
平坦 � 平滑 � Gouraud
�
2
OpenGL 明暗处理
�
� � �
需要
法向量 材料属性 光源
-
-
弃用基于状态的明暗处理函数 (glNormal, glMaterial, glLight) 在应用中计算或传送属性给着色器来计 算
在OpenGL应用程序中计算
ambient=product(light_ambient,reflect_ambient); float d=dot(n,normalize(light_position)); if (d>0) diffuse=product(light_diffuse,reflect_diffuse)*d; else diffuse=vec4(0.0,0.0,0.0,1.0); vec4 half=normalize(light_position+view_direction); float s=dot(half,n); if (s>0.0) specular=pow(s,material_shininess)* product(light_specular,reflect_specular); else specular=vec4(0.0,0.0,0.0,1.0); color_out=ambient+diffuse+specular;
在顶点着色器中实现光照计算II
void main() { // Transform vertex position into eye coordinates vec3 pos = (ModelView * vPosition).xyz; vec3 L = normalize( LightPosition.xyz - pos ); vec3 E = normalize( -pos ); vec3 H = normalize( L + E ); // Transform vertex normal into eye coordinates vec3 N = normalize( ModelView*vec4(vNormal, 0.0) ).xyz;
7
距离与方向
�颜色采用RGBA �位置采用其次坐标
若 w =1.0,表示一个有限的位置 � 若 w =0.0, 表示方向向量
�
�距离项的系数采用二次项
(1/(a+b*d+c*d*d)) 其中d 是渲染的点到光源的距离
8
聚光灯
�设置聚光灯的各项参数
方向:DIRECTION � 角度范围:CUTOFF � 衰减指数: cosαφ Nhomakorabea15
透明效果
�材料属性是利用RGBA值指定的A值用来使表
面透明 �默认状态下不管A的值是多少,所有表都是不 透明的 �后面我们会讲到如何激活融合(blending)功能 以及这种功能的应用
16
多边形的明暗处理
�对每个顶点进行明暗处理的计算
顶点的颜色变为顶点的明暗效果,并且作为顶点 属性传送给顶点着色器 � 可以传送参数给顶点着色器,用于明暗处理的计 算