Skip to content

Commit

Permalink
Site updated: 2022-04-20 16:30:32
Browse files Browse the repository at this point in the history
  • Loading branch information
lijie67 committed Apr 20, 2022
1 parent d9da26d commit 779d228
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 6 deletions.
8 changes: 4 additions & 4 deletions 2022/03/webgl-shader/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ <h1 class="page-title">
<div class="picture-container">

</div>
<p>不会3D的厨师不是一个好司机,这个时代不卷就只能去开滴滴。 在元宇宙概念的背景下,上级领导也要求做点技术储备,在学习了一段时间3D框架后,也顺便了解下<code>webGL</code>的原理</p>
<p>不会3D的厨师不是一个好司机,这个时代不卷就只能去开滴滴。 在元宇宙概念的背景下,上级领导也要求做点技术储备,在学习了一些常用的Web3D框架(babylonjs,threejs)后, 好奇于它们的底层原理,所以去了解下webGL的知识,本文主要介绍WebGl中着色器的原理</p>
<h2 id="webGL"><a href="#webGL" class="headerlink" title="webGL"></a>webGL</h2><p>webGL其实是一个很底层的图像引擎,主要提供的能力就是接收输入的图形的顶点坐标,程序在GPU中帮你画出图形(光珊化)和上色后输出到浏览器,在GPU运行的程序则是一种OpenGL着色语言(GLGS),一个webGL程序大概是如下步骤、其中最关键的还是着色器部分。</p>
<p><img src="/img/webgl/webgl.png"></p>
<p><img src="https://img10.360buyimg.com/imagetools/jfs/t1/181430/1/23122/47131/625fc3ccE1817f782/68bb2226f2f70419.png"></p>
<p>下面的一些代码基本都会省略api调用部分</p>
<h2 id="着色器"><a href="#着色器" class="headerlink" title="着色器"></a>着色器</h2><p>简单点的说着色器就干两件事:</p>
<ol>
Expand All @@ -114,8 +114,8 @@ <h2 id="画一个三角形"><a href="#画一个三角形" class="headerlink" tit

