文档章节

翻译:探索GLSL-用几何着色器(着色器库)实现法线可视化

FreeBlues
 FreeBlues
发布于 2016/07/26 12:19
字数 1177
阅读 45
收藏 0

翻译:探索GLSL-用几何着色器(着色器库)实现法线可视化

翻译自: Exploring GLSL – Normal Visualizer with Geometry Shaders (Shader Library)

  • 译者: FreeBlues

概述

亲爱的读者们, 我回来了! 已经三周没发表新文章了... 很多事情需要去做, 再加上跟明媚的天气 -- 导致没有新文章给 Geek3D.

今天我们来看看一个简单而有用的几何着色器(geometry shaders)的应用: 法线可视化(normal visualizer). 我已经在文章Simple Introduction to Geometry Shaders in GLSL (Part 1)Simple Introduction to Geometry Shaders in GLSL (Part 2 中讨论过 GLSL几何着色器.

一个 几何着色器 允许创建一个新的几何图形(一个顶点, 一条线, 或者一个多边形) on the fly. 我们将会利用这个特性生成一个三角形网格的顶点和面的可视化法线的线条.

本文的示例用GLSL Hacker编写, 你可以在 Code Sample PackGLSL_Geometry_Shader_Normal_Visualizer/ 目录中找到全部的源码. 你可以来这里下载(我建议使用最新的 DEV 版本).

一般而言, GLSL 程序并不特定于 GLSL Hacker. 你可以在任何 OpenGL/WebGL 应用中使用它们, 只需要做一些小小的修改(着色器输入).

顶点法线可视化

截图:

顶点法线的生成很简单. 每个法线都是由两个顶点构成的一条线. 第一个顶点就是输入的顶点(属于当前的网格-mesh). 第二个顶点就是第一个顶点沿着它的法线方向做一段位移后的新顶点.

V0 = Pi
V1 = pi + (normal_length * N)
  • i 是顶点索引(范围0~2是因为几何着色器的输入是一个三角形).
  • PiNi 是第i 个顶点的位置法线.
  • V0V1 是新线条的顶点.

顶点法线几何着色器输入顶点的一部分. 下面是完整的原来渲染顶点法线的 GLSL 程序(顶点+几何+片段).

  • 顶点着色器

这是一个简单的透传顶点着色器. 这里没有任何变换(译者注:指矩阵变换), 顶点将在几何着色器中被变换用于最终的显示.

#version 150
in vec4 gxl3d_Position;
in vec4 gxl3d_Normal;
 
out Vertex
{
  vec4 normal;
  vec4 color;
} vertex;
 
void main()
{
  gl_Position = gxl3d_Position;
  vertex.normal = gxl3d_Normal;
  vertex.color =  vec4(1.0, 1.0, 0.0, 1.0);
}
  • 几何着色器

几何着色器 做了大部分的工作: 它把顶点从本地空间(译者注: 也叫模型空间)变换到窗口空间(裁剪空间)(gxl3d_ModelViewProjectionMatrix)并且创建了那些线条.

#version 150
layout(triangles) in;
 
// Three lines will be generated: 6 vertices
layout(line_strip, max_vertices=6) out;
 
uniform float normal_length;
uniform mat4 gxl3d_ModelViewProjectionMatrix;
 
in Vertex
{
  vec4 normal;
  vec4 color;
} vertex[];
 
out vec4 vertex_color;
 
void main()
{
  int i;
  for(i=0; i<gl_in.length(); i++)
  {
    vec3 P = gl_in[i].gl_Position.xyz;
    vec3 N = vertex[i].normal.xyz;
    
    gl_Position = gxl3d_ModelViewProjectionMatrix * vec4(P, 1.0);
    vertex_color = vertex[i].color;
    EmitVertex();
    
    gl_Position = gxl3d_ModelViewProjectionMatrix * vec4(P + N * normal_length, 1.0);
    vertex_color = vertex[i].color;
    EmitVertex();
    
    EndPrimitive();
  }
}
  • 片段着色器
#version 150
in vec4 vertex_color;
out vec4 Out_Color;
void main()
{
  Out_Color = vertex_color;
}

面法线可视化

截图:

顶点法线的生成很简单. 让我们看看如何在几何着色器中生成面法线. 我们所需要的是定义一个三角形的三个顶点. 幸运的是这些顶点是几何着色器的输入, 感谢这一行代码:

layout(triangles) in; 

如果 P0, P1P2是面顶点的位置, 面法线就是下面的叉积(cross product)的结果:

V0 = P0-P1
V1 = P2-P1
N = cross (V1, V0)

截图:

现在我们已经有了编写面法线可视化的所有理论. 下面就是单独的 几何着色器 的代码, 因为跟前面的 GLSL 程序相比, 只有 几何着色器 做了更新. 这个 几何着色器 生成 3 条顶点法线(黄色), 1 条面法线(红色): 4 条线或者 8 个新顶点.

  • 几何着色器
#version 150
layout(triangles) in;
layout(line_strip, <b>max_vertices=8</b>) out;
 
uniform float normal_length;
uniform mat4 gxl3d_ModelViewProjectionMatrix;
 
in Vertex
{
  vec4 normal;
  vec4 color;
} vertex[];
 
out vec4 vertex_color;
 
void main()
{
  int i;
  
  //------ 3 lines for the 3 vertex normals
  //
  for(i=0; i&lt;gl_in.length(); i++)
  {
    vec3 P = gl_in[i].gl_Position.xyz;
    vec3 N = vertex[i].normal.xyz;
    
    gl_Position = gxl3d_ModelViewProjectionMatrix * vec4(P, 1.0);
    vertex_color = vertex[i].color;
    EmitVertex();
    
    gl_Position = gxl3d_ModelViewProjectionMatrix * vec4(P + N * normal_length, 1.0);
    vertex_color = vertex[i].color;
    EmitVertex();
    
    EndPrimitive();
  }
  
 
  //------ One line for the face normal
  //
  vec3 P0 = gl_in[0].gl_Position.xyz;
  vec3 P1 = gl_in[1].gl_Position.xyz;
  vec3 P2 = gl_in[2].gl_Position.xyz;
  
  vec3 V0 = P0 - P1;
  vec3 V1 = P2 - P1;
  
  vec3 N = cross(V1, V0);
  N = normalize(N);
  
  // Center of the triangle
  vec3 P = (P0+P1+P2) / 3.0;
  
  gl_Position = gxl3d_ModelViewProjectionMatrix * vec4(P, 1.0);
  vertex_color = vec4(1, 0, 0, 1);
  EmitVertex();
  
  gl_Position = gxl3d_ModelViewProjectionMatrix * vec4(P + N * normal_length, 1.0);
  vertex_color = vec4(1, 0, 0, 1);
  EmitVertex();
  EndPrimitive();
}

参考

OpenGL Superbible, fifth edition, chapter 11

相关文章

Mesh Exploder with Geometry Shaders
Simple Introduction to Geometry Shaders in GLSL (Part 2)
Particle Billboarding with the Geometry Shader (GLSL)
(Shader Library) Bumpy Sphere Env Normal Mapping
Simple Introduction to Geometry Shaders in GLSL (Part 1)

© 著作权归作者所有

共有 人打赏支持
FreeBlues
粉丝 98
博文 280
码字总数 493678
作品 0
其它
程序员
私信 提问
[Qt和GLSL的笔记3] GLSL基本知识和两个小例子

时间:2017年4月21日 作者:RyuZhihao123 (northwest A&F University) 写在前面: 这一部分可能相对乏味。主要是我整理的关于GLSL的基本知识。 Qt和GLSL开发3 - GLSL基本知识 一、关于固定管...

Mahabharata_
2017/04/21
0
0
翻译:GLSL的顶点位移贴图

翻译:GLSL的顶点位移贴图 翻译自: Vertex Displacement Mapping using GLSL - 译者: FreeBlues 说明: 之所以选择这篇文档, 是因为现在但凡提到位移贴图(Displacement Mapping), 都要求设备支...

FreeBlues
2016/07/23
79
2
翻译:非常详细易懂的法线贴图(Normal Mapping)

翻译:非常详细易懂的法线贴图(Normal Mapping) - 本文翻译自: Shaders » Lesson 6: Normal Mapping 作者: Matt DesLauriers - 译者: FreeBlues 这一系列依赖于最小规模的用于着色器和渲染工...

FreeBlues
2016/08/05
199
0
OpenGL学习之路4----使用着色器(shader)

根据教程:ogldev一步步从零开始,记录学习历程 一、OpenGL 渲染管线 这节相比上一节有了本质上的区别,OpenGL实际上是通过渲染管线(rendering pipeline),经过一系列的数据处理,将应用程序的...

zach_z
2018/04/23
0
0
从0开始的OpenGL学习(二十五)

本章主要解决1个问题: 如何在OpenGL使用几何着色器? 引言 除了顶点着色器和片元着色器,OpenGL还提供了几个额外的着色器可供使用,本章讲的几何着色器(geometry shader)就是其中之一。几...

闪电的蓝熊猫
2017/12/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

5、redis分布式锁

参考链接:https://www.cnblogs.com/linjiqin/p/8003838.html 一:介绍 实现分布式锁有三种方式:1、数据库乐观锁,2、基于redis,3、基于zookeeper。 redis服务端是单线程操作,完美地避免了...

刘付kin
23分钟前
3
0
OSChina 周日乱弹 —— 我重新说

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @宇辰OSC :分享矢野立美的单曲《LOVE Theme from TIGA <M-2>》: 《LOVE Theme from TIGA <M-2>》- 矢野立美 手机党少年们想听歌,请使劲儿戳...

小小编辑
今天
64
5
Java单例模式学习记录

在项目开发中经常能遇见的设计模式就是单例模式了,而实现的方式最常见的有两种:饿汉和饱汉(懒汉)。由于日常接触较多而研究的不够深入,导致面试的时候被询问到后有点没底,这里记录一下学习...

JerryLin123
昨天
10
0
VSCODE 无法调试

VSCODE 无法调试 可以运行 可能的原因: GCC 的参数忘了加 -g

shzwork
昨天
5
0
理解去中心化 稳定币 DAI

随着摩根大通推出JPM Coin 稳定币,可以预见稳定币将成为区块链落地的一大助推器。 坦白来讲,对于一个程序员的我来讲(不懂一点专业经济和金融),理解DAI的机制,真的有一点复杂。耐心看完...

Tiny熊
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部