OpenGL Shader in OpenCASCADE
eryar@163.com
Abstract. As implementation of one of the strategic steps in OpenCASCADE visualization component development road-map, support for GLSL shader programs has been added in OpenCASCADE Technology 6.7.0.
Key Words. OpenCASCADE, GLSL, Shader, Gooch Shader
1. Introduction
OpenCASCADE從6.7.0之后,Shader程序也成了源碼的一部分。程序開發者可以為實現各種特效提供自己的Shader程序。在TKOpenGl庫中就有Shader相關的類,如下圖所示:

OpenCASCADE中的Shader管理是完全自動完成的,和其他OpenGL的資源一樣。仔細看看這幾個類相關的函數,會發現與Qt中的Shader比較類似。對比使用,會加快對OpenGL Shader程序的理解。
在OCCT6.7.0版本中的Shader程序還有一些局限性,如不能使用GLSL1.40版本或更新版本的功能。為了克服這個局限性,OCCT為了實現一些shader的操作定義了一些uniform的變量,這樣Shader程序就不依賴于GLSL1.30定義的一些變量了,使程序的兼容性更好。在源文件的Shaders文件夾中的Declarations.glsl中定義了這些變量,摘抄部分如下所示:
// Vertex attributes
#ifdef VERTEX_SHADER
attribute vec4 occVertex;
attribute vec3 occNormal;
attribute vec4 occTexCoord;
attribute vec4 occVertColor;
#endif
// Matrix state
uniform mat4 occWorldViewMatrix; //!< World-view matrix
uniform mat4 occProjectionMatrix; //!< Projection matrix
uniform mat4 occModelWorldMatrix; //!< Model-world matrix
uniform mat4 occWorldViewMatrixInverse; //!< Inverse of the world-view matrix
uniform mat4 occProjectionMatrixInverse; //!< Inverse of the projection matrix
uniform mat4 occModelWorldMatrixInverse; //!< Inverse of the model-world matrix
uniform mat4 occWorldViewMatrixTranspose; //!< Transpose of the world-view matrix
uniform mat4 occProjectionMatrixTranspose; //!< Transpose of the projection matrix
uniform mat4 occModelWorldMatrixTranspose; //!< Transpose of the model-world matrix
uniform mat4 occWorldViewMatrixInverseTranspose; //!< Transpose of the inverse of the world-view matrix
uniform mat4 occProjectionMatrixInverseTranspose; //!< Transpose of the inverse of the projection matrix
uniform mat4 occModelWorldMatrixInverseTranspose; //!< Transpose of the inverse of the model-world matrix
與OpenGL的內置uniform變量對比會發現,主要內容都是類似的:
//
uniform mat4 gl_ModelViewMatrix;
uniform mat4 gl_ProjectionMatrix;
uniform mat4 gl_ModelViewProjectionMatrix;
uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];
//
// Derived matrix state that provides inverse and transposed versions
// of the matrices above. Poorly conditioned matrices may result
// in unpredictable values in their inverse forms.
//
uniform mat3 gl_NormalMatrix; // transpose of the inverse of the upper
// leftmost 3x3 of gl_ModelViewMatrix
uniform mat4 gl_ModelViewMatrixInverse;
uniform mat4 gl_ProjectionMatrixInverse;
uniform mat4 gl_ModelViewProjectionMatrixInverse;
uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords];
uniform mat4 gl_ModelViewMatrixTranspose;
uniform mat4 gl_ProjectionMatrixTranspose;
uniform mat4 gl_ModelViewProjectionMatrixTranspose;
uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords]
uniform mat4 gl_ModelViewMatrixInverseTranspose;
uniform mat4 gl_ProjectionMatrixInverseTranspose;
uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose;
uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords]
看樣子OpenCASCADE為了GLSL版本兼容性也是動了些腦筋啊!
2.Test Shader
為了方便在OpenCASCADE中測試自定義的Shader程序,OpenCASCADE在Draw Test Harness中提供了一個vshaderprog命令。如下圖所示為在Draw Test Harness中使用命令vshaderprog產生的Gouraud Shading和Phong Shading效果:
Figure 2.1 Gouraud Shading(Left) and Phong Shading(right) by OCCT
在Draw Test Harness中使用vshaderprog命令很簡單,如下圖所示:
Figure 2.2 vshaderprog usage
為指定的模型指定頂點著色器和片段著色器即可。
3.Gooch Shader
Gooch著色屬于非真實性圖像著色,主要用于繪制各種手冊、技術圖書上的示意圖。1998年,Bruce和Amy Gooch、Peter Shirley以及Elaine Cohen對示意圖進行了調查并提出了使用噴槍和畫筆繪制的彩色示意圖特征:
v 表面邊界、輪廓邊緣及對象表面的不連續處通常是使用黑色曲線繪制;
v 使用一個單獨的光源,它會在對象上產生白色的高光;
v 光源通常位于對象的上方,這樣在對象的可見區域上,漫反射部分會在[0,1]中變化;
v ……
Figure 3.1 Gooch Shader Effect
上圖所示為Gooch著色器渲染出來的效果,看上去是不是很有感覺??!以上圖片來自Amy Gooch, Bruce Gooch, Peter Shirley和Elaine Cohen的論文:
A Non-Photorealistic Lighting Model For Automatic Technical Illustration.
Department of Computer Science University of Utah. Utah大學還有著名的Utah Teapot。
在《OpenGL Shading Language》一書中發現了Gooch著色器的相關實現代碼,如下所示:
頂點著色器Gooch.vs:
//
// Vertex shader for Gooch shading
//
// Author: Randi Rost
//
// Copyright (c) 2002-2005 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//
uniform vec3 LightPosition; // (0.0, 10.0, 4.0)
varying float NdotL;
varying vec3 ReflectVec;
varying vec3 ViewVec;
void main()
{
LightPosition = vec3(0.0, 10.0, 4.0);
vec3 ecPos = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);
vec3 lightVec = normalize(LightPosition - ecPos);
ReflectVec = normalize(reflect(-lightVec, tnorm));
ViewVec = normalize(-ecPos);
NdotL = (dot(lightVec, tnorm) + 1.0) * 0.5;
gl_Position = ftransform();
}
片段著色器Gooch.fs:
//
// Fragment shader for Gooch shading
//
// Author: Randi Rost
//
// Copyright (c) 2002-2005 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//
uniform vec3 SurfaceColor; // (0.75, 0.75, 0.75)
uniform vec3 WarmColor; // (0.6, 0.6, 0.0)
uniform vec3 CoolColor; // (0.0, 0.0, 0.6)
uniform float DiffuseWarm; // 0.45
uniform float DiffuseCool; // 0.45
varying float NdotL;
varying vec3 ReflectVec;
varying vec3 ViewVec;
void main()
{
SurfaceColor = vec3(0.75, 0.75, 0.75);
WarmColor = vec3(0.6, 0.6, 0.0);
CoolColor = vec3(0.0, 0.0, 0.6);
DiffuseWarm = 0.45;
DiffuseCool = 0.45;
vec3 kcool = min(CoolColor + DiffuseCool * SurfaceColor, 1.0);
vec3 kwarm = min(WarmColor + DiffuseWarm * SurfaceColor, 1.0);
vec3 kfinal = mix(kcool, kwarm, NdotL);
vec3 nreflect = normalize(ReflectVec);
vec3 nview = normalize(ViewVec);
float spec = max(dot(nreflect, nview), 0.0);
spec = pow(spec, 32.0);
gl_FragColor = vec4(min(kfinal + spec, 1.0), 1.0);
}
將它們加載到OpenCASCADE中,顯示效果如下圖所示:
Figure 3.2 A Main Engine in Draw Test Harness
Figure 3.3 Use Gooch Shader Program
由上圖可知,Shader有一定的作用,但效果不是很理想。還需要學習相關的知識,才能完善。如果在OpenCASCADE中只修改下shader就可以得到各種特效,豈不快哉!
4.Conclusion
綜上所述,OpenGL的Shader是個很好玩的東西,所以OpenCASCADE中引入了這個。為了保證GLSL的兼容性,OpenCASCADE也定義了一些變量。
在不改變程序源碼的情況下,只換上不同的shader,就可以得到各種炫麗的特效,這些特效主要是利用GPU的資源完成,不占用CPU??碠penGL最新的規格書中,GLSL已經越來越Fashion了!
5. References
1. Randi J. Rost. OpenGL Shading Language. Addison Wesley. 2006
2. Amy Gooch, Bruce Gooch, Peter Shirley, Elaine Cohen. A Non-Photorealistic Lighting Model For Automatic Technical Illustration. Department of Computer Science University of Utah.
3. San, Shader support in OCCT6.7.0. http://dev.opencascade.org/index.php?q=node/902