当前位置:   article > 正文

跟随chatgpt学习如何使用GLSL进行简单的图形渲染

跟随chatgpt学习如何使用GLSL进行简单的图形渲染

1. 准备一个HTML文件:创建一个新的HTML文件,将 HTML 文件命名为 `index.html`,并添加一个用于显示图形的<canvas>元素。

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>Simple WebGL Rendering</title>
  6. <style>
  7. body { margin: 0; }
  8. canvas { width: 100%; height: 100%; }
  9. </style>
  10. </head>
  11. <body>
  12. <canvas id="canvas"></canvas>
  13. <script src="script.js"></script>
  14. </body>
  15. </html>

2. 创建JavaScript文件:创建一个名为`script.js`的 JavaScript 文件来处理图形的渲染逻辑。

  1. // 获取canvas元素
  2. const canvas = document.getElementById("canvas");
  3. // 创建WebGL上下文
  4. const gl = canvas.getContext("webgl");
  5. // 定义顶点着色器代码
  6. const vertexShaderSource = `
  7. attribute vec2 position;
  8. void main() {
  9. gl_Position = vec4(position, 0.0, 1.0);
  10. }
  11. `;
  12. // 创建顶点着色器
  13. const vertexShader = gl.createShader(gl.VERTEX_SHADER);
  14. gl.shaderSource(vertexShader, vertexShaderSource);
  15. gl.compileShader(vertexShader);
  16. // 检查顶点着色器是否编译成功
  17. if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
  18. console.error("Vertex shader compilation error:", gl.getShaderInfoLog(vertexShader));
  19. }
  20. // 定义片段着色器代码
  21. const fragmentShaderSource = `
  22. precision mediump float;
  23. void main() {
  24. gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  25. }
  26. `;
  27. // 创建片段着色器
  28. const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  29. gl.shaderSource(fragmentShader, fragmentShaderSource);
  30. gl.compileShader(fragmentShader);
  31. // 检查片段着色器是否编译成功
  32. if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
  33. console.error("Fragment shader compilation error:", gl.getShaderInfoLog(fragmentShader));
  34. }
  35. // 创建着色器程序
  36. const shaderProgram = gl.createProgram();
  37. gl.attachShader(shaderProgram, vertexShader);
  38. gl.attachShader(shaderProgram, fragmentShader);
  39. gl.linkProgram(shaderProgram);
  40. // 使用着色器程序
  41. gl.useProgram(shaderProgram);
  42. // 渲染图形
  43. const vertices = [-0.5, -0.5,
  44. 0.5, -0.5,
  45. 0.0, 0.5
  46. ];
  47. const vertexBuffer = gl.createBuffer();
  48. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  49. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
  50. const positionAttributeLocation = gl.getAttribLocation(shaderProgram, "position");
  51. gl.enableVertexAttribArray(positionAttributeLocation);
  52. gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
  53. gl.clearColor(0, 0, 0, 1);
  54. gl.clear(gl.COLOR_BUFFER_BIT);
  55. gl.drawArrays(gl.TRIANGLES, 0, 3);

运行成功页面

一个简单的glsl小实验成功了,不过我想要这个三角形动起来。

修改后的script代码如下

  1. // 获取画布元素和 WebGL 上下文
  2. var canvas = document.getElementById("canvas");
  3. var gl = canvas.getContext("webgl");
  4. // 顶点着色器代码
  5. const vertexShaderSource = `
  6. attribute vec2 a_position;
  7. uniform vec2 u_translation;
  8. void main() {
  9. gl_Position = vec4(a_position + u_translation, 0, 1);
  10. }
  11. `;
  12. // 片段着色器代码
  13. const fragmentShaderSource = `
  14. precision mediump float;
  15. void main() {
  16. gl_FragColor = vec4(1, 0, 0, 1);
  17. }
  18. `;
  19. // 创建着色器程序
  20. var program = createProgram(gl, vertexShaderSource, fragmentShaderSource);
  21. // 获取顶点位置 attribute 的位置
  22. var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
  23. // 创建并绑定顶点缓冲区
  24. var positionBuffer = gl.createBuffer();
  25. gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
  26. // 定义一个简单的三角形顶点位置数组
  27. var positions = [
  28. 0, 0,
  29. -0.5, -0.5,
  30. 0.5, -0.5
  31. ];
  32. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
  33. // 设置顶点属性指针
  34. gl.enableVertexAttribArray(positionAttributeLocation);
  35. gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
  36. // 清空画布
  37. gl.clearColor(0, 0, 0, 1);
  38. // 设置着色器程序
  39. gl.useProgram(program);
  40. // 获取着色器程序中 uniform 变量的位置
  41. var translationUniformLocation = gl.getUniformLocation(program, "u_translation");
  42. // 更新平移向量
  43. function updateTranslation() {
  44. var time = new Date().getTime() * 0.001; // 获取时间并转换为秒
  45. var translation = [
  46. Math.sin(time), // x 轴上的移动,使用正弦函数模拟
  47. Math.cos(time) // y 轴上的移动,使用余弦函数模拟
  48. ];
  49. gl.uniform2fv(translationUniformLocation, translation);
  50. }
  51. // 动画循环
  52. function animate() {
  53. // 清空画布
  54. gl.clear(gl.COLOR_BUFFER_BIT);
  55. // 绘制三角形
  56. gl.drawArrays(gl.TRIANGLES, 0, 3);
  57. // 更新平移向量
  58. updateTranslation();
  59. // 请求下一次动画循环
  60. requestAnimationFrame(animate);
  61. }
  62. // 开始动画循环
  63. animate();
  64. // 创建着色器程序的函数
  65. function createProgram(gl, vertexShaderSource, fragmentShaderSource) {
  66. // 创建顶点着色器和片段着色器
  67. var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
  68. var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
  69. // 创建着色器程序
  70. var program = gl.createProgram();
  71. // 附加着色器到着色器程序
  72. gl.attachShader(program, vertexShader);
  73. gl.attachShader(program, fragmentShader);
  74. // 链接着色器程序
  75. gl.linkProgram(program);
  76. // 检查链接状态
  77. var success = gl.getProgramParameter(program, gl.LINK_STATUS);
  78. if (success) {
  79. return program;
  80. }
  81. // 链接错误,打印错误信息
  82. console.log(gl.getProgramInfoLog(program));
  83. gl.deleteProgram(program);
  84. }
  85. // 创建着色器的函数
  86. function createShader(gl, type, source) {
  87. // 创建着色器
  88. var shader = gl.createShader(type);
  89. // 附加着色器源代码到着色器
  90. gl.shaderSource(shader, source);
  91. // 编译着色器
  92. gl.compileShader(shader);
  93. // 检查编译状态
  94. var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  95. if (success) {
  96. return shader;
  97. }
  98. // 编译错误,打印错误信息
  99. console.log(gl.getShaderInfoLog(shader));
  100. gl.deleteShader(shader);
  101. }

运行成功截图

他现在就是一个游来游去的红色三角形了。太神奇了!~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/107231
推荐阅读
相关标签
  

闽ICP备14008679号