找回密码
 立即注册
查看: 452|回复: 11

如何理解 OpenGL 中着色器、渲染管线、光栅化等概念?

[复制链接]
发表于 2022-1-4 16:24 | 显示全部楼层 |阅读模式
您可以参考:
Graphics Pipeline或者
图形处理器架构(GPU Architecture)与图形管线(Graphics Pipeline)入门里的PDF。或者我试着用简单直白的话语为您解释一遍,或许专业性不强,如果能帮到您理解也不错。
您提到的这几个词语,都和渲染管线相关,渲染管线的英文pipeline,可能翻译成渲染流水线更好。您可以将其当成一个函数,函数内的实现又分为多个模块。
pipeline(param)
{
  param_a = function_a(param);
  param_b = function_b(param_a);
  ......
  return param_x;
}
你可以把以上这个函数画成流程图,实际上dx的手册里就是画流程图了。有输入,中间有很多模块按顺序处理最后输出,你可以把渲染管线的输出当成一个颜色的二维数组,返回给显示器。
而其中的着色器 光栅化就是其中 function_xx内部使用到的实现细节,有时候我们使用这些名词来表示function_xx这个结构本身。
对于图形 api的使用者来说,为了能正确显示图像,往往要对整个pipeline的过程,顺序有了解。一简单流程如下:
管线程序段输入=>顶点着色器=>光栅化=>像素着色器=>屏幕颜色
(上一个函数的)输出  传递给=> (下一个函数作为)输入
下面简单举例过程帮助您理解:
使用opengl时,我们需要提供vertex buffer object    index buffer object (vertex element array),也就是模型数据。您可以把这个模型数据当做pipeline的输入param。接下来就开始了管线内部流程。
您输入的模型数据,会把顶点数组(vbo)中的每个点拆开,单独一个点当做参数输入到顶点着色器里,你可以把顶点着色器看成一个叫做vertex_shader()的函数,把整个过程想象成
for_each(v in vbo){  vertex_shader(v);  },或者一个多线程处理。
处理完后,你的顶点会附着上一些通用信息,比如纹理uv之类的,你可以把一个顶点当做一个struct;管线会根据vbo ibo 拼成多个三角形,把这些三角形送入光栅化过程,三角形会被打散成一个个的小像素。
这些像素会呗当做参数传入像素着色器,过程和顶点着色器类似。
对于可编程管线来说,vertexshader pixelshader(opengl里叫fragment shader 片段着色器)这两个函数,也需要在渲染前通过api设置好,你可以想象成在把你的函数安装到显卡上处理着色器的模块里去。
这个流程的模块,是会随着版本升级而有一些变化的。对于opengl来说,早期固定管线的内容,国内能接触到的教程,更多强调的是每个模块如何使用,怎么调用api,而忽略了管线模块的顺序这些说明,同时读者也会忽略管线模块输入输出这些令人困扰的内容。
可编程管线的教程又略微有点滞后。比起使用directx的初学者来说,可能对管线的概念更模糊一些。
directx在帮助手册里就能看到每个版本的管线内容。opengl现在文档已经慢慢完善,您可以看看官网上的手册和wiki。
您说的 着色器属于可编程管线的内容。对于可编程管线的内容,还是好好了解整个管线的内容再动手使用api比较好。每个具体的内容,楼上各位大神已经描述得很详细了。
手机排版感人,希望对您有帮助。
发表于 2022-1-4 16:29 | 显示全部楼层
您可以参考:
Graphics Pipeline或者
图形处理器架构(GPU Architecture)与图形管线(Graphics Pipeline)入门里的PDF。或者我试着用简单直白的话语为您解释一遍,或许专业性不强,如果能帮到您理解也不错。
您提到的这几个词语,都和渲染管线相关,渲染管线的英文pipeline,可能翻译成渲染流水线更好。您可以将其当成一个函数,函数内的实现又分为多个模块。
pipeline(param)
{
  param_a = function_a(param);
  param_b = function_b(param_a);
  ......
  return param_x;
}
你可以把以上这个函数画成流程图,实际上dx的手册里就是画流程图了。有输入,中间有很多模块按顺序处理最后输出,你可以把渲染管线的输出当成一个颜色的二维数组,返回给显示器。
而其中的着色器 光栅化就是其中 function_xx内部使用到的实现细节,有时候我们使用这些名词来表示function_xx这个结构本身。
对于图形 api的使用者来说,为了能正确显示图像,往往要对整个pipeline的过程,顺序有了解。一简单流程如下:
管线程序段输入=>顶点着色器=>光栅化=>像素着色器=>屏幕颜色
(上一个函数的)输出  传递给=> (下一个函数作为)输入
下面简单举例过程帮助您理解:
使用opengl时,我们需要提供vertex buffer object    index buffer object (vertex element array),也就是模型数据。您可以把这个模型数据当做pipeline的输入param。接下来就开始了管线内部流程。
您输入的模型数据,会把顶点数组(vbo)中的每个点拆开,单独一个点当做参数输入到顶点着色器里,你可以把顶点着色器看成一个叫做vertex_shader()的函数,把整个过程想象成
for_each(v in vbo){  vertex_shader(v);  },或者一个多线程处理。
处理完后,你的顶点会附着上一些通用信息,比如纹理uv之类的,你可以把一个顶点当做一个struct;管线会根据vbo ibo 拼成多个三角形,把这些三角形送入光栅化过程,三角形会被打散成一个个的小像素。
这些像素会呗当做参数传入像素着色器,过程和顶点着色器类似。
对于可编程管线来说,vertexshader pixelshader(opengl里叫fragment shader 片段着色器)这两个函数,也需要在渲染前通过api设置好,你可以想象成在把你的函数安装到显卡上处理着色器的模块里去。
这个流程的模块,是会随着版本升级而有一些变化的。对于opengl来说,早期固定管线的内容,国内能接触到的教程,更多强调的是每个模块如何使用,怎么调用api,而忽略了管线模块的顺序这些说明,同时读者也会忽略管线模块输入输出这些令人困扰的内容。
可编程管线的教程又略微有点滞后。比起使用directx的初学者来说,可能对管线的概念更模糊一些。
directx在帮助手册里就能看到每个版本的管线内容。opengl现在文档已经慢慢完善,您可以看看官网上的手册和wiki。
您说的 着色器属于可编程管线的内容。对于可编程管线的内容,还是好好了解整个管线的内容再动手使用api比较好。每个具体的内容,楼上各位大神已经描述得很详细了。
手机排版感人,希望对您有帮助。
发表于 2022-1-4 16:30 | 显示全部楼层
卧槽,前些日子看这几个概念就十分想吐槽,这么难理解的概念窃以为纯属翻译的不够接地气。
————
首先,光栅化(Rasterize/rasteriztion)。
这个词儿Adobe官方翻译成栅格化或者像素化。没错,就是把矢量图形转化成像素点儿的过程。我们屏幕上显示的画面都是由像素组成,而三维物体都是点线面构成的。要让点线面,变成能在屏幕上显示的像素,就需要Rasterize这个过程。就是从矢量的点线面的描述,变成像素的描述。
如下图,这是一个放大了1200%的屏幕,前面是告诉计算机我有一个圆形,后面就是计算机把圆形转换成可以显示的像素点。这个过程就是Rasterize。


