openGL之glsl入门1--基本概念

2024-03-10 11:58

本文主要是介绍openGL之glsl入门1--基本概念,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

    从零开始学习openGL与GLSL(没有计算机图像学基础),开始确实挺费劲,网上的资料虽然多,但不系统,例子也不全,openGL还好(这里指的是v2.0之前的版本,使用glBegin(), glEnd()方式绘制),完整的例子比较多,而GLSL的例子相对少不少,中间走了不少弯路。下面说一下个人的一些学习经历和看法。

1. 学习路线

    GLSL的学习还是比较推荐以红宝书为主线进行学习,其他资料辅助,虽然入门难度比较大,但是比较系统权威,不会走偏,不懂的话多练练,多翻翻其他资料,也是可以慢慢弄清楚的。

     大家可以自己去找红宝书《OpenGL编程指南(第八版).pdf》(与之配套的源码《oglpg-8th-edition》 )。蓝宝书《OpenGL超级宝典》也是经典,大家也可以看看,都比较权威,正如他们的名字,红宝书重编程,蓝宝书重原理。

     个人的学习经历是:

1. 先把网上的老的openGL程序都跑一遍(使用glBegin(), glEnd()方式绘制 ),先看效果,再捋概念,熟悉老的程序的话,学GLSL会快很多,概念是一致的,只是编程实现方式不同。

2. 中途恶补《计算机图形学》知识,熟悉齐次坐标,坐标变换等知识。

3. 一章一章看红宝书,对照sample写自己的代码。

4. 再根据学习的情况,一步一步往自己的工作中需完成的任务上靠。

 

说明:关于红宝书,这里推荐大家以此为主线进行学习,估计很多人有意见,入门难度确实稍高,第一个程序,前面的4章讲完了才能基本搞懂,都不像一般的helloworld程序一样简洁,我也是搞了好久才把第一个例子跑起来,搞明白,而且sample程序里问题不少,根本没法直接用,可能是我下载了假的sample程序,做参考还是不错的,后来我放弃了直接跑sample,而只是参考,自己改写,这样理解更透彻。推荐的理由是系统性与权威性,而不是门槛高低,所以本文的目的不是替代书籍,而是为大家提供一些有意思的代码,让大家更好的理解红宝书。

2. 基本概念

2.1 顶点、片元着色器

     刚接触openGL,新概念确实不少,其中顶点着色器这个概念搞了好久都没弄明白,老是想着顶点着什么色,其实这个都是翻译误导的,英文为Vertex Shader,Shader这个词翻译为着色器不好理解,不过这东西确实不太好翻译,反正顶点着色器和上颜色没什么关系。

      这里从网上找了一张图,可以这么理解,顶点着色器的作用是做出石膏模子,而片元 着色器的作用是为石膏模子上色,简单的说,顶点着色器是做出3D图像的轮廓框架(毛坯,进行空间与空间变化等与空间相关操作),而片元 着色器让它变得好看一些,即上色(装修,进行颜色与纹理等操作)。片元着色器(fragment shader)有的又称为片段着色器,只是翻译问题,我们以红宝书的名称为准。

 

2.2 GLSLCS模型

     CS(客户端服务器)模型,client是gl打头的一系列api,对应的时CPU部分,而server就是GLSL语言部分,对应的时GPU部分。

     老的api编程对用户来说,这个概念不明显,api已经封装了GPU部分操作,在用户看来,感觉不出来哪些操作在cpu上执行,哪些在GPU上执行。这里举一个例子来辅助大家理解。

     上图是计算器和美元,用计算器算账,做以下类比:

1. 客户端:人的脑和手(数据输入,灵活,但计算速度不如计算器),计算器键盘是计算器提供给用户的接口(api)。

2. 服务器:计算器,单纯运算能力比较强(GPU)

     这就是固定管线模型,我们输入的数据(一天的账目),计算器很快的给出结果,比自己算快多了,GPU初期就是这样的。

     计算器用来算账是不错,但我有一个需求,我要求每一笔账目输入的是美元单位,而显示出来的是人民币单位,有两种方法

1. 输入账目的时候每一笔都乘一下汇率再输入(CPU处理),但这样,整体速度就慢太多了。

2. 也可以专门出一款计算器搞一个功能键(创一个新的api)来做这项工作,但用户的需求是多种多样的,这样的灵活性太差。想一想老式的中文打印机,每个字一个键(区位编码),用起来与扩展起来都非常不方便。

    此时的计算器就不满足需求了,我们需要可编程计算器(电脑),我输入数据过后,还可以控制输出数据的时候再乘一个汇率,这就是可编程管线。

    可编程管线简单的说就是,用户CPU输入数据过后,GPU还可以对数据做进一步编程处理,CPU只需要输入必要的数据,剩下的需求都交给GPU来做,充分利用GPU的处理优势,通过缓冲对象,进一步提高处理性能。CPU侧重点在数据输入与控制,GPU着重数据处理与显示。

     有的网友问,为什么《OpenGL编程指南(第八版).pdf》例子没有用到glBegin(), glEnd()的方式绘图,就是因为,红宝书8的例子全部用GLSL shader编程实现的,这些老的api新的版本已经废弃(但还是可以使用),这里建议大家还是先熟悉一下老的api,类比起来有助于理解。

