WebGL基础
东北小麦客 2023-06-02 WebGLGLSLShader
# 使用webGL
编辑一个基础的shader
(js)
参考资料
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#main {
width: 50vw;
height: 50vh;
}
</style>
</head>
<body>
<canvas id="main"></canvas>
</body>
<script id="vertexShaderScript" type="x-shader/x-vertex">
#version 330 core
// 指定OpenGL的版本
void main() {
gl_Position = vec4(0.0, 0.0, 0.0, 1); // dom 容器中间, !!! 使用了NDC坐标 !!!
gl_PointSize = 8.0;
}
</script>
<script id="fragmentShaderScript" type="x-shader/x-fragment">
#version 330 core
// 指定OpenGL的版本
void main() {
gl_FragColor = vec4(0, 1, 0, 1);
}
</script>
<script>
/**
* 根据传入的 类型 创建对应的 `shader`
* Create a shader object
* @param gl GL context
* @param type the type of the shader object to be created
* @param source shader program (string)
* @return created shader object, or null if the creation has failed.
*/
function loadShader(gl, type, source) {
// 1.Create shader object
const shader = gl.createShader(type);
if (shader == null) {
console.log('unable to create shader');
return null;
}
// 2.Set the shader program
gl.shaderSource(shader, source);
// 3.Compile the shader
gl.compileShader(shader);
// 4.Check the result of compilation
const compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (!compiled) {
var error = gl.getShaderInfoLog(shader);
console.log('Failed to compile shader: ' + error);
gl.deleteShader(shader);
return null;
}
return shader;
}
/**
* Create the linked program object
* @param gl GL context
* @param vshader a vertex shader program (string) 顶点着色器文件的数据
* @param fshader a fragment shader program (string) 片元着色器文件的数据
* @return created program object, or null if the creation has failed
*/
function createProgram(gl, vshader, fshader) {
// 1.Create shader object
var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
if (!vertexShader || !fragmentShader) {
return null;
}
// 2.Create a program object
var program = gl.createProgram();
if (!program) {
return null;
}
// 3. Attach the shader objects
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
// 4.Link the program object
gl.linkProgram(program);
// 5.Check the result of linking
var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!linked) {
var error = gl.getProgramInfoLog(program);
console.log('Failed to link program: ' + error);
gl.deleteProgram(program);
gl.deleteShader(vertexShader);
gl.deleteShader(fragmentShader);
return null;
}
return program;
}
function initShaders(gl, vshader, fshader) {
var program = createProgram(gl, vshader, fshader);
if (!program) {
console.log('Failed to create program');
return false;
}
gl.useProgram(program);
gl.program = program;
return true;
}
const dom = document.getElementById('main');
var gl = dom.getContext('webgl');
// 顶点着色器文件数据
const VSHADER_SOURCE = `
void main() {
gl_Position = vec4(0.0 ,0.0 ,0.0 , 1.0);
gl_PointSize = 10.0;
}
`;
// 片元着色器文件数据
const FSHADER_SOURCE = `
void main() {
gl_FragColor = vec4(1, 0.0, 0 ,1.0);
}
`;
// const vertexShaderText = VSHADER_SOURCE; // 方式一
const vertexShaderText = document.getElementById('vertexShaderScript').text; // 方式二
const fragmentShaderText = document.getElementById('fragmentShaderScript').text;
initShaders(gl, vertexShaderText, fragmentShaderText);
gl.drawArrays(gl.POINTS, 0, 1);
</script>
</html>