————
渲染管线(Pipeline)
这个翻译尤其不接地气,简直就是直译(pipe管子line线路)。Pipeline是输送管道的意思。其实是指三维渲染的过程中显卡执行的、从几何体到最终渲染图像的、数据传输处理计算的过程。
————
着色器(Shader)
这个翻译的挺好。画画的时候我们经常有这么一个过程:先打线稿,再上色。着色器就是用来做这个工作的。
通常着色器分两种:
1顶点着色器(vertex shader)这个是告诉电脑如何打线稿的——如何处理顶点、法线等的数据的小程序。
2片面着色器(fragment shader)这个是告诉电脑如何上色的——如何处理光、阴影、遮挡、环境等等对物体表面的影响,最终生成一副图像的小程序。
采用了这两种着色器小程序 数据传输处理计算的渲染过程,称之为 可编程管线。
————
以上,希望能让楼主理解这些拗口的概念。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2022-1-4 16:40 | 显示全部楼层
通俗点说,你告诉GL我要画条线,然后告诉他线两个端点的坐标是(0,0)和(0,10),那么GL自动脑补出中间10个点的坐标,这个过程就叫光册化,脑补的方法叫线性差值.
复杂点,现在我要画个三角形,给他三个顶点的坐标,它会计算出里面所有像素的坐标.
再复杂点,我不只给顶点坐标了,我告诉他(0,0)点是白色,(0,10)点是黑色,那么光册化就自动计算出中间10个点每个点的颜色,自动做过渡的效果.这个计算方法还是线性差值.
继续通俗,线性差值也没啥,小学算数罢了,谁都会. 不懂就自己计算如上10个点的坐标,计算过程就是线性差值. 没错,就这么简单.
着色器分两个部分,一个顶点,一个片断,中间就是光册化.
也就是先顶点处理,计算出每个顶点的坐标,颜色,纹理坐标等等,也可以是任何其它千奇百怪的东西(寿命,温度,身高,婚否,饭量………). 然后经过光册化,给他们差值.最后片断阶段,你会获得每个像素的坐标,颜色,纹理,寿命,温度……
初学阶段,你可以把片断(fragment)理解成像素,其实意思差别不大,等你GL入门了,自然就理解这俩词有啥区别了(ps:最讨厌那些拽词的,明明意思差不多,为了自己装逼就非说俩词怎么怎么不一样,一点不考虑初学者的感受)
==========================
额,这段解释有重要错误,有空我再修改………sorry
发表于 2022-1-4 16:43 | 显示全部楼层
我觉得百度百科讲的挺好的,大概意思都讲到了。
光栅化:光栅化_百度百科 (注意看配图)
渲染管线:OpenGL: 渲染管线理论 (这个就不放百科了,废话多)
着色器:着色器_百度百科
百度觉得不好,就 Google。
发表于 2022-1-4 16:51 | 显示全部楼层
直接看代码吧,比较好理解
GitHub - zxx43/Software-Render: 软件渲染器
发表于 2022-1-4 16:59 | 显示全部楼层
整个流程是为了输出图形,屏幕上显示的图形就是每一个像素有不同的颜色,那我们要做的就是设置所有的像素的值。