2.3 归一化

     归一化实际是把对应的数据类型转成[0-1]的范围,如使用GL_UNSIGNED_BYTE 类型存储该颜色分量值, 归一化是把0~255转为0~1的范围,如RGBA中R的值为10,即颜色分量R归一化公式为R/255 = 10.0/255,有符号型数据的归一化会复杂一些,计算公式红宝书上有讲(3.3.1章节)。

     openGL的坐标系也是一种归一化的坐标系(规格化设备坐标系),在传入坐标时,api也经常有是否归一化的选项,注意归一化是根据数据类型长度来的,同一个值,不同类型的归一化完全不一样。这个特性要用,如果给出的是非归一化的坐标,如BMP中的RGBA的值,最好使用接口去归一化,用CPU归一化效率太低。

     openGL坐标范围为[-1.0,1.0],但不是说坐标只能是这个范围内的,超出范围后,只会显示不出来而已,通过缩放,平移,旋转等操作,可以把超出1.0的坐标显示出来,颜色RGBA的范围为[0,1.0],这个范围不能超,否则没意义。

     shader里面的颜色用的是RGBA,注意透明度分量A在最后。

2.4 齐次坐标

    为方便坐标转换,GLSL中用的坐标全是齐次坐标,即(x,y,z,w) 4维坐标,坐标变换的矩阵也是4维矩阵。

    齐次坐标(x,y,z,w)转3维坐标(x/w,y/w,z/w),

  

2.5 向量

     向量和点的表示方式比较类似,点主要是表示位置,向量主要表示方向。

     点是三维空间中的某个坐标,是绝对的,它的值是参照原点的,而向量用于表示力和速度等具有方向和大小的量, 通常用具有长度和方向的线段来表示,虽然他们都具有三个分量,但对于向量,如果将向量放在坐标系中的任何位置(平移),都不会改变其性质,因为向量表示的是方向和大小,与位置距离无关,它的值是相对与基准点的。

     齐次坐标与向量在shader编程中大量使用,还有矩阵的概念都需要弄清楚。

2.6 缓冲对象

     openGL中有大量的缓冲OBJECT,常见的有vbo,vao,ebo,pbo,fbo,这些缓冲对象开始学习的时候不是必须的,对openGL有一定的了解后再去深入理解即可,使用缓冲对象能使程序效率更高,不使用也能用。红宝书第一个例子就抬出了vbo和vao,确实增大学习难度,理解了过后,这些概念也没那么难,但由于使用方式习惯(gen bind方式)与一般程序使用方式习惯不一样,又夹杂着一堆的新概念、新的api,学习难度就上来了。

     本文档后续用完整例子来讲解缓冲对象的用法。

3. 其他说明

     系列学习文章都是针对GLSL编程的,基于glsl3.3版本。

     后续的例子尽量不依赖太多内容,程序尽量完整,尽量能直接跑,用的C语言,应该可以跨平台。

     学GLSL之前,大家还是把老的openGL程序先熟悉一下(使用glBegin(), glEnd() 绘制),环境搭建与辅助库的使用大家自己去了解。可以边学边查。

     不清楚的地方,可以一起交流。

 

这篇关于openGL之glsl入门1--基本概念的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/794175

相关文章

Spring WebClient从入门到精通

《SpringWebClient从入门到精通》本文详解SpringWebClient非阻塞响应式特性及优势,涵盖核心API、实战应用与性能优化,对比RestTemplate,为微服务通信提供高效解决... 目录一、WebClient 概述1.1 为什么选择 WebClient?1.2 WebClient 与

Spring Boot 与微服务入门实战详细总结

《SpringBoot与微服务入门实战详细总结》本文讲解SpringBoot框架的核心特性如快速构建、自动配置、零XML与微服务架构的定义、演进及优缺点,涵盖开发环境准备和HelloWorld实战... 目录一、Spring Boot 核心概述二、微服务架构详解1. 微服务的定义与演进2. 微服务的优缺点三

从入门到精通详解LangChain加载HTML内容的全攻略

《从入门到精通详解LangChain加载HTML内容的全攻略》这篇文章主要为大家详细介绍了如何用LangChain优雅地处理HTML内容,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录引言:当大语言模型遇见html一、HTML加载器为什么需要专门的HTML加载器核心加载器对比表二

从入门到进阶讲解Python自动化Playwright实战指南

《从入门到进阶讲解Python自动化Playwright实战指南》Playwright是针对Python语言的纯自动化工具,它可以通过单个API自动执行Chromium,Firefox和WebKit... 目录Playwright 简介核心优势安装步骤观点与案例结合Playwright 核心功能从零开始学习

从入门到精通MySQL联合查询

《从入门到精通MySQL联合查询》:本文主要介绍从入门到精通MySQL联合查询,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下... 目录摘要1. 多表联合查询时mysql内部原理2. 内连接3. 外连接4. 自连接5. 子查询6. 合并查询7. 插入查询结果摘要前面我们学习了数据库设计时要满

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

从入门到精通MySQL 数据库索引(实战案例)

《从入门到精通MySQL数据库索引(实战案例)》索引是数据库的目录,提升查询速度,主要类型包括BTree、Hash、全文、空间索引,需根据场景选择,建议用于高频查询、关联字段、排序等,避免重复率高或... 目录一、索引是什么?能干嘛?核心作用:二、索引的 4 种主要类型(附通俗例子)1. BTree 索引(

Redis 配置文件使用建议redis.conf 从入门到实战

《Redis配置文件使用建议redis.conf从入门到实战》Redis配置方式包括配置文件、命令行参数、运行时CONFIG命令,支持动态修改参数及持久化,常用项涉及端口、绑定、内存策略等,版本8... 目录一、Redis.conf 是什么?二、命令行方式传参(适用于测试)三、运行时动态修改配置(不重启服务

MySQL DQL从入门到精通

《MySQLDQL从入门到精通》通过DQL,我们可以从数据库中检索出所需的数据,进行各种复杂的数据分析和处理,本文将深入探讨MySQLDQL的各个方面,帮助你全面掌握这一重要技能,感兴趣的朋友跟随小... 目录一、DQL 基础:SELECT 语句入门二、数据过滤:WHERE 子句的使用三、结果排序:ORDE