<h2 id="给片元着色器传值"><a href="#给片元着色器传值" class="headerlink" title="给片元着色器传值"></a>给片元着色器传值</h2><p>前面片元着色器颜色是固定,但在实际程序中,我们可能会给每个三角形设置不同颜色,或者贴图的时候需要传纹理坐标,那么如何传值呢?同样我们需要创建一个buffer,使用关键字<code>varying</code>将数据通过顶点着色器再传到片元着色器,如下代码:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//顶点颜色</span></span><br><span class="line"><span class="keyword">const</span> colors = <span class="built_in">Float32Array</span>([</span><br><span class="line"> <span class="number">0.1</span>, <span class="number">0.0</span> , <span class="number">0.0</span>, <span class="number">0.1</span>, <span class="comment">//red</span></span><br><span class="line"> <span class="number">0.1</span>, <span class="number">1.0</span> , <span class="number">0.1</span>, <span class="number">0.1</span>, <span class="comment">//green</span></span><br><span class="line"> <span class="number">0.1</span>, <span class="number">0.0</span> , <span class="number">0.1</span>, <span class="number">0.1</span>, <span class="comment">//blue</span></span><br><span class="line">])</span><br><span class="line"></span><br><span class="line"><span class="comment">//顶点着色器</span></span><br><span class="line"><span class="keyword">const</span> vsSource = <span class="string">`</span></span><br><span class="line"><span class="string"> //属性值,从缓冲中获取数据</span></span><br><span class="line"><span class="string"> attribute vec4 position;</span></span><br><span class="line"><span class="string"> //缓冲区取color数据</span></span><br><span class="line"><span class="string"> attribute vec4 colors;</span></span><br><span class="line"><span class="string"> //定义varying数据</span></span><br><span class="line"><span class="string"> varying vec4 v_color;</span></span><br><span class="line"><span class="string"> void main(void) &#123;</span></span><br><span class="line"><span class="string"> gl_Position = position;</span></span><br><span class="line"><span class="string"> v_color = colors;</span></span><br><span class="line"><span class="string"> &#125;`</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//片元着色器</span></span><br><span class="line"><span class="keyword">const</span> fsSource = <span class="string">`</span></span><br><span class="line"><span class="string"> varying vec4 v_color;</span></span><br><span class="line"><span class="string"> void main(void) &#123;</span></span><br><span class="line"><span class="string"> gl_FragColor = v_color;</span></span><br><span class="line"><span class="string"> &#125;`</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>从代码上看我们还是用<code>attribute</code>从缓冲区取数据,然后通过<code>varying</code>关键字定义了<code>v_color</code>,在顶点着色器中赋值,最后片元着色器也是通过<code>varying</code> 取到颜色值。我们给三角形三个顶点设置了不同颜色,每个片元的值是由顶点的线性插值得到,所以看到的是下面的渐变的颜色。<br><img src="/img/webGL/11.png"></p>
<h2 id="执行顺序"><a href="#执行顺序" class="headerlink" title="执行顺序"></a>执行顺序</h2><p>根据下图,我们再来梳理下着色器的执行流程,首先在缓冲区中获得数据,顶点着色器根据坐标输出图形(三角形),这一步可以叫做图元装配,确定形状后,我们就知道图形中存在多少片元(像素),每个像素都会调用一次片元着色器进行上色。<br><img src="/img/webGL/2.png"></p>
<p>从代码上看我们还是用<code>attribute</code>从缓冲区取数据,然后通过<code>varying</code>关键字定义了<code>v_color</code>,在顶点着色器中赋值,最后片元着色器也是通过<code>varying</code> 取到颜色值。我们给三角形三个顶点设置了不同颜色,每个片元的值是由顶点的线性插值得到,所以看到的是下面的渐变的颜色。<br><img src="https://img11.360buyimg.com/imagetools/jfs/t1/200339/34/23479/73833/625fc3ccEcdcb7a01/f91e861b1017ed64.png"></p>
<h2 id="执行顺序"><a href="#执行顺序" class="headerlink" title="执行顺序"></a>执行顺序</h2><p>根据下图,我们再来梳理下着色器的执行流程,首先在缓冲区中获得数据,顶点着色器根据坐标输出图形(三角形),这一步可以叫做图元装配,确定形状后,我们就知道图形中存在多少片元(像素),每个像素都会调用一次片元着色器进行上色。<br><img src="https://img11.360buyimg.com/imagetools/jfs/t1/123504/28/27636/997473/625fc3cbE8b406d80/1e2186d5500075e6.png"></p>
<h2 id="顶点索引"><a href="#顶点索引" class="headerlink" title="顶点索引"></a>顶点索引</h2><p>我们知道再复杂的模型的是由三角形的组成的,前面我们画一个平面是使用了两个三角6个顶点来画的,但其实两个三角中其中其实是有两个顶点是重复的,所以我们可以使用<code>gl.drawElemnt</code>来代替<code>gl.drawArrays</code>,前者支持通过索引来指定顶点,这样可以减少我们顶点传输量,一个平面可能就只减少了两个点,但如果图形复杂就减少很多内存了。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">//平面顶点</span></span><br><span class="line"><span class="keyword">const</span> position = [</span><br><span class="line"> -<span class="number">1.0</span>, -<span class="number">1.0</span>, <span class="number">1.0</span> <span class="comment">//顶点0</span></span><br><span class="line"> <span class="number">1.0</span>, -<span class="number">1.0</span>, <span class="number">1.0</span>, <span class="comment">//顶点1</span></span><br><span class="line"> <span class="number">1.0</span>, <span class="number">1.0</span>, <span class="number">1.0</span>, <span class="comment">//顶点2</span></span><br><span class="line"> -<span class="number">1.0</span>, <span class="number">1.0</span>, <span class="number">1.0</span>, <span class="comment">//顶点3</span></span><br><span class="line">]</span><br><span class="line"><span class="comment">//索引指定使用哪个顶点</span></span><br><span class="line"><span class="keyword">const</span> index = [</span><br><span class="line"> <span class="number">0</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">0</span>, <span class="number">2</span>, <span class="number">3</span> <span class="comment">//下标</span></span><br><span class="line"> ]</span><br><span class="line"><span class="comment">//api部分</span></span><br><span class="line">gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index);</span><br><span class="line">gl.drawElements(gl.TRIANGLES, <span class="number">36</span>);</span><br><span class="line"></span><br></pre></td></tr></table></figure>

Expand Down
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ <h1 class="index-title">

<div class="excerpt">

不会3D的厨师不是一个好司机,这个时代不卷就只能去开滴滴。 在元宇宙概念的背景下,上级领导也要求做点技术储备,在学习了一段时间3D框架后,也顺便了解下webGL的原理
webGLwebGL其实是一个很底层的图像引擎,主要提供的能力就是接收输入的图形的顶点坐标,程序在GPU中帮你画出图形(光珊...
不会3D的厨师不是一个好司机,这个时代不卷就只能去开滴滴。 在元宇宙概念的背景下,上级领导也要求做点技术储备,在学习了一些常用的Web3D框架(babylonjs,threejs)后, 好奇于它们的底层原理,所以去了解下webGL的知识,本文主要介绍WebGl中着色器的原理
webGLweb...

</div>
<div class="index-meta">
Expand Down

0 comments on commit 779d228

Please sign in to comment.