WebGL入门课程01-基本概念
[TOC]
一、3D图形学入门
3D坐标系
- 新增了一个坐标轴Z标识深度
网格、多边形和顶点
- 网格是由一个或者多个多边形组成的物体,各个顶点的坐标(x,y,x)定义了多边形在3D空间中的位置。
材质、纹理和光源
- 网格表面可以有一个或者多个位图来决定,这就是通常所说的纹理映射简称纹理
- 大多数的图形系统中,网格表面的特性被统称为材质,材质通常依赖一个或者多个光源来呈现外观效果
变换与矩阵
- 3D网格的形状由顶点位置确定
- 变换包括对渲染模型的缩放、旋转、位移等操作
- 变换通常是由矩阵来操作的
相机、透视、视口和投影
- 相机来定义用户和场景的相对朝向
- 视野尺寸决定了透视关系
- 视口是由浏览器或Canvas元素决定的
- 投影矩阵是将相机空间的3D坐标转换为视口中的2D绘制空间的坐标
着色器
- 为了在最终的图像中渲染模型,精确定义顶点、变换、材质、光源和相机之间的关系和交互。这就用到着色器。
- 着色器通常由高等级的类C语言编写,编译并运行在图形处理单元(GPU)中。当我们编写WebGL程序的时候,必须定义着色器,否则图形不会显示在屏幕上。
二、WebGL概述
WebGL的定义
- 网页上绘制和渲染3D图形的技术
- 内嵌在浏览器
- 多平台运行
- ”Web版的OpenGL“
WebGL的起源
- DirecD和OpenGL
- OpenGL ES以及GLSL ES
WebGL程序的结构
三、第一个WebGL程序
用背景色情况canvas标签的绘图区
操作步骤:
- 获取canvas元素
- 获取WebGL绘制上下文
- 设置背景色
- 清除canvas
关键函数:
clearColor(red,green,blue,alpha);
clear(buffer);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WEBBL第一个小程序</title>
<style>
*{
margin: 0;
padding: 0;
}
#web01{
height: 500px;
width: 800px;
}
</style>
</head>
<body>
<canvas id="web01"></canvas>
<script>
const canvas=document.querySelector('#web01');
const gl=canvas.getContext('webgl');
gl.clearColor(0.0,1.0,1.0,1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
</script>
</body>
</html>
四、着色器
绘制一个点
- WebGL坐标系
操作步骤:
- 获取canvas元素
- 获取WebGL绘制上下文
- 初始化着色器
- 定义顶点着色器:描述顶点的特性
- 定义片元着色器:今夕足片逐片处理过程
- 初始化着色器
- 设置背景色
- 清除canvas
- 绘图
drawArray()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{
margin: 0;
padding: 0;
}
#web02{
width: 750px;
height: 500px;
}
</style>
</head>
<body>
<canvas id="web02"></canvas>
<script>
let canvas=document.querySelector("#web02");
let gl=canvas.getContext('webgl');
let VERTEX_SHADER=''+
'void main(){'+
'gl_Position=vec4(0.0,-0.5,1.0,1.0);'+
'gl_PointSize=20.0;'+
'}';
let FRAG_SHADER=''+
'void main(){'+
'gl_FragColor=vec4(1.0,0.3,0.0,1.0);'+
'}';
let vertex=gl.createShader(gl.VERTEX_SHADER);
let frag=gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertex,VERTEX_SHADER);
gl.shaderSource(frag,FRAG_SHADER);
gl.compileShader(vertex);
gl.compileShader(frag);
let program=gl.createProgram();
gl.attachShader(program,vertex);
gl.attachShader(program,frag);
gl.linkProgram(program);
gl.useProgram(program);
gl.clearColor(0.0,0.0,0.0,1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS,0,1);
</script>
</body>
</html>
五、Attrbute、Uniform变量
使用attribute绘制一个点
- attribute变量传输的是与顶点相关的数据
- 主要操作步骤:
- 在顶点着色器中声明attribute变量
- 将attribute变量赋值给JS变量
- 向attribute变量传输数据
- 关键函数:
getAttributeLocation(program,'a_pas');
vertexAttribute4f(location,v1,v2,v3,v4);
使用uniform改变点的颜色
- uniform传输的是对于所有点都相同的数据
- 主要操作步骤:
- 在片元着色器中声明uniform变量
- 获取uniform变量存储位置复制给JS变量
- 向uniform变量传入数据
- 关键函数:
getUniformLocation(program,'u_color');
uniform4f(location,v1,v2,v3,v4);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>L03-使用属性绘制点</title>
<style>
#web03{
height: 500px;
width: 500px;
}
</style>
</head>
<body>
<canvas id="web03"></canvas>
<script>
let canvas=document.querySelector("#web03");
let gl=canvas.getContext('webgl');
let VERTEX_SHADER='' +
'attribute vec4 a_pos;' +
'void main(){' +
'gl_Position=a_pos;' +
'gl_PointSize=25.0;' +
'}';
let FRAG_SHADER='' +
'precision lowp float;' +
'uniform vec4 u_color;' +
'void main(){' +
'gl_FragColor=u_color;' +
'}';
let vertex=gl.createShader(gl.VERTEX_SHADER);
let frag=gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertex,VERTEX_SHADER);
gl.shaderSource(frag,FRAG_SHADER);
gl.compileShader(vertex);
gl.compileShader(frag);
let program=gl.createProgram();
gl.attachShader(program,vertex);
gl.attachShader(program,frag);
gl.linkProgram(program);
gl.useProgram(program);
gl.clearColor(0.0,0.1,0.0,1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
let a_position=gl.getAttribLocation(program,'a_pos');
let u_color=gl.getUniformLocation(program,'u_color');
gl.vertexAttrib4f(a_position,0.0,0.3,1.0,1.0);
gl.uniform4f(u_color,0.0,1.0,0.0,1.0);
gl.drawArrays(gl.POINTS,0,1);
</script>
</body>
</html>