View difference between Paste ID: CAm0JgVc and 3d7A6ACU
SHOW: | | - or go back to the newest paste.
1
function createCShader(gl: WebGLRenderingContext, source: string, type: any) {
2
  var shader = gl.createShader(type);
3
  if (shader == null) throw new DOMException("Compiled shader is null");
4
  gl.shaderSource(shader, source);
5
  gl.compileShader(shader);
6
  var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
7
  if (success) {
8
    return shader;
9
  }
10
11
  console.error(gl.getShaderInfoLog(shader));
12
  throw new Error(gl.getShaderInfoLog(shader) || "No message available");
13
}
14
15
export function createWebglProgram(gl, sourceVS, sourceFS) {
16
  const vertexShader = createCShader(gl, sourceVS, gl.VERTEX_SHADER);
17
  const fragmentShader = createCShader(gl, sourceFS, gl.FRAGMENT_SHADER);
18
  var program = gl.createProgram();
19
  gl.attachShader(program, vertexShader);
20
  gl.attachShader(program, fragmentShader);
21
  gl.linkProgram(program);
22
  var success = gl.getProgramParameter(program, gl.LINK_STATUS);
23
  if (success) {
24
    return program;
25
  }
26
27
  console.error(gl.getProgramInfoLog(program));
28
  gl.deleteProgram(program);
29
}
30
31
32
33
function doGPGPU() {
34
  const vs = `
35
  attribute vec4 position;
36
  void main() {
37
    gl_Position = position;
38
  }
39
  `;
40
41
  const fs = `
42
  precision highp float;
43
   
44
  uniform sampler2D srcTex;
45
  uniform vec2 srcDimensions;
46
   
47
  void main() {
48
    vec2 texcoord = gl_FragCoord.xy / srcDimensions;
49
    vec4 value = texture2D(srcTex, texcoord);
50
    gl_FragColor = value;
51
  }
52
  `;
53
54
  const dstWidth = 3;
55
  const dstHeight = 2;
56
57
  // make a 3x2 canvas for 6 results
58
  const canvas = document.createElement('canvas');
59
  canvas.width = dstWidth;
60
  canvas.height = dstHeight;
61
62
  const gl = canvas.getContext('webgl');
63
  if (!gl) throw new DOMException()
64
  // check we can use floating point textures
65
  const ext1 = gl.getExtension('OES_texture_float');
66
  if (!ext1) {
67
    alert('Need OES_texture_float');
68
    return;
69
  }
70
  // check we can render to floating point textures
71
  const ext2 = gl.getExtension('WEBGL_color_buffer_float');
72
  if (!ext2) {
73
    alert('Need WEBGL_color_buffer_float');
74
    return;
75
  }
76
  // check we can use textures in a vertex shader
77
  if (gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS) < 1) {
78
    alert('Can not use textures in vertex shaders');
79
    return;
80
  }
81
82
  const program = createWebglProgram(gl, vs, fs);
83
84
  const positionLoc = gl.getAttribLocation(program, 'position');
85
  const srcTexLoc = gl.getUniformLocation(program, 'srcTex');
86
  const srcDimensionsLoc = gl.getUniformLocation(program, 'srcDimensions');
87
88
  // setup a full canvas clip space quad
89
  const buffer = gl.createBuffer();
90
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
91
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
92
    -1, -1,
93
    1, -1,
94
    -1, 1,
95
    -1, 1,
96
    1, -1,
97
    1, 1,
98
  ]), gl.STATIC_DRAW);
99
100
  // setup our attributes to tell WebGL how to pull
101
  // the data from the buffer above to the position attribute
102
  gl.enableVertexAttribArray(positionLoc);
103
  gl.vertexAttribPointer(
104
    positionLoc,
105
    2,         // size (num components)
106
    gl.FLOAT,  // type of data in buffer
107
    false,     // normalize
108
    0,         // stride (0 = auto)
109
    0,         // offset
110
  );
111
112
  
113
  const positions = new Float32Array(new Array(canvas.width * canvas.height * 4).map(_ => Math.random() * 10));
114
115
  const inputTex = createTexture(gl, positions, canvas.width, canvas.height);
116
  const outputTex = createTexture(gl, null, canvas.width, canvas.height);
117
118
  const inputFb = createFramebuffer(gl, inputTex);
119
  const outputFb = createFramebuffer(gl, outputTex);
120
121
  gl.bindFramebuffer(gl.FRAMEBUFFER, outputFb);
122
  gl.viewport(0, 0, dstWidth, dstHeight);
123
124
  gl.activeTexture(gl.TEXTURE0)
125
  gl.bindTexture(gl.TEXTURE_2D, inputTex);
126
127
  
128
  gl.useProgram(program);
129
  gl.uniform1i(srcTexLoc, 0);
130
  gl.uniform2f(srcDimensionsLoc, dstWidth, dstHeight);
131
  
132
  gl.drawArrays(gl.TRIANGLES, 0, dstHeight * dstWidth);
133
134
  // get the result
135
  const results = new Float32Array(dstWidth * dstHeight * 4);
136
  gl.readPixels(0, 0, dstWidth, dstHeight, gl.RGBA, gl.FLOAT, results);
137
138
  // print the results
139
  console.log(results.length)
140
  console.log(results)
141
142
}
143-
143+
144
function createTexture(gl, data, width, height) {
145
  const tex = gl.createTexture();
146
  gl.bindTexture(gl.TEXTURE_2D, tex);
147
  gl.texImage2D(
148
    gl.TEXTURE_2D,
149
    0,        // mip level
150
    gl.RGBA,  // internal format
151
    width,
152
    height,
153
    0,        // border
154
    gl.RGBA,  // format
155
    gl.FLOAT, // type
156
    data,
157
  );
158
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
159
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
160
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
161
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
162
  return tex;
163
}
164
165
function createFramebuffer(gl, tex) {
166
  const fb = gl.createFramebuffer();
167
  gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
168
  gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
169
  return fb;
170
}