1、顶点着色器
描述顶点特性(位置、颜色等),控制点的位置和大小。
/**
* 顶点着色器
* gl_Position 常量 代表是位置 vec4 一个函数 返回一个vec4类型的数据
* g1_PointSize 常量 代表是尺寸 float类型
* @type {string}
*/
const VSHADER_SOURCE = 'void main() { ' +
'gl_Position = vec4(0.0,0.0,0.0,1.0);' +
'gl_PointSize = 10.0;' +
'}';
2、片元着色器
描述每个像素处理过程,片元可以理解为像素,控制点的颜色。
/**
* 片元着色器
* gl_FragColor 常量 代表颜色 类型为vec4
* @type {string}
*/
const FSHADER_SOURCE =
'void main() {' +
'gl_FragColor = vec4(1.0,0.1,0.1,1.0);' +
'}';
3、着色器初始化(地址)
过程为
创建着色器对象 --》创建着色器程序对象--》添加片段或者顶点着色器--》链接着色器程序对象--》添加着色器对象到渲染状态--》赋值gl.program
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webGl</title>
<style>
body {
margin: 0px;
}
</style>
</head>
<body onload="main()">
<canvas id="webGl" width="900px" height="900px" style="width: 900px;height: 900px;"></canvas>
<script>
/**
* 顶点着色器
* gl_Position 常量 代表是位置 vec4 一个函数 返回一个vec4类型的数据
* g1_PointSize 常量 代表是尺寸 float类型
* @type {string}
*/
const VSHADER_SOURCE = 'void main() { ' +
'gl_Position = vec4(0.0,0.0,0.0,1.0);' +
'gl_PointSize = 10.0;' +
'}';
/**
* 片元着色器
* gl_FragColor 常量 代表颜色 类型为vec4
* @type {string}
*/
const FSHADER_SOURCE =
'void main() {' +
'gl_FragColor = vec4(1.0,0.1,0.1,1.0);' +
'}';
function main() {
const canvas = document.getElementById('webGl');
// Get the rendering context for WebGL
const gl = canvas.getContext('experimental-webgl ') || canvas.getContext('webgl');
if (!gl) {
console.log('不支持webGl 请使用谷歌浏览器查看!');
return;
}
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('着色器初始化失败!');
return;
}
// 清理颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 清空canvas
gl.clear(gl.COLOR_BUFFER_BIT);
// 绘制一个点
gl.drawArrays(gl.POINTS, 0, 1);
}
/**
* 初始化着色器
* @param gl
* @param vshader
* @param fshader
* @returns {*}
*/
function initShaders(gl, vshader, fshader) {
const program = createProgram(gl, vshader, fshader);
if (!program) {
console.log('创建WebGLProgram程序失败');
return false;
}
// 方法将定义好的WebGLProgram 对象添加到当前的渲染状态中。
gl.useProgram(program);
gl.program = program;
return true;
}
/**
* 创建着色器程序 WebGLProgram
* @param gl
* @param vshader
* @param fshader
* @returns {*}
*/
function createProgram(gl, vshader, fshader) {
// 创建着色器对象
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
if (!vertexShader || !fragmentShader) {
return null;
}
// 创建一个着色器程序对象
const program = gl.createProgram();
if (!program) {
return null;
}
// 负责往 着色器程序对象(WebGLProgram) 添加一个片段或者顶点着色器。
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
// 链接给定的WebGLProgram,从而完成为程序的片元和顶点着色器准备GPU代码的过程。
gl.linkProgram(program);
// Check the result of linking
const linked = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!linked) {
const error = gl.getProgramInfoLog(program);
console.log('链接程序失败: ' + error);
gl.deleteProgram(program);
gl.deleteShader(fragmentShader);
gl.deleteShader(vertexShader);
return null;
}
return program;
}
/**
* 加载着色器
* @param gl
* @param type
* @param source
* @returns {*}
*/
function loadShader(gl, type, source) {
// 创建着色器对象
const shader = gl.createShader(type);
if (shader == null) {
console.log('unable to create shader');
return null;
}
/**
* 设置着色器程序
* shader着色器对象
* source 包含GLSL程序代码的字符串。
*/
gl.shaderSource(shader, source);
// 编译一个GLSL着色器,使其成为为二进制数据,然后就可以被WebGLProgram对象所使用.
gl.compileShader(shader);
// 返回给定的着色器信息
const compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
console.log(compiled)
if (!compiled) {
const error = gl.getShaderInfoLog(shader);
console.log('编译着色器失败: ' + error);
gl.deleteShader(shader);
return null;
}
return shader;
}
</script>
</body>
</html>