几个简单的小例子手把手带你入门webgl(一)

简介: 各位同学们大家好,又到了周末写文章的时间,之前群里有粉丝提问, 就是shader不是很理解。然后今天他就来了, 废话不多说,读完今天的这篇文章你可以学到以下几点:为什么需要有shader ? shader的作用是什么????shader 中的每个参数到底是什么意思??怎么去用???你如果会了,这篇文章你可以不用看👀,不用浪费时间,去看别的文章。如果哪里写的有问题欢迎大家指正,我也在不断地学习当中。why need shader这里我结合自己的思考🤔,讲讲webgl的整个的一个渲染过程。渲染管线「Webgl」的渲染依赖底层「GPU」的渲染能力。所以「WEBGL」 渲染流程

各位同学们大家好,又到了周末写文章的时间,之前群里有粉丝提问, 就是shader不是很理解。然后今天他就来了, 废话不多说,读完今天的这篇文章你可以学到以下几点:

  1. 为什么需要有shader ? shader的作用是什么????
  2. shader 中的每个参数到底是什么意思??怎么去用???

你如果会了,这篇文章你可以不用看👀,不用浪费时间,去看别的文章。如果哪里写的有问题欢迎大家指正,我也在不断地学习当中。

why need shader



这里我结合自己的思考🤔,讲讲webgl的整个的一个渲染过程。


渲染管线


「Webgl」的渲染依赖底层「GPU」的渲染能力。所以「WEBGL」 渲染流程和 「GPU」 内部的渲染管线是相符的。


「渲染管线的作用是将3D模型转换为2维图像。」


在早期,渲染管线是不可编程的,叫做「固定渲染管线」,工作的细节流程已经固定,修改的话需要调整一些参数。


现代的 「GPU」 所包含的渲染管线为「可编程渲染管线」,可以通过编程 「GLSL 着色器语言」 来控制一些渲染阶段的细节。


简单来说:就是使用「shader」,我们可以对画布中「每个像素点做处理」,然后就可以生成各种酷炫的效果了。


渲染过程



渲染过程大概经历了下面这么多过程, 因为本篇文章的重点其实是在着色器,所以我重点分析从「顶点着色器」—— 「片元着色器」的一个过程


  • 「顶点着色器」


  • 「图片装配」


  • 「光栅化」


  • 「片元着色器」


  • 「逐片段操作(本文不会分享此内容)」


  • 「裁剪测试」


  • 「多重采样操作」


  • 「背面剔除」


  • 「模板测试」


  • 「深度测试」


  • 「融合」


  • 「缓存」


顶点着色器


WebGL就是和GPU打交道,在GPU上运行的代码是一对着色器,一个是顶点着色器,另一个是片元着色器。每次调用着色程序都会先执行顶点着色器,再执行片元着色器。

一个顶点着色器的工作是生成裁剪空间坐标值,通常是以下的形式:


const vertexShaderSource = `
    attribute vec3 position; 
    void main() {
        gl_Position = vec4(position,1); 
    }
`


每个顶点调用一次(顶点)着色器,每次调用都需要设置一个特殊的全局变量 「gl_Position」。该变量的值就是裁减空间坐标值。这里有同学就问了, 什么是「裁剪空间的坐标值」???


其实我之前有讲过,我在讲一遍。


何为裁剪空间坐标?就是无论你的画布有多大,裁剪坐标的坐标范围永远是 -1 到 1 。

看下面这张图:

image.png

image.gif裁剪坐标系


如果运行一次顶点着色器, 那么gl_Position  就是**(-0.5,-0.5,0,1)** 记住他永远是个 「Vec4」,  简单理解就是对应「x、y、z、w」。即使你没用其他的,也要设置默认值, 这就是所谓的 3维模型转换到我们屏幕中。


顶点着色器需要的数据,可以通过以下四种方式获得。


  1. attributes 属性(从缓冲读取数据)


  1. uniforms 全局变量 (一般用来对物体做整体变化、 旋转、缩放)


  1. textures 纹理(从像素或者纹理获得数据)


  1. varyings 变量  (将顶点着色器的变量 传给 片元着色器)


Attributes 属性


属性可以用 float, vec2, vec3, vec4, mat2, mat3mat4 数据类型

所以它内建的数据类型例如vec2, vec3vec4分别代表两个值,三个值和四个值, 类似的还有mat2, mat3mat4 分别代表 2x2, 3x3 和 4x4 矩阵。你可以做一些运算例如常量和矢量的乘法。看几个例子吧:


vec4 a = vec4(1, 2, 3, 4);
vec4 b = a * 2.0;
// b 现在是 vec4(2, 4, 6, 8);


向量乘法 和矩阵乘法 :


mat4 a = ???
mat4 b = ???
mat4 c = a * b;
vec4 v = ???
vec4 y = c * v;


它还支持矢量「调制」,意味者你可以交换或重复分量。


v.yyyy  ===  vec4(y, y, y,y )
v.bgra  ===  vec4(v.b,v.g,v.r,v.a)
vec4(v.rgb, 1) ===  vec4(v.r, v.g, v.b, 1) 
vec4(1) === vec4(1, 1, 1, 1)


这样你在处理图片的时候可以轻松进「行 颜色通道 对调」, 发现你可以实现各种各样的滤镜了。


后面的属性在下面实战中会讲解:我们接着往下走:


图元装配和光栅化


「什么是图元?」


「描述各种图形元素的函数叫做图元,描述几何元素的称为几何图元(点,线段或多边形)。点和线是最简单的几何图元」经过顶点着色器计算之后的坐标会被组装成「组合图元」


