1 / 60

高级计算机图形学

高级计算机图形学. 讲 授:董兰芳 研究方向:科学计算可视化 图形、图像处理 模式识别 Telephone:0551-3603484 Email:l fdong@ustc.edu.cn Homepage: http://staff.ustc.edu.cn/~lfdong 中国科学技术大学 视觉计算与可视化实验室. 第九章 可编程着色器. 9 . 6 GLSL 语言 9.7 GLSL 程序使用 9.8 顶点波动 9.9 二维图形渐变 9.10 非真实感着色

gunnar
Download Presentation

高级计算机图形学

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 高级计算机图形学 讲 授:董兰芳 研究方向:科学计算可视化 图形、图像处理 模式识别 Telephone:0551-3603484 Email:lfdong@ustc.edu.cn Homepage: http://staff.ustc.edu.cn/~lfdong 中国科学技术大学 视觉计算与可视化实验室

  2. 第九章 可编程着色器 9.6GLSL语言 9.7 GLSL程序使用 9.8 顶点波动 9.9 二维图形渐变 9.10 非真实感着色 9.11 基于可编程着色器的光照计算 9.12 Sampler变量类型 9.13 立方体贴图 2

  3. 9.6 GLSL语言 • 基础知识 • GLSL的语法来自于C/C++字符集、记号(tokens) 、标识符(identifiers) • 嵌套结构 • 控制流:if-else, for, while, do-while • 关键字 • 注释://…和/*…*/ • 入口函数:void main() 3

  4. 9.6 GLSL语言 • 数据类型-标量 • float 浮点型,IEEE754单精度不支持双精度,字面浮点常数的后缀f或F是可选的。 • int 整型,至少16位精度[-65535,65535] 十进制、八进制、十六进制:42, 052, 0x2A,不支持长整型,不支持按位运算;GLSL1.5精度为32位,支持无符号整型uint。 • bool布尔型:true/false关系运算和逻辑运算产生布尔型。 • 条件跳转表达式(if, for, ?:, while, do-while)只接受布尔型。 4

  5. 9.6 GLSL语言 • 数据类型-向量 • 二维到四维的float、int、bool型, • vec2、vec3、vec4 • ivec2、ivec3、ivec4 • bvec2、bvec3、bvec4 • 其中的元素可以通过下面的索引下标来获取: • (x, y, z, w) 位置或方向 • (r, g, b, a) 颜色 • (s, t, p, q) 纹理坐标 5

  6. 9.6 GLSL语言 • 数据类型-矩阵 • 2×2, 2×3, 2×4, 3×2, 3×3, • 3×4, 4×2, 4×3, 和4×4浮点矩阵 • mat2,mat3, mat4 • mat2x2, mat2x3, mat2x4 • mat3x2, mat3x3, mat3x4 • mat4x2, mat4x3, mat4x4 • 第一个数指定列数,第二个数指定行数。 • 列优先。例如4列3行矩阵:mat4x3 M;M[2]是 • 第3列,类型vec3;M[3][1]是第4列第2行元素。 6

  7. 9.6 GLSL语言 • 数据类型-采样器(sampler) • 纹理的不透明句柄 • sampler[1,2,3]D 访问1D 、2D 、3D纹理 • samplerCube 访问立方图纹理 • 例子: • uniform sampler2D Grass; • vec4 color = texture2D(Grass, coord); 7

  8. 9.6 GLSL语言 • 存储限定符 • 声明变量时可以在类型前指定存储限定符。 • 例:const 只读。 • attribute 应用程序传递给顶点着色器的每顶点数据。 • uniform 应用程序传递给着色器的图元数据。 • varying 顶点着色器经光栅化器传递给片段着色器的 • 插值数据。 8

  9. 9.6 GLSL语言 • attribute限定符 • OpenGL用attribute变量向顶点着色器传递每顶点 • 的数据。 • 在顶点着色器中声明为全局变量,只读不能在片元 • 着色器中声明使用。 • 使用OpenGL顶点API或顶点数组传递属性变量值 • 给顶点。 • 着色器类型限制为浮点标量、向量和矩阵,不能声 • 明为数组或结构float标量内部存储为vec4。 9

  10. 9.6 GLSL语言 uniform限定符 unifrom用于声明在图元处理时保持不变的全局变量, 不能在glBegin和glEnd间改变其值。 在顶点和片段着色器中只读任何类型的变量,包括 结构和数组。 10

  11. 9.6 GLSL语言 • varying限定符 • varying变量是顶点和片元着色器交流数据的唯一方式。 • 顶点着色器输出的每顶点数据由光栅化器插值为每片 • 元数据输入到片元着色器。 • 全局变量,顶点着色器可读写,片元着色器只读。 • 类型限制为浮点标量、向量和矩阵,以及这些类型的 • 数组,不能为结构。 11

  12. 9.6 GLSL语言 • 内置函数 • 角度和三角函数 • 指数函数 • 常用函数 • 几何函数 • 矩阵函数 • 向量关系函数 • 纹理访问函数 • 片元处理函数 • 噪声函数 12

  13. 9.6 GLSL语言 • 顶点着色器 • 顶点着色器必须负责如下OpenGL固定功能的逐顶点操作: • 模型-视图矩阵和投影矩阵没有应用于顶点坐标。 • 纹理矩阵没有应用于纹理坐标。 • 法向量没有变换到观察坐标,且没有重新缩放或规范化。 • 没有对启用GL_AUTO_NORMAL执行法向规范化。 13

  14. 9.6 GLSL语言 • 顶点着色器 • 没有自动生成纹理坐标 • 没有执行每顶点的光照计算 • 没有执行彩色材料计算(glColorMaterial) • 没有执行彩色索引光照计算。 • 当设置当前光栅位置时,将应用上述所有操作。 14

  15. 9.6 GLSL语言 • 顶点着色器 • 下述操作将应用到顶点着色器所得到的顶点值: • 颜色钳位(clamping)和掩模(masking) • 裁剪坐标的透视除法 • 包括深度范围缩放的视口映射 • 包括用户定义裁剪平面的裁剪前向面确定 • 平面明暗处理 • 颜色、纹理坐标、雾、点大小等一般属性裁剪 • 最终颜色处理 15

  16. 9.6 GLSL语言 内置顶点属性(attribute) 应用程序提供顶点信息:位置、法向、颜色、纹理 坐标glVertex, glNormal, glColor, glTexCoord,glDrawArrays 内置顶点属性 attribute vec4 gl_Vertex; // glVertex attribute vec4 gl_Color; // glColor attribute vec4 gl_SecondaryColor; // glSecondaryColor attribute vec3 gl_Normal; // glNormal attribute vec4 gl_MultiTexCoordn;//glMultiTexCoord(n,…), n=0,…7 attribute float gl_FogCoord; // glFogCoord 16

  17. 9.6 GLSL语言 特殊输出变量 gl_Position:顶点着色器必须写入的齐次裁剪坐标,将用于 图元装配、裁剪、剔除 gl_PointSize:将被光栅化的点大小 gl_ClipVertex:相对于用户裁剪平面的顶点位置 vec4 gl_Position; // must be written to float gl_PointSize; // may be written to vec4 gl_ClipVertex; // may be written to 17

  18. 9.6 GLSL语言 • 片元着色器 • 片元着色器取代固定功能的纹理、颜色求和、雾等。 • 没有应用纹理环境和纹理函数 • 没有执行纹理应用程序 • 没有应用颜色求和 • 没用应用雾化 18

  19. 9.6 GLSL语言 内置常量 const int gl_MaxLights = 8; const int gl_MaxClipPlanes = 6; const int gl_MaxTextureUnits = 2; const int gl_MaxTextureCoords = 2; const int gl_MaxVertexAttribs = 16; const int gl_MaxVertexUniformComponents = 512; const int gl_MaxVaryingFloats = 32; const int gl_MaxVertexTextureImageUnits = 0; const int gl_MaxTextureImageUnits = 2; const int gl_MaxFragmentUniformComponents = 64; const int gl_MaxCombinedTextureImageUnits = 2; const int gl_MaxDrawBuffers = 1; 19

  20. 9.6 GLSL语言 内置uniform变量 uniform mat4 gl_ModelViewMatrix; uniform mat4 gl_ProjectionMatrix; uniform mat4 gl_ModelViewProjectionMatrix; uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords]; uniform mat3 gl_NormalMatrix; uniform vec4 gl_ClipPlane[gl_MaxClipPlanes]; uniform gl_MaterialParameters gl_FrontMaterial; uniform gl_MaterialParameters gl_BackMaterial; uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights]; uniform gl_LightModelParameters gl_LightModel; uniform gl_FogParameters gl_Fog; 20

  21. 9.6 GLSL语言 固定功能着色器变换 // Transform vertex to clip space gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; //or this: gl_Position = ftransform(); 21

  22. 9.6 GLSL语言 • 视点坐标位置计算 • 下述代码把顶点位置变换为视点坐标 • vec4 ecPosition; • vec3 ecPosition3; // in 3D space • // Transform vertex to eye coordinates • if (NeedEyePosition) • {ecPosition = gl_ModelViewMatrix * gl_Vertex; • ecPosition3 = (vec3(ecPosition)) / ecPosition.w; • } 22

  23. 9.6 GLSL语言 • 法向变换 • 在视点空间计算光照时,法向也必须变换到视点 • 空间。 • 法向规范化:glEnable(GL_NORMALIZE • 法向缩放:缩放比例因子为内置uniform变量 • gl_NormalScale • normal = gl_NormalMatrix * gl_Normal; • normal = normalize(normal); • normal = normal * gl_NormalScale; 23

  24. 9.6 GLSL语言 • 纹理坐标变换 • OpenGL的每一个纹理单元都定义了一个纹理矩阵, • 可用内置的uniform变量 • gl_TextureMatrix访问 • gl_TexCoord[0] = gl_TextureMatrix[0] * • gl_MultiTexCoord0; 24

  25. 第九章 可编程着色器 9.6GLSL语言详解 9.7 GLSL程序使用 9.8 顶点波动 9.9 二维图形渐变 9.10 非真实感着色 9.11 基于可编程着色器的光照计算 9.12 Sampler变量类型 9.13 立方体贴图 9.14 凹凸映射 25

  26. 9.7 GLSL程序使用 连接着色器与OpenGL 调用glCreateShader创建着色器对象 调用glShaderSource为着色器加载源代码 调用glCompileShader编译每个着色器 调用glCreateProgram创建程序对象 调用glAttachShader把着色器对象连接到程序对象 调用glLinkProgram 链接程序对象,生成可执行程序 调用glUseProgram安装可执行程序替换OpengGL固定 功能流水线处理模块 用uniform和attribute变量在应用程序和着色器间通信 26

  27. 9.7 GLSL程序使用 • OpenGL应用程序有两种方式向着色器发送值 • 使用内置和用户定义的全局变量 • uniform变量 • attribute变量 • 纹理可解释为图像或数据数组 27

  28. 9.7 GLSL程序使用 • 内置顶点属性 • 内置顶点属性gl_Color /gl_Normal • /gl_Vertex等glBegin/glEnd间用glColor • /glNormal /glVertex等函数指定 • 顶点数组方式 28

  29. 第九章 可编程着色器 9.6GLSL语言详解 9.7 GLSL程序使用 9.8 顶点波动 9.9 二维图形渐变 9.10 非真实感着色 9.11 基于可编程着色器的光照计算 9.12 Sampler变量类型 9.13 立方体贴图 9.14 凹凸映射 29

  30. 9.8 顶点波动 • 波动顶点着色器 • uniform float time; • uniform float xs, zs, // frequencies • uniform float h; // height scale • void main() • { • vec4 t = gl_Vertex; • t.y = gl_Vertex.y • + h*sin(time + xs*gl_Vertex.x) • + h*sin(time + zs*gl_Vertex.z); • gl_Position = • gl_ModelViewProjectionMatrix*t; • } • attribute变量和uniform变量在顶点着色器内只读 30

  31. 9.8 顶点波动 • Glint timeParam; • timeParam = glGetUniformLocation(program, • "time"); • void idle() • { • glUniform1f(timeParam, • (GLfloat) glutGet(GLUT_ELAPSED_TIME)); • glutPostRedisplay(); • } 31

  32. 第九章 可编程着色器 9.6GLSL语言详解 9.7 GLSL程序使用 9.8 顶点波动 9.9 二维图形渐变 9.10 非真实感着色 9.11 基于可编程着色器的光照计算 9.12 Sampler变量类型 9.13 立方体贴图 9.14 凹凸映射 32

  33. 9.9 二维图形渐变 • 渐变(morphing)效果 • 渐变:一个物体平滑地变换到另一个物体 • 假设两个物体的顶点有一一对应关系。 • 顶点着色器需要输出一个由对应顶点对插 • 值得到的顶点。 33

  34. 9.9 二维图形渐变 • 一个顶点通过gl_Vertex传入,对应顶点用顶点属 • 性变量传入。 • attribute vec4 vertices2; • uniform float time; • void main() • {float s = 0.5*(1.0+sin(0.001*time)); • vec4 t = mix(gl_Vertex, vertices2, s); • gl_Position = gl_ModelViewProjectionMatrix*t; • gl_FrontColor = gl_Color;} • mix(x, y, a) 返回x * (1.0-a) + y * a 34

  35. 9.9 二维图形渐变 • GLint vertices2Param; • vertices2Param=glGetAttribLocation(program, "vertices2"); • #define N 50 • GLfloat vertices_one[N][3], vertices_two[N][3]; • glBegin(GL_TRIANGLES); • for (int i = 0; i < N; i++) • {glVertexAttrib3fv(vertices2Param, • vertices_two[i]); • glVertex3fv(vertices_one[i]);} • glEnd(); 35

  36. 第九章 可编程着色器 9.6GLSL语言详解 9.7 GLSL程序使用 9.8 顶点波动 9.9 二维图形渐变 9.10 非真实感着色 9.11 基于可编程着色器的光照计算 9.12 Sampler变量类型 9.13 立方体贴图 9.14 凹凸映射 36

  37. 9.10 非真实感着色 • 非真实感着色 • 根据光线和法向的夹角给对象赋两种颜色 • 根据视线和方向的夹角把对象轮廓赋为黑色 • const vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0); • const vec4 red = vec4(1.0, 0.0, 0.0, 1.0); • const vec4 black = vec4(0.0, 0.0, 0.0, 1.0); • if(dot(L, N) > 0.5) gl_FrontColor = yellow; • else gl_FrontColor = red; • if(abs(dot(E, N)) < 0.1) glFrontColor = black; 37

  38. 第九章 可编程着色器 9.6GLSL语言详解 9.7 GLSL程序使用 9.8 顶点波动 9.9 二维图形渐变 9.10 非真实感着色 9.11 基于可编程着色器的光照计算 9.12 Sampler变量类型 9.13 立方体贴图 9.14 凹凸映射 38

  39. 9.11 基于可编程着色器的光照计算 Phong光照模型 I =kdIdl· n +ksIs(r· v )α+ kaIa I =kdIdl· n +ksIs(n· h )β+ kaIa 39

  40. 9.11 基于可编程着色器的光照计算 内置uniform变量 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]; 40

  41. 9.11 基于可编程着色器的光照计算 struct gl_LightModelParameters { vec4 ambient; // Acs}; uniform gl_LightModelParameters gl_LightModel; 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; 41

  42. 9.11 基于可编程着色器的光照计算 • Phong光照 • 光源位置gl_LightSource[i].position在视点坐标 • 系中给出视点在视点坐标系的原点 • N:视点坐标系中的法向量 • L:视点坐标系中的顶点到光源向量(光线) • E:视点坐标系中的顶点到视点向量(视线) • R:视点坐标系中的理想反射向量 • H:视点坐标系中L和E的中值向量 42

  43. 9.11 基于可编程着色器的光照计算 • void main(void) • /* modified Phong vertex shader (without distance term) */ • { • gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; • vec4 ambient, diffuse, specular; • vec4 eyePosition = gl_ModelViewMatrix * gl_Vertex; • vec4 eyeLightPos = gl_LightSource[0].position; • vec3 N = normalize(gl_NormalMatrix * gl_Normal); • vec3 L = normalize(eyeLightPos.xyz -eyePosition.xyz); • vec3 E = -normalize(eyePosition.xyz); • vec3 H = normalize(L + E); 43

  44. 9.11 基于可编程着色器的光照计算 改进的Phong顶点着色器II /* compute diffuse, ambient, and specular contributions */ float f = 1.0; float Kd = max(dot(L, N), 0.0); float Ks = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess); if (dot(L,N) < 0.0) f = 0.0; ambient = gl_FrontLightProduct[0].ambient; diffuse = Kd*gl_FrontLightProduct[0].diffuse; specular = f*Ks*gl_FrontLightProduct[0].specular; gl_FrontColor = ambient+diffuse+specular; } 44

  45. 9.11 基于可编程着色器的光照计算 • 基于片元的Phong光照 • 利用varying变量把属性从顶点着色器传递 • 到片元着色器法向量N • 光线向量L • 视线向量E 45

  46. 9.11 基于可编程着色器的光照计算 基于片元光照的顶点着色器 varying vec3 N, L, E; void main() { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; vec4 eyePosition = gl_ModelViewMatrix * gl_Vertex; vec4 eyeLightPos = gl_LightSource[0].position; N = normalize(gl_NormalMatrix * gl_Normal); L = normalize(eyeLightPos.xyz -eyePosition.xyz); E = -normalize(eyePosition.xyz); } 46

  47. 9.11 基于可编程着色器的光照计算 • 改进Phong光照片元着色器I • varying vec3 N; • varying vec3 L; • varying vec3 E; • void main() • { • vec3 Normal = normalize(N); • vec3 Light = normalize(L); • vec3 Eye = normalize(E); • vec3 Half = normalize(Eye + Light);} 47

  48. 9.11 基于可编程着色器的光照计算 • 改进Phong光照片段着色器II • float f = 1.0; • float Kd = max(dot(Normal, Light), 0.0); • float Ks = pow(max(dot(Half, Normal), 0.0), • gl_FrontMaterial.shininess); • vec4 diffuse = Kd * gl_FrontLightProduct[0].diffuse; • if (dot(Normal, Light) < 0.0) f = 0.0; • vec4 specular = f * Ks * gl_FrontLightProduct[0].specular; • vec4 ambient = gl_FrontLightProduct[0].ambient; • gl_FragColor = ambient + diffuse + specular; • } 48

  49. 9.11 基于可编程着色器的光照计算 效果对比 逐顶点光照 逐片段光照 49

  50. 第九章 可编程着色器 9.6GLSL语言详解 9.7 GLSL程序使用 9.8 顶点波动 9.9 二维图形渐变 9.10 非真实感着色 9.11 基于可编程着色器的光照计算 9.12 Sampler变量类型 9.13 立方体贴图 9.14 凹凸映射 50

More Related