<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
}
#glcanvas {
width: 100%;
height: 100%;
}
</style>
<!-- //attribute变量只能在顶点着色器里使用,表示:顶点、材质、光照
uniform 定义变量,是通过程序传进来的
-->
<script id="vertex-shader" type="nojs">
attribute vec4 a_position;
uniform mat4 u_Mat;
void main(){
gl_Position=u_Mat*a_position;
}
</script>
<!--
precision highp float;高精度
precision mediump float;中精度
precision lowp float;低精度
-->
<script id="fragment-shader" type="nojs">
precision mediump float;
void main(){
gl_FragColor=vec4(1,0,0,1);
}
</script>
</head>
<body onload="main()">
<canvas id="glcanvas">
你的浏览器似乎不支持或者禁用了 HTML5
<code><canvas></code>
元素。
</canvas>
<script>
// 从这里开始
function main() {
const canvas = document.querySelector("#glcanvas");
// 初始化 WebGL 上下文
const gl = canvas.getContext("webgl");
console.log(`gl`, gl);
// 确认 WebGL 支持性
if (!gl) {
alert("无法初始化 WebGL,你的浏览器、操作系统或硬件等可能不支持 WebGL。");
return;
}
// 使用完全不透明的黑色清除所有图像
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 用上面指定的颜色清除缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
// 获取顶点着色器文本
let vertexShaderSource = document.getElementById("vertex-shader").textContent
// 获取片元着色器文本
let fragmentShaderSource = document.getElementById("fragment-shader").textContent
console.log(`vertexShaderSource`, vertexShaderSource);
console.log(`fragmentShaderSource`, fragmentShaderSource);
// 创建顶点着色器
let vertexShader = gl.createShader(gl.VERTEX_SHADER)
// 创建片元着色器
let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
console.log(`vertexShader`, vertexShader);
console.log(`fragmentShader`, fragmentShader);
// 向着色器指定glsl源代码
gl.shaderSource(vertexShader, vertexShaderSource)
gl.shaderSource(fragmentShader, fragmentShaderSource)
// 编译顶点着色器
gl.compileShader(vertexShader)
// 编译片元着色器
gl.compileShader(fragmentShader)
// 检查顶点着色器
let vertexSuccess = gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)
console.log(`vertexSuccess`, vertexSuccess);
// 获取顶点着色器的信息日志,查看具体的错误位置以及错误类型
let vertexLog = gl.getShaderInfoLog(vertexShader)
console.log(`vertexLog`, vertexLog);
// 检查片元着色器
let fragmentSuccess = gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)
console.log(`fragmentSuccess`, fragmentSuccess);
// 获取片元着色器的信息日志,查看具体的错误位置以及错误类型
let fragmentLog = gl.getShaderInfoLog(fragmentShader)
console.log(`fragmentLog`, fragmentLog);
// 创建一个程序
let program = gl.createProgram()
// 为程序对象分配着色器
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)
// 连接程序对象
gl.linkProgram(program)
// 检查着色器对象是否连接成功
let programSccess = gl.getProgramParameter(program, gl.LINK_STATUS)
console.log(`programSccess`, programSccess);
// 获取连接程序对象的信息日志,查看具体的错误位置以及错误类型
let programLog = gl.getProgramInfoLog(program)
console.log(`programLog`, programLog);
// 获取着色器 中生命的变量
let positionAttributeLocation = gl.getAttribLocation(program, "a_position")
// 创建缓存区
let positionBuffer = gl.createBuffer()
// 将缓存区的对象绑定到webgl
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
// 创建顶点
let positions = [
0.0,
0.5,
-0.5,
-0.5,
0.5,
-0.5
]
// STATIC_DRAW静态绘制
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW)
// 定义视图大小 x y w h
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height)
// 使用程序
gl.useProgram(program)
// 激活对应属性,只有激活才能使用
gl.enableVertexAttribArray(positionAttributeLocation)
//
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0)
let u_Mat
let scale = {
x: 0.3,
y: 0.3,
z: 0.3
}
let animate = () => { // 定义一个缩放的矩阵
// scale.x-=0.1
// if(scale.x==0.8){
// scale.x=0.1
// }
let mat = new Float32Array([
scale.x,
0.0,
0.0,
0.0,
0.0,
scale.x,
0.0,
0.0,
0.0,
0.0,
scale.x,
0.0,
0.0,
0.0,
0.0,
1.0,
])
// 缩放变量
u_Mat = gl.getUniformLocation(program, 'u_Mat')
gl.uniformMatrix4fv(u_Mat, false, mat)
// 绘制图形
gl.drawArrays(gl.TRIANGLES, 0, 3)
requestAnimationFrame(animate)
}
animate()
// 清空颜色
gl.clearColor(0, 0, 0, 1)
// 清空绘制区域
gl.clear(gl.COLOR_BUFFER_BIT)
}
</script>
</body>
</html>
webgl与glsl着色器绘制三角形
于 2023-08-28 16:48:13 首次发布