「通俗解释」「图元就是一个点、一条线段、或者是一个多边形。」


「什么是图元装配呢?」


「简单理解就是说将我们设置的顶点、颜色、纹理等内容组装称为一个可渲染的多边形的过程。」


组装的类型取决于:你最后绘制选择的图形类型


gl.drawArrays(gl.TRIANGLES, 0, 3)


「如果是三角形的话,顶点着色器就执行三次」


光栅化


「什么是光栅化:」


通过图元装配生成的多边形,计算像素并填充,「剔除」不可见的部分,「剪裁」掉不在可视范围内的部分。最终生成可见的带有颜色数据的图形并绘制。


「光栅化流程图解:」


image.png

光珊化图解


剔除和剪裁


  • 「剔除」
    在日常生活中,对于不透明物体,背面对于观察者来说是不可见的。同样,在「webgl」中,我们也可以设定物体的背面不可见,那么在渲染过程中,就会将不可见的部分剔除,不参与绘制。节省渲染开销。


  • 「剪裁」
    日常生活中不论是在看电视还是观察物体,都会有一个可视范围,在可视范围之外的事物我们是看不到的。类似的,图形生成后,有的部分可能位于可视范围之外,这一部分会被剪裁掉,不参与绘制。以此来提高性能。这个就是「视椎体」, 在📷范围内能看到的东西,才进行绘制。


片元着色器


「光珊化后,每一个像素点都包含了 颜色 、深度 、纹理数据, 这个我们叫做片元」


小tips :每个像素的颜色由片元着色器的「gl_FragColor」提供


接收光栅化阶段生成的片元,在光栅化阶段中,已经计算出每个片元的颜色信息,这一阶段会将片元做逐片元挑选的操作,处理过的片元会继续向后面的阶段传递。「片元着色器运行的次数由图形有多少个片元决定的」


「逐片元挑选」


通过模板测试和深度测试来确定片元是否要显示,测试过程中会丢弃掉部分无用的片元内容,然后生成可绘制的二维图像绘制并显示。


  • **深度测试:**就是对 「z」 轴的值做测试,值比较小的片元内容会覆盖值比较大的。(类似于近处的物体会遮挡远处物体)。


  • **模板测试:**模拟观察者的观察行为,可以接为镜像观察。标记所有镜像中出现的片元,最后只绘制有标记的内容。


相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
相关文章
|
11月前
|
前端开发 JavaScript
Threejs入门进阶实战案例(3):视频贴图的解决方案
Threejs入门进阶实战案例(3):视频贴图的解决方案
257 0
|
11月前
|
搜索推荐 定位技术
SWMM从入门到实践教程 02 快速入门案例的绘制
SWMM从入门到实践教程 02 快速入门案例的绘制
|
前端开发 定位技术
从零开始手把手教你使用javascript+canvas开发一个塔防游戏01地图创建
从零开始手把手教你使用javascript+canvas开发一个塔防游戏01地图创建
124 0
从零开始手把手教你使用javascript+canvas开发一个塔防游戏01地图创建
|
移动开发 数据可视化 JavaScript
谈一谈|小白如何使用egret
谈一谈|小白如何使用egret
174 0
游戏开发零基础入门教程(1):先对游戏有个概念
首先回答第一个问题,是的,学完这个教程后,你能够做出自己的游戏。这里,有一点儿地方需要澄清一下,“做出来”跟“能够做出来”是完全不同的,“做出来”是既定的事实,去做了,并且做出来了。而“能够做出来”只是一种想象,前提是要先“去做”。
223 0
游戏开发应该怎么学?如何入门?最好的方法是什么?
我遇到很多的想要学习做游戏,但是最终因为各种各样的原因半途而废的人,“半途而废”并不是一件多么稀奇的事,大概我们每个人都是“半途而废”的专家。但是,投入一定的时间和精力,最终却没有学成,会让人有很强的挫败感。如果再三尝试,都没有学成的话,那么这种挫败感是足以让一个人彻底放弃的。
147 0
|
安全
游戏开发零基础入门教程(12):从想法到设计的过程
一个游戏通常开始于一个想法,这个想法可以是千奇百怪的,可以是五花八门的,甚至可以是可笑的。不论如何有一个想法,是一个游戏的开端。当你有了一个想法了以后,如果你希望它最终能够变成一个真正的游戏,那么你就必须要继续往前走,反复的思考,雕琢你的粗糙的想法,将它细化,形成一份具体的可行的游戏设计方案。
95 0
|
移动开发 前端开发 JavaScript
通过游戏学javascript系列第一节Canvas游戏开发基础
通过游戏学javascript系列第一节Canvas游戏开发基础
119 0
|
存储 缓存 前端开发
几个简单的小例子手把手带你入门webgl(二)
实战——绘制个三角形 在进行实战之前,我们先给你看一张图,让你能大概了解,用原生webgl生成一个三角形需要那些步骤: draw 我们就跟着这个流程图一步一步去操作: 初始化canvas 新建一个webgl画布 <canvas id="webgl" width="500" height="500"></canvas> 创建webgl 上下文: const gl = document.getElementById('webgl').getContext('webgl') 创建着色器程序 着色器的程序这些代码,其实是重复的,我们还是先看下图,看下我们到底需要哪些步骤: shader 那我们就跟着这
几个简单的小例子手把手带你入门webgl(二)
|
Web App开发 移动开发 前端开发
①万字《详解canvas api画图》小白前端入门教程(建议收藏)
①万字《详解canvas api画图》小白前端入门教程(建议收藏)
①万字《详解canvas api画图》小白前端入门教程(建议收藏)