上面这个东西整个就是渲染管线,他的工作流程就是把顶点数据传入顶点着色器,opengl会装配成图元,变成3D物体,就像第一张图那样中的场景,近截面和远截面中间这个部分就叫做视口,显示的图形就是这部分中的物体,超出的物体会被忽略掉,然后经过投影,归一化等操作(矩阵变换)将图形显示到屏幕上,经过投影变换,然后经过光栅化转变成像素图形,再经过片段着色器给像素染色,最后的测试会决定你同一个位置的物体到底哪一个可以显示在屏幕上以及颜色的混合。你可以看看这篇http://mp.weixin.qq.com/s/NoQRro0RYpN9ddac69aMJg
还有http://learnopengl.com这个还有中文网站
我说错的地方望纠正和指导

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2022-1-4 17:05 | 显示全部楼层
请看如下视频链接 How Real Time Computer Graphics and Rasterization work
发表于 2022-1-4 17:13 | 显示全部楼层
Pipleline 就是 管线,正确无比的翻译
Pipeline transport

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2022-1-4 17:23 | 显示全部楼层
我也是新手,刚刚去看了GPUs - Graphics Processing Units这篇文章,发现很多技术名词是单纯直译过来的,极具“误导性”。
我把该文图形管线部分翻译成一篇博客,可以去看看:渲染管线入门 - CSDN博客
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2025-5-14 15:55 , Processed in 0.139963 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表