Last active
April 4, 2023 02:58
-
-
Save eczn/b956299758108eef22999801a86f3201 to your computer and use it in GitHub Desktop.
白噪音生成 & 渲染到 canvas 上 (备注:gpt 教我写的,我改了其中相关着色器的参数以及简化和理解)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// export {} | |
const canvas = document.getElementById('canvas')! as HTMLCanvasElement; | |
const gl = canvas.getContext('webgl')!; | |
// 定义顶点着色器 | |
const vertexShaderSource = ` | |
attribute vec4 a_position; | |
void main() { | |
gl_Position = a_position; | |
} | |
`; | |
// 定义片段着色器 | |
const fragmentShaderSource = ` | |
#ifdef GL_ES | |
precision mediump float; | |
#endif | |
uniform float u_time; | |
uniform float u_size; | |
// uniform vec2 u_resolution; | |
float random2d(vec2 co) { | |
float a = 12.9898; | |
float b = 78.233; | |
float c = 43758.5453; | |
float dt= dot(co.xy ,vec2(a,b)); | |
float sn= mod(dt,3.14); | |
return fract(sin(sn) * c); | |
} | |
// web 上还不支持那么新的特性 | |
float mymod(float a, float b) { | |
return a - (b * floor(a/b)); | |
} | |
float ff(float x) { | |
// return x - mymod(x, 4.0); | |
// return x - mymod(x, 2.0); | |
return x - mymod(x, u_size); | |
} | |
void main(){ | |
vec2 coord = vec2(ff(gl_FragCoord.x), ff(gl_FragCoord.y)); | |
vec3 color = vec3(0.0); | |
float grain = 0.0; | |
grain = random2d(vec2(sin(coord)) * u_time); | |
float vv = (grain > 0.5) ? 1.0 : 0.0; | |
color += vec3(vv); | |
gl_FragColor = vec4(color, 1.0); | |
} | |
`; | |
// 创建顶点着色器 | |
const vertexShader = gl.createShader(gl.VERTEX_SHADER)!; | |
gl.shaderSource(vertexShader, vertexShaderSource); | |
gl.compileShader(vertexShader); | |
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) { | |
console.error(gl.getShaderInfoLog(vertexShader)); | |
} | |
// 创建片段着色器 | |
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)!; | |
gl.shaderSource(fragmentShader, fragmentShaderSource); | |
gl.compileShader(fragmentShader); | |
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { | |
console.error(gl.getShaderInfoLog(fragmentShader)); | |
} | |
// 创建着色器程序 | |
const program = gl.createProgram()!; | |
gl.attachShader(program, vertexShader); | |
gl.attachShader(program, fragmentShader); | |
gl.linkProgram(program); | |
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { | |
console.error(gl.getProgramInfoLog(program)); | |
} | |
gl.useProgram(program); | |
// 获取顶点着色器的位置属性 | |
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position'); | |
const positionBuffer = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); | |
// 定义顶点数据 | |
const vertices: number[] = [ | |
-1, 1, | |
-1, -1, | |
1, -1, | |
1, -1, | |
1, 1, | |
-1, 1, | |
]; | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); | |
gl.enableVertexAttribArray(positionAttributeLocation); | |
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0); | |
// 获取 uniform 变量的位置 | |
// const resolutionUniformLocation = gl.getUniformLocation(program, 'u_resolution'); | |
const timeUniformLocation = gl.getUniformLocation(program, 'u_time'); | |
const sizeUniformLocation = gl.getUniformLocation(program, 'u_size'); | |
canvas.width = window.innerWidth; | |
canvas.height = window.innerHeight; | |
function drawgl() { | |
// 设置 canvas 的分辨率 | |
gl.viewport(0, 0, canvas.width, canvas.height); | |
// 创造一个随机数并传递到着色器程序中 | |
gl.uniform1f(timeUniformLocation, Math.random()); | |
gl.uniform1f(sizeUniformLocation, 8.0); | |
// 清空画布并绘制白噪音 | |
gl.clearColor(0, 0, 0, 1); | |
gl.clear(gl.COLOR_BUFFER_BIT); | |
gl.drawArrays(gl.TRIANGLES, 0, 6); | |
requestAnimationFrame(drawgl); | |
} | |
drawgl(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment