0


WebGL系列教程二(环境搭建及着色器初始化)

快速导航(持续更新中)

WebGL系列教程一(开篇)
WebGL系列教程二(环境搭建及着色器初始化)
WebGL系列教程三(使用缓冲区绘制三角形)
WebGL系列教程四(绘制彩色三角形)
WebGL系列教程五(使用索引绘制彩色立方体)
WebGL系列教程六(纹理映射与立方体贴图)
WebGL系列教程七(二维及三维旋转、平移、缩放)
WebGL系列教程八(GLSL着色器基础语法)
WebGL系列教程九(动画)
WebGL系列教程十(模型Model、视图View、投影Projection变换)
WebGL系列教程十一(光照原理及Blinn Phong着色模型)

目录

1 前言

  上一篇中我们对

WebGL

进行了简单的介绍,从本篇开始,正式进入实战。那么我们第一步需要做什么呢?当然是环境的搭建,以及

Shader

的初始化。废话不多说,咱们直接开整。

2 新建html页面

  其实搭建

WebGL

的环境十分简单,因为

WebGL

在在浏览里运行的,因此只需要新建一个

html

页面就行了。

3 着色器介绍

3.1 顶点着色器、片元着色器与光栅化的概念

  那么什么是顶点着色器?什么是片元着色器?什么叫做光栅化?这三个概念对我们学习

WebGL

还是很重要的,在学习

WebGL

的过程中,我曾经常困惑于片元、光栅化的概念,现在我们就用一张图来解释下。假设我们要在屏幕上画一个三角形。
在这里插入图片描述
  如图所示,

v1 v2 v3

就叫做顶点,三角形内部的一个个红色的点,就叫做片元,也叫片段,其实它的意思就是一个个像素。注意像素应该是密密麻麻占满了整个三角形,这里为了示意只画出来了少部分。屏幕是什么?屏幕是一种光栅设备,因此把任何一种图形,不论是二维三维的,画在屏幕上,就叫做光栅化。光栅化的概念就这么简单。看过很多其他教程,只说光栅化,不说光栅化是什么意思,很令人困惑。

3.2 声明顶点着色器

  声明顶点着色器很简单,只需要写一个

script

标签,注意

type
<script id="vertex-shader" type="x-shader/x-vertex"></script>

3.3 声明片元着色器

  声明片元着色器也很简单,只需要写一个

script

标签,同样注意

type
<script id="vertex-shader" type="x-shader/x-fragment"></script>

4 坐标系(右手系)介绍

  现在我们来做一个最简单的例子,画一个点,这个点的坐标分别是

x=0.5,y=0.5,z=0

。在此之前我们先明确一下

WebGL

中的坐标系:

X轴向右,Y轴向上,Z轴向外

。右手握拳,四指从

X

Y

转动,大拇指的方向就是

Z

轴的方向。很明显,

WebGL

中默认是右手系。因为

z=0

,因此这个点在

xy

所形成的平面内。
在这里插入图片描述

5 着色器初始化

  初始化着色也很简单,我们先给出步骤,然后一步步来说明

  1. 创建着色器对象
  2. 获取着色器对象的源代码
  3. 绑定着色器的源
  4. 编译着色器
  5. 创建并关联项目

5.1 给一个画布canvas

<canvasid="canvas"width="1080"height="720"></canvas>

5.2 获取WebGL对象

const canvas = document.getElementById("canvas");const gl = canvas.getContext("webgl");

5.3 创建着色器对象

//创建着色器对象let vertexShader = gl.createShader(gl.VERTEX_SHADER);let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);

5.4 获取着色器对象的源

//获取着色器对象的源let vertexSource = document.getElementById("vertex-shader").innerText;let fragmentSource = document.getElementById("fragment-shader").innerText;

因为这里我们要用的innerText,也就是script标签里的文本,因此也可以不把文本写在script标签里,而是直接手写字符串,这样的不好处就是没有智能提示,比如:
let vertexSource = “…”
let fragmentSource = “…”

5.5 绑定着色器的源

//绑定着色器的源
gl.shaderSource(vertexShader,vertexSource);
gl.shaderSource(fragmentShader,fragmentSource);

5.6 编译着色器

//编译着色器
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);

5.7 创建并关联项目

//创建并关联项目let program = gl.createProgram();
gl.attachShader(program,vertexShader);
gl.attachShader(program,fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);

6 绘制

  现在我们的准备工作已经完事了,可以开始绘制了。首先需要补齐

script

标签的内容

6.1 声明点的位置、大小和颜色

<scriptid="vertex-shader"type="x-shader/x-vertex">//声明一个点,vec2表示2维向量
    attribute vec2 aPos;voidmain(){//点的大小10像素
        gl_PointSize =10.0;//点的位置,将vec2补齐为vec4
        gl_Position =vec4(aPos,0.0,1.0);}</script><scriptid="fragment-shader"type="x-shader/x-fragment">voidmain(){//点的颜色,rgba形式,红色
        gl_FragColor =vec4(1.0,0.0,0.0,1.0);}</script>

6.2 绘制

//绘制let aPos = gl.getAttribLocation(program,"aPos");//设置顶点的值,该顶点是用二维坐标表示的,vertexAttrib2f表示vertex中的attribute属性,2个float值
gl.vertexAttrib2f(aPos,0.5,0.5);//绘制点,从第0个点开始,绘制两个
gl.drawArrays(gl.POINTS,0,2);

在这里插入图片描述
改为x=0,y=0看看效果,点回到了正中间。
在这里插入图片描述

6.3 完整代码

<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Document</title><style>#canvas{border: 1px solid #ccc;}</style></head><body><canvasid="canvas"width="1080"height="720"></canvas><scriptid="vertex-shader"type="x-shader/x-vertex">
        attribute vec2 aPos;voidmain(){
            gl_PointSize =10.0;
            gl_Position =vec4(aPos,0.0,1.0);//gl_Position = aPos;   }</script><scriptid="fragment-shader"type="x-shader/x-fragment">voidmain(){
            gl_FragColor =vec4(1.0,0.0,0.0,1.0);}</script><script>const canvas = document.getElementById("canvas");const gl = canvas.getContext("webgl");//创建着色器对象let vertexShader = gl.createShader(gl.VERTEX_SHADER);let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);//获取着色器对象的源let vertexSource = document.getElementById("vertex-shader").innerText;let fragmentSource = document.getElementById("fragment-shader").innerText;//绑定着色器的源
        gl.shaderSource(vertexShader,vertexSource);
        gl.shaderSource(fragmentShader,fragmentSource);//编译着色器
        gl.compileShader(vertexShader);
        gl.compileShader(fragmentShader);
        console.log(gl.getShaderInfoLog(vertexShader));//创建并关联项目let program = gl.createProgram();
        gl.attachShader(program,vertexShader);
        gl.attachShader(program,fragmentShader);
        gl.linkProgram(program);
        gl.useProgram(program);//绘制let aPos = gl.getAttribLocation(program,"aPos");//设置顶点的值,该顶点是用二维坐标表示的
        gl.vertexAttrib2f(aPos,0.0,0.0);
        gl.drawArrays(gl.POINTS,0,2);</script></body></html>

7 总结

  本篇博文中我们梳理了WebGL中整个的绘制流程,右手坐标系的指向,顶点着色器、片元着色器、光栅化等概念的含义,并以一个最简单的示例,点绘制来演示

Shader

的初始化过程,代码并不复杂,希望读者仔细体会,回见~


本文转载自: https://blog.csdn.net/xiangshangdemayi/article/details/142007006
版权归原作者 AIGIS. 所有, 如有侵权,请联系我们删除。

“WebGL系列教程二(环境搭建及着色器初始化)”的评论:

还没有评论