翻译:探索GLSL-用几何着色器(着色器库)实现法线可视化
翻译:探索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 Pack 的 GLSL_Geometry_Shader_Normal_Visualizer/ 目录中找到全部的源码. 你可以来这里下载(我建议使用最新的 DEV 版本).
一般而言, GLSL 程序并不特定于 GLSL Hacker. 你可以在任何 OpenGL/WebGL 应用中使用它们, 只需要做一些小小的修改(着色器输入).
顶点法线可视化
截图:

顶点法线的生成很简单. 每个法线都是由两个顶点构成的一条线. 第一个顶点就是输入的顶点(属于当前的网格-mesh). 第二个顶点就是第一个顶点沿着它的法线方向做一段位移后的新顶点.
V0 = Pi
V1 = pi + (normal_length * N)
i是顶点索引(范围0~2是因为几何着色器的输入是一个三角形).Pi和Ni是第i个顶点的位置和法线.V0和V1是新线条的顶点.
顶点法线是几何着色器输入顶点的一部分. 下面是完整的原来渲染顶点法线的 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, P1和P2是面顶点的位置, 面法线就是下面的叉积(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<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)
翻译:探索GLSL-用几何着色器(着色器库)实现法线可视化的更多相关文章
- python基础整理4——面向对象装饰器惰性器及高级模块
面向对象编程 面向过程:根据业务逻辑从上到下写代码 面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程 面向对象编程(Object Oriented Pro ...
- 【译】通过 Rust 学习解析器组合器 — Part 1
原文地址:Learning Parser Combinators With Rust 原文作者:Bodil 译文出自:掘金翻译计划 本文永久链接:https://github.com/xitu/gol ...
- 浩瀚技术团队... 安卓智能POS移动PDA开单器 开单器 进销存系统 进销存系统
浩瀚技术团队... 智能POS移动PDA开单器 开单器 进销存系统 进销存系统 点餐 会员管理 会员管理 深度解读 手机APP移动办公到底是什么? 快速打单POS·不仅仅是快那么简单!
- Qt之Dialog\widget\ mainwindow的区别和布局管理器 & 分裂器的区别
1.Dialog\widget\ mainwindow的区别 注意mainwindow和widget的区别,mainwindow都工具栏和菜单栏 Dialog and mainwinodws 都是继承 ...
- flash视频器播放器代码
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- 与众不同 windows phone (14) - Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成
原文:与众不同 windows phone (14) - Media(媒体)之音频播放器, 视频播放器, 与 Windows Phone 的音乐和视频中心集成 [索引页][源码下载] 与众不同 win ...
- python 带参与不带参装饰器的使用与流程分析/什么是装饰器/装饰器使用注意事项
一.什么是装饰器 装饰器是用来给函数动态的添加功能的一种技术,属于一种语法糖.通俗一点讲就是:在不会影响原有函数的功能基础上,在原有函数的执行过程中额外的添加上另外一段处理逻辑 二.装饰器功能实现的技 ...
- Django_rest_framework_渲染器/解析器/路由控制/分页
目录 渲染器 解析器 路由控制 分页 渲染器 简介 什么是渲染器 根据 用户请求URL 或 用户可接受的类型,筛选出合适的 渲染组件. 渲染器的作用 序列化.友好的展示数据 渲染器配置 首先要在set ...
- Python - 三大器 迭代器,生层器,装饰器
目录 Python - 三大器 迭代器,生层器,装饰器 一. 容器 二. 可迭代对象(iterable) 三. 迭代器 四. 生成器 五. 装饰器 1. 定义 六. 闭包 Python - 三大器 迭 ...
随机推荐
- Java中Class类详解、用法及泛化
Java中Class类及用法 Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识,即所谓的RTTI.这项信息纪录了每个对象所属的类.虚拟机通常使用运行时类型信息选准正确方 ...
- Jmeter(二十二)_jenkins配置gitlab插件与ant插件
Docker部署接口自动化持续集成环境第四步,代码上传到远程仓库! 接上文:脚本上传Gitlab 服务器中的Jenkins通过Gitlab插件读取远程Git远程仓库中的代码,然后通过ant插件进行构建 ...
- Windows10没有修改hosts文件权限的解决方案(亲测有效)
当遇到有hosts文件不会编辑或者,修改了没办法保存”,以及需要权限等问题如图: 或者这样: 我学了一招,现在教给你: 1.win+R 2.进入hosts的文件所在目录: 3.我们开始如何操作才能不出 ...
- 人类又被AI碾压,这次是星际争霸
还记得2017年,那个血洗围棋界的“阿尔法狗”吗? 这个由谷歌旗下 DeepMind 公司开发的 AI ,对阵世界顶尖围棋选手,打出完全碾压式的战绩: AlphaGo vs. 樊麾 - 5 : ...
- 《Linux内核分析》第五周
20135103王海宁 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 这周的实验在上周实验四的基础上, ...
- linux内核分析--操作系统是如何工作的?
一个简单的时间片轮转多道程序 操作系统的"两把剑":中断上下文(保存现场和恢复现场)和进程上下文的切换 源代码的分析 *使用的源代码为视频中所使用的精简内核的源代码 首先分析myp ...
- rabbitmq windows 安装,更改配置文件路径的问题(管理页面不显示的问题)
路径中的advanced和rabbitmq是advanced.config和rabbitmq.config的文件名而不是文件夹名 并将这两个环境变量加到path里. 完成后,执行命令:rabbitmq ...
- level3
伸冤下:老师的评论是有看到!看完我就去修改程序了,忘记回复请原谅!= = 前阵子都在修改功能和思路,但是由于一个细节的错误找不到,导致没有成品可以上传...求谅解. 细心真的很重要 = =!!! im ...
- 个人项目——wc源程序特征统计
这一次要做的项目是wc——统计程序文件特征的命令行程序. 根据需求需求得到的模式为:wc.exe [parameter][filename] 在[parameter]中,用户通过输入参数与程序交互,需 ...
- T检验在项目上的具体实施
我觉得 T 检验,应该用在 判断某种仿真条件因素 对碳纳米管的随机性 是否有显著影响 上.所以不是针对<相同仿真条件对不同源的影响>这个表中的数据做 T 检验 如:判断 金属/半导体比率 ...