webgl 着色器

webgl 绘图需要两种着色器:
  • 顶点着色器(Vertex shader):描述顶点的特征,如位置、颜色等。
  • 片元着色器(Fragment shader):进行逐片元处理,如光照。
webgl 的着色器语言是GLSL ES语言
片元着色程序,要写在type=“x-shader/x-fragment” 的script中。
<script id="fragmentShader" type="x-shader/x-fragment">
    void main() {
        gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
    }
</script>
void main() {…… } 是主体函数。

在顶点着色器中,gl_Position 是顶点的位置,gl_PointSize 是顶点的尺寸,这种名称都是固定的,不能写成别的。

在片元着色器中,gl_FragColor 是片元的颜色。

vec4()  是一个4维矢量对象。

将vec4() 赋值给顶点点位gl_Position 的时候,其中的前三个参数是x、y、z,第4个参数默认1.0,其含义我们后面会详解;

将vec4() 赋值给片元颜色gl_FragColor 的时候,其中的参数是r,g,b,a。

至于GLSL ES语言的其它知识,咱们会在后面另开一篇详解,这里先以入门为主。
着色器初始化
1. 建立程序对象,目前这只是一个手绘板的外壳。
const shaderProgram = gl.createProgram();
2. 建立顶点着色器对象和片元着色器对象,这是手绘板里用于接收触控笔信号的零部件,二者可以分工合作,把触控笔的压感(js信号)解析为计算机语言(GLSL ES),然后让计算机(浏览器的webgl 渲染引擎)识别显示。
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
   const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
3. 将顶点着色器对象和片元着色器对象装进程序对象中,这就完成的手绘板的拼装。
  gl.attachShader(shaderProgram, vertexShader);
   gl.attachShader(shaderProgram, fragmentShader);
4. 连接webgl 上下文对象和程序对象,就像连接触控笔和手绘板一样(触控笔里有传感器,可以向手绘板发送信号)。
gl.linkProgram(shaderProgram);
5. 启动程序对象,就像按下了手绘板的启动按钮,使其开始工作。
gl.useProgram(program);
在以后的学习里,initShaders 会经常用到,所以我们可以将其模块化。
function initShaders(gl,vsSource,fsSource){
    //创建程序对象
    const program = gl.createProgram();
    //建立着色对象
    const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
    const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
    //把顶点着色对象装进程序对象中
    gl.attachShader(program, vertexShader);
    //把片元着色对象装进程序对象中
    gl.attachShader(program, fragmentShader);
    //连接webgl上下文对象和程序对象
    gl.linkProgram(program);
    //启动程序对象
    gl.useProgram(program);
    //将程序对象挂到上下文对象上
    gl.program = program;
    return true;
}
function loadShader(gl, type, source) {
    //根据着色类型,建立着色器对象
    const shader = gl.createShader(type);
    //将着色器源文件传入着色器对象中
    gl.shaderSource(shader, source);
    //编译着色器对象
    gl.compileShader(shader);
    //返回着色器对象
    return shader;
}
export {initShaders}
后面在需要的时候,import 引入即可。

```js
import {initShaders} from '../jsm/Utils.js';
```

【定义着色器字符串】
顶点着色器有二个固定的属性gl_Position和gl_PointSize,分别表示位置和尺寸:

<!-- 顶点着色器 -->
<script type='x-shader/x-vertex' id='vs-shader'>
    void main(){
        gl_Position=vec4(0.0,0.0,0.0,1.0);
        gl_PointSize=100.0;
    }
</script>

片段着色器有一个固定的属性gl_FragColor表示颜色:

<!-- 片段着色器 -->
<script type='x-shader/x-fragment' id='fs-shader'>
    void main(){
        gl_FragColor=vec4(1.0,1.0,0.0,1.0);
    }
</script>
<!DOCTYPE html>
<html>
 
<head>
    <!-- 顶点着色器 -->
    <script type='x-shader/x-vertex' id='shader-vs'>
        void main(){
            gl_Position=vec4(0.0,0.0,0.0,1.0);
            gl_PointSize=100.0;
        }
    </script>
    <!-- 片段着色器 -->
    <script type='x-shader/x-fragment' id='shader-fs'>
        void main(){
            gl_FragColor=vec4(1.0,1.0,0.0,1.0);
        }
    </script>
</head>
 
<body>
    <canvas id='webgl' width='400' height='400'></canvas>
</body>
<script>
 
    // 1.获取webgl
    var canvas = document.getElementById('webgl');
    var gl = canvas.getContext('webgl');
 
    // 2.清空屏幕
    gl.clearColor(0.5, 0.5, 0.5, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
 
    // 3.初始化着色器
    var vs_source = document.getElementById('shader-vs').innerHTML,
        fs_source = document.getElementById('shader-fs').innerHTML;
 
    // 创建顶点着色器对象
    var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    // 绑定资源
    gl.shaderSource(vertexShader, vs_source);
    // 编译着色器
    gl.compileShader(vertexShader);
 
    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fs_source);
    gl.compileShader(fragmentShader);
 
    // 创建一个着色器程序
    var glProgram = gl.createProgram();
 
    // 把前面创建的二个着色器对象添加到着色器程序中
    gl.attachShader(glProgram, vertexShader);
    gl.attachShader(glProgram, fragmentShader);
 
    // 把着色器程序链接成一个完整的程序
    gl.linkProgram(glProgram);
 
    // 使用这个完整的程序
    gl.useProgram(glProgram);
 
    // 4.绘制一个点
    gl.drawArrays(gl.POINTS, 0, 1);
 
</script>
 
</html>
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值