Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function createCShader(gl: WebGLRenderingContext, source: string, type: any) {
- var shader = gl.createShader(type);
- if (shader == null) throw new DOMException("Compiled shader is null");
- gl.shaderSource(shader, source);
- gl.compileShader(shader);
- var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
- if (success) {
- return shader;
- }
- console.error(gl.getShaderInfoLog(shader));
- throw new Error(gl.getShaderInfoLog(shader) || "No message available");
- }
- export function createWebglProgram(gl, sourceVS, sourceFS) {
- const vertexShader = createCShader(gl, sourceVS, gl.VERTEX_SHADER);
- const fragmentShader = createCShader(gl, sourceFS, gl.FRAGMENT_SHADER);
- var program = gl.createProgram();
- gl.attachShader(program, vertexShader);
- gl.attachShader(program, fragmentShader);
- gl.linkProgram(program);
- var success = gl.getProgramParameter(program, gl.LINK_STATUS);
- if (success) {
- return program;
- }
- console.error(gl.getProgramInfoLog(program));
- gl.deleteProgram(program);
- }
- function doGPGPU() {
- const vs = `
- attribute vec4 position;
- void main() {
- gl_Position = position;
- }
- `;
- const fs = `
- precision highp float;
- uniform sampler2D srcTex;
- uniform vec2 srcDimensions;
- void main() {
- vec2 texcoord = gl_FragCoord.xy / srcDimensions;
- vec4 value = texture2D(srcTex, texcoord);
- gl_FragColor = value;
- }
- `;
- const dstWidth = 3;
- const dstHeight = 2;
- // make a 3x2 canvas for 6 results
- const canvas = document.createElement('canvas');
- canvas.width = dstWidth;
- canvas.height = dstHeight;
- const gl = canvas.getContext('webgl');
- if (!gl) throw new DOMException()
- // check we can use floating point textures
- const ext1 = gl.getExtension('OES_texture_float');
- if (!ext1) {
- alert('Need OES_texture_float');
- return;
- }
- // check we can render to floating point textures
- const ext2 = gl.getExtension('WEBGL_color_buffer_float');
- if (!ext2) {
- alert('Need WEBGL_color_buffer_float');
- return;
- }
- // check we can use textures in a vertex shader
- if (gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS) < 1) {
- alert('Can not use textures in vertex shaders');
- return;
- }
- const program = createWebglProgram(gl, vs, fs);
- const positionLoc = gl.getAttribLocation(program, 'position');
- const srcTexLoc = gl.getUniformLocation(program, 'srcTex');
- const srcDimensionsLoc = gl.getUniformLocation(program, 'srcDimensions');
- // setup a full canvas clip space quad
- const buffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
- -1, -1,
- 1, -1,
- -1, 1,
- -1, 1,
- 1, -1,
- 1, 1,
- ]), gl.STATIC_DRAW);
- // setup our attributes to tell WebGL how to pull
- // the data from the buffer above to the position attribute
- gl.enableVertexAttribArray(positionLoc);
- gl.vertexAttribPointer(
- positionLoc,
- 2, // size (num components)
- gl.FLOAT, // type of data in buffer
- false, // normalize
- 0, // stride (0 = auto)
- 0, // offset
- );
- const positions = new Float32Array(new Array(canvas.width * canvas.height * 4).map(_ => Math.random() * 10));
- const inputTex = createTexture(gl, positions, canvas.width, canvas.height);
- const outputTex = createTexture(gl, null, canvas.width, canvas.height);
- const inputFb = createFramebuffer(gl, inputTex);
- const outputFb = createFramebuffer(gl, outputTex);
- gl.bindFramebuffer(gl.FRAMEBUFFER, outputFb);
- gl.viewport(0, 0, dstWidth, dstHeight);
- gl.activeTexture(gl.TEXTURE0)
- gl.bindTexture(gl.TEXTURE_2D, inputTex);
- gl.useProgram(program);
- gl.uniform1i(srcTexLoc, 0);
- gl.uniform2f(srcDimensionsLoc, dstWidth, dstHeight);
- gl.drawArrays(gl.TRIANGLES, 0, dstHeight * dstWidth);
- // get the result
- const results = new Float32Array(dstWidth * dstHeight * 4);
- gl.readPixels(0, 0, dstWidth, dstHeight, gl.RGBA, gl.FLOAT, results);
- // print the results
- console.log(results.length)
- console.log(results)
- }
- function createTexture(gl, data, width, height) {
- const tex = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, tex);
- gl.texImage2D(
- gl.TEXTURE_2D,
- 0, // mip level
- gl.RGBA, // internal format
- width,
- height,
- 0, // border
- gl.RGBA, // format
- gl.FLOAT, // type
- data,
- );
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- return tex;
- }
- function createFramebuffer(gl, tex) {
- const fb = gl.createFramebuffer();
- gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
- return fb;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement