使用WEBGL_depth_texture进行WebGL像素位置重建

时间:2018-02-03 19:33:46

标签: javascript webgl

我是WebGL的新手,经过几天的搜索和实验,我找不到一个例子,或者至少是我正在寻找的部分片段:

我正在尝试为后期处理生成深度图,我将在其中重建实际的像素位置(世界空间)。

我设法找到从深度缓冲区提取值后重建实际深度的指南

但是,我找不到办法:

  1. 使用if event.unicode == "!": print("!") 从深度纹理中提取此类数据
  2. 使用帧缓冲区的WEBGL_depth_texture
  3. 导出深度值
  4. 将深度缓冲区值编码为RGBA值,然后提取此数据
  5. 我已经读过这些:

    但他们都没有完全证明如何做到这一点。

    请提供帮助,或者如果可能的话,请参考指导/指南/帮助解决此类问题的其他问题。

    这是我迄今为止的最佳尝试: https://codepen.io/naoric/pen/yvYgrQ?editors=0010

    readPixels
    const $ = sel => document.querySelector(sel)
    const $$ = sel => document.querySelectorAll(sel)
    
    const content = sel => $(sel).textContent
    
    const canvas = $('#canvas')
    const gl = canvas.getContext('webgl')
    window.ext = gl.getExtension('WEBGL_depth_texture')
    gl.enable(gl.DEPTH_TEST);
    
    
    const vertexShaderText = content('#vertex-shader')
    const fragmentShaderText = content('#fragment-shader')
    
    function createShader(gl, type, source) {
      const shader = gl.createShader(type)
      gl.shaderSource(shader, source)
      gl.compileShader(shader)
    
      const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS)
      if (success) return shader
    
      console.error(gl.getShaderInfoLog(shader))
      gl.deleteShader(shader)
    }
    
    function createProgram(gl, vertexShader, fragmentShader) {
      const program = gl.createProgram()
      gl.attachShader(program, vertexShader)
      gl.attachShader(program, fragmentShader)
    
      gl.linkProgram(program)
      const success = gl.getProgramParameter(program, gl.LINK_STATUS)
      if (success) return program
    
      console.log(gl.getProgramInfoLog(program))
      gl.deleteProgram(program)
    }
    
    const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderText)
    const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderText)
    
    const program = createProgram(gl, vertexShader, fragmentShader)
    
    const positionAttributeLocation = gl.getAttribLocation(program, 'a_position')
    const depthTexturePositions = gl.getAttribLocation(program, 'tex_position')
    const uSampler = gl.getUniformLocation(program, 'u_texture')
    
    
    const positionBuffer = createPositionBuffer(gl)
    const texCoordBuffer = createTextureBuffer(gl)
    const {frameBuffer, depthTexture} = createFrameBuffer(gl, 256)
    
    
    render(gl)
    
    function render(gl) {
      gl.viewport(0, 0, gl.canvas.width, gl.canvas.height)
    
    
      gl.clearColor(0, 0, 0, 0)
      gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
      gl.enable(gl.DEPTH_TEST);
    
      gl.useProgram(program)
    
      gl.enableVertexAttribArray(positionAttributeLocation)
      gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
    
      const size = 3,
        type = gl.FLOAT,
        normalize = false,
        stride = 0,
        offset = 0
    
      gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset)
    
    
      gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer)
      draw(gl)
      gl.bindFramebuffer(gl.FRAMEBUFFER, null)
    
      gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
      gl.vertexAttribPointer(depthTexturePositions, 2, gl.FLOAT, false, 0, 0);
      gl.enableVertexAttribArray(depthTexturePositions);
      gl.activeTexture(gl.TEXTURE0);
      gl.bindTexture(gl.TEXTURE_2D, depthTexture);
      gl.uniform1i(uSampler, 0);
      // const pixels = readTexturePixels(depthTexture, 512, 512)
      // console.log({pixels})
      draw(gl)
      // Unbind the framebuffer
      setTimeout(() => render(gl), 1500)
    }
    
    function createTextureBuffer(gl) {
      const texCoordBuffer = gl.createBuffer()
      gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer)
      const positions = [
        -1.0,  1.0,
        1.0,  1.0,
        1.0,  -1.0,
        -1.0, -1.0,
      ]
    
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW)
      return texCoordBuffer
    }
    
    
    function createPositionBuffer(gl) {
      const positionBuffer = gl.createBuffer()
    
      gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
    
      const positions = [
        0, -0.4, 0.1,
        0, .5, 0.3,
        .7, 0, 0.7
      ]
    
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW)
      gl.bindBuffer(gl.ARRAY_BUFFER, null)
      return positionBuffer
    }
    
    
    function createFrameBuffer(gl, size) {
      const frameBuffer = gl.createFramebuffer()
      gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer)
      const colorTexture = createTexture(gl, size)
      gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTexture, 0);
      const depthTexture = createDepthTexture(gl, size)
      gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture, 0);
      if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
        alert("framebuffer not complete");
      }
      gl.bindFramebuffer(gl.FRAMEBUFFER, null);
      
      return {frameBuffer, depthTexture}
    }
    
    function createDepthTexture(gl, size) {
      var depthTexture = gl.createTexture();
      gl.bindTexture(gl.TEXTURE_2D, depthTexture);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_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);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, size, size, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null);
      // gl.bindTexture(gl.TEXTURE_2D, null)
      return depthTexture
    }
    
    
    function createTexture(gl, size) {
      const texture = gl.createTexture()
      gl.bindTexture(gl.TEXTURE_2D, texture)
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_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);
      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
      // gl.bindTexture(gl.TEXTURE_2D, null)
      return texture
    }
    
    function draw(gl) {
      const primitiveType = gl.TRIANGLES,
        offset = 0,
        count = 3
    
      gl.drawArrays(primitiveType, offset, count)
    }

0 个答案:

没有答案
相关问题