Shader 渐变屏幕

本文详细介绍了如何在WebGL中使用顶点着色器处理顶点数据,以及如何通过片元着色器利用UV坐标和时间变量实现动态颜色渐变效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

渐变

前置工作,创建缓冲,对顶点着色器传递顶点数据

function main() {
  var canvas = document.getElementById('webgl');
  var gl = getWebGLContext(canvas);
  if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) return
  var n = initVertexBuffers(gl);
}

function initVertexBuffers(gl) {
  var vertices = new Float32Array([-1, 1, -1, -1, 1, -1, 1, 1]);
  var n = 4;
  var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  var vertexBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(a_Position);
  return n;
}

顶点着色

var VSHADER_SOURCE =
  'attribute vec4 a_Position;\n' +
  'void main() {\n' +
  '  gl_Position = a_Position;\n' +
  '}\n';

思考,最终操作改变每个片元的颜色,就是根据uv坐标的不同逐片元计算,使用cos控制周期性效果

uv坐标:二维空间每个像素绝对位置(0,0 ~ 宽高) gl_FragCoord.xy  /  设备分辨率

cos周期变化:delta时间,每帧间隔为主键

对片元着色传递这些控制变量

  let time = Date.now();
  let iTime = 0;
  let iResolutionAddr = gl.getUniformLocation(gl.program, "iResolution");
  let iTimeAddr = gl.getUniformLocation(gl.program, "iTime");
  gl.clear(gl.COLOR_BUFFER_BIT);

  let loop = () => {
    let nowTime = Date.now();
    let dt = (nowTime - time) * 0.002;
    iTime += dt;
    time = nowTime;

    gl.uniform2f(iResolutionAddr, 1536, 865); // 传递分辨率
    gl.uniform1f(iTimeAddr, iTime); // 传递时间

    gl.clearColor(0, 0, 0, 0);
    gl.drawArrays(gl.TRIANGLE_FAN, 0, n);
    requestAnimationFrame(loop);
  };
  loop();

片元着色

var FSHADER_SOURCE =
  '#ifdef GL_ES\n' +
  'precision mediump float;\n' +
  '#endif\n' +
  'uniform vec2 iResolution;\n' + // 屏幕分辨率
  'uniform float iTime;\n' +
  'void main() {\n' +
    'vec2 uv = gl_FragCoord.xy / iResolution;' +  // 计算uv 0~1
    // cos 分别计算 v.x, v.y, v.z 的余弦值,返回 vec3(-1~1, -1~1, -1~1)
    'vec3 c = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0, 2, 4));' +  // vec3 0~1 
    'gl_FragColor = vec4(c, 1.0);\n' +
  '}\n';

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山楂树の

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值