+BIT祝威+悄悄在此留下版了个权的信息说:

CSharpGL(14)用geometry shader渲染模型的法线(normal)

+BIT祝威+悄悄在此留下版了个权的信息说:

由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了。CSharpGL源码中包含10多个独立的Demo,更适合入门参考。

为了尽可能提升渲染效率,CSharpGL是面向Shader的,因此稍有难度。

问题

在处理光照效果等问题时,模型的顶点的法线是必不可少的数据。但是法线并不直接显示在模型上,也没有别的办法可以直观地看到。如果法线计算错了,那是非常难以排查的。所以我就想用geometry shader来渲染出模型的法线。如下图的白色针状部分,就是这个teapot的法线。为了便于区分,针尖部分是顶点位置,较粗的针头部分则是法线的方向。从这个图中可以看到,我做的这个teapot的法线是很有问题的。怪不得之前拿它试验光照效果时会有一些诡异的现象。

CSharpGL(14)用geometry shader渲染模型的法线(normal)

+BIT祝威+悄悄在此留下版了个权的信息说:

下载

这个示例是CSharpGL的一部分,CSharpGL已在GitHub开源,欢迎对OpenGL有兴趣的同学加入(https://github.com/bitzhuwei/CSharpGL

 

+BIT祝威+悄悄在此留下版了个权的信息说:

原理

Geometry shader的执行,在vertex shader之后,在fragment shader之前。Geometry shader的输入数据是一个primitive(points、lines、triangles等),输出可以是0或多个primitive(points、line_strip或triangle_strip)。Geometry shader的作用,就是能增加新的图元。本篇就利用这个功能,将模型顶点的法线作为新增的图元渲染出来。

+BIT祝威+悄悄在此留下版了个权的信息说:

Geometry shader

Geometry shader代码如下,含义参考注释即可。如果要用此shader,最好删掉中文注释。因为有的显卡可能不支持中文,会造成无法编译通过的情况。

 1 #version 410 core
 2 
 3 //输入类型为三角形
 4 layout (triangles) in;
 5 //输出的是三角形带
 6 layout (triangle_strip, max_vertices = 11) out;
 7 
 8 uniform mat4 modelMatrix;
 9 uniform mat4 viewMatrix;
10 uniform mat4 projectionMatrix;
11 
12 uniform float normalLength = 0.5f;
13 
14 in VS_GS_VERTEX
15 {
16     vec3 normal;
17 } vertex_in[];
18 
19 out GS_FS_VERTEX
20 {
21     vec3 color;
22 } vertex_out;
23 
24 void main(void)
25 {
26     int i;
27     //先输出模型本身
28     for (i = 0; i < gl_in.length(); i++) {
29         vertex_out.color = vertex_in[i].normal;
30         vec4 position = gl_in[i].gl_Position;
31         gl_Position = projectionMatrix * viewMatrix * (modelMatrix * position);
32         EmitVertex();
33     }
34     EndPrimitive();
35 
36     //生成顶点的法线(一个法线用一个三棱柱表示)
37     for (i = 0; i < gl_in.length(); i++) {//我的理解:此处gl_in.length()为3
38         //法线颜色为白色
39         vertex_out.color = vec3(1, 1, 1);
40 
41          //获取模型的顶点位置(针尖)
42         vec4 position = gl_in[i].gl_Position;
43         //获取模型的法线(针头)位置
44         vec4 target = position + vertex_in[i].normal * normalLength;
45         {
46             vec4 v0 = position;
47             gl_Position = projectionMatrix * viewMatrix * (modelMatrix * v0);
48             EmitVertex();//生成一个三棱柱顶点
49 
50             vec4 v1 = target;
51             if (target.x > position.x) { v1.x += normalLength / 30.0f; }
52             else { v1.x -= normalLength / 10.0f; }
53             gl_Position = projectionMatrix * viewMatrix * (modelMatrix * v1);
54             EmitVertex();//生成一个三棱柱顶点
55 
56             vec4 v2 = position;
57             gl_Position = projectionMatrix * viewMatrix * (modelMatrix * v2);
58             EmitVertex();//生成一个三棱柱顶点
59 
60             vec4 v3 = target;
61             if (target.y > position.y) { v3.y += normalLength / 30.0f; }
62             else { v3.y -= normalLength / 10.0f; }
63             gl_Position = projectionMatrix * viewMatrix * (modelMatrix * v3);
64             EmitVertex();//生成一个三棱柱顶点
65             
66             vec4 v4 = position;
67             gl_Position = projectionMatrix * viewMatrix * (modelMatrix * v4);
68             EmitVertex();//生成一个三棱柱顶点
69 
70             vec4 v5 = target;
71             if (target.z > position.z) { v5.z += normalLength / 30.0f; }
72             else { v5.z -= normalLength / 10.0f; }
73             gl_Position = projectionMatrix * viewMatrix * (modelMatrix * v5);
74             EmitVertex();//生成一个三棱柱顶点
75 
76             vec4 v6 = position;
77             gl_Position = projectionMatrix * viewMatrix * (modelMatrix * v6);
78             EmitVertex();//生成一个三棱柱顶点
79 
80             vec4 v7 = target;
81             if (target.x > position.x) { v7.x += normalLength / 30.0f; }
82             else { v7.x -= normalLength / 10.0f; }
83             gl_Position = projectionMatrix * viewMatrix * (modelMatrix * v7);
84             EmitVertex();//生成一个三棱柱顶点
85 
86         }
87         
88         EndPrimitive();//依据上面的8个顶点,为此顶点的法线生成一个三棱柱
89     }
90 }
geometry shader

相关文章:

  • 2021-10-12
  • 2022-12-23
  • 2021-06-18
  • 2021-04-25
  • 2021-07-22
  • 2021-07-15
  • 2021-06-01
  • 2023-03-09
猜你喜欢
  • 2021-08-03
  • 2021-07-13
  • 2021-04-26
  • 2022-12-23
  • 2021-06-29
  • 2022-02-08
相关资源
相似解决方案