GLSL:几何缺乏深度

时间:2018-01-29 23:55:42

标签: glsl webgl

使用WebGL + GLSL,我试图使用以下顶点索引渲染棱镜:

sketch

到目前为止,我还没有能够使这个渲染棱镜 - 我得到了一个三角形的平面:

var canvas,
    gl,
    fs,
    vs,
    glProgram,
    vertexBuffer,
    vertexIndexBuffer,
    colorBuffer,
    positionVal,
    colorVal,
    mvMatrix = mat4.create(),
    pMatrix = mat4.create(),
    angle = 0.01;

function initWebgl() {
  canvas = document.querySelector('canvas');
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  try {
    gl = canvas.getContext('webgl')
    gl.enable(gl.DEPTH_TEST)
    gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT)
  } catch(err) {
    alert('Your browser does not support Webgl')
    return;
  }
  // set the default background color
  gl.clearColor(0.9, 0.9, 0.9, 1.0)
  gl.clear(gl.COLOR_BUFFER_BIT)
}

function initCamera() {
  // set camera area, fov, near clip, far clip, and translation
  gl.viewport(0, 0, canvas.width, canvas.height)
  mat4.perspective(45, canvas.width/canvas.height, 0.1, 100, pMatrix);
  mat4.identity(mvMatrix);
  mat4.translate(mvMatrix, [0, 0, -2.0]);
}

function initShaders() {
  vs = buildShader('#shader-vs', gl.VERTEX_SHADER)
  fs = buildShader('#shader-fs', gl.FRAGMENT_SHADER)
}

function buildShader(selector, type) {
  var src = document.querySelector(selector).innerHTML;
  var shader = gl.createShader(type)
  gl.shaderSource(shader, src)
  gl.compileShader(shader)
  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    console.warn('Shader error', selector, gl.getShaderInfoLog(shader))
  }
  return shader;
}

function initProgram() {
  glProgram = gl.createProgram()
  gl.attachShader(glProgram, vs)
  gl.attachShader(glProgram, fs)
  gl.linkProgram(glProgram)
  if (!gl.getProgramParameter(glProgram, gl.LINK_STATUS)) {
    console.warn('Program link error')
  }
  gl.useProgram(glProgram)
}

function updatePositions() {
  mat4.identity(mvMatrix)
  mat4.translate(mvMatrix, [-1.0, -1.0, -7.0])
  mat4.rotate(mvMatrix, angle, [0.0, 1.0, 0.0])
  angle += 0.01;
}

function getBuffers() {
  // vertex buffer
  var vertexData = new Float32Array([
    // front
    -0.5, -0.5, 0.0,
    0.5, -0.5, 0.0,
    0, 0.5, 0.0,
    // back
    -0.5, -0.5, 5,
    0.5, -0.5, 5,
    0, 0.5, 5,
  ])
  vertexBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW)

  // vertex index buffer - creates prism
  var vertexIndices = new Uint16Array([
    // front
    0, 1, 2,
    // right
    1, 2, 4,
    2, 4, 5,
    // back
    3, 4, 5,
    // left
    2, 3, 5,
    0, 2, 3,
    // bottom
    0, 1, 3,
    1, 3, 4,
  ])
  vertexIndexBuffer = gl.createBuffer()
  vertexIndexBuffer.number_vertex_points = vertexIndices.length;
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer)
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, vertexIndices, gl.STATIC_DRAW)

  // color buffer
  colorVal = colorVal || 0.5;
  colorVal += 0.01;
  var colorData = new Float32Array([
    Math.sin(colorVal) + 1, Math.cos(colorVal) + 1, 1,
    1, Math.sin(colorVal) + 1, 0,
    Math.cos(colorVal) + 1, 1, 0,

    Math.sin(colorVal) + 1, Math.cos(colorVal) + 1, 1,
    1, Math.sin(colorVal) + 1, 0,
    Math.cos(colorVal) + 1, 1, 0,
  ])
  colorBuffer = gl.createBuffer()
  gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
  gl.bufferData(gl.ARRAY_BUFFER, colorData, gl.DYNAMIC_DRAW)
}

function drawBuffers() {
  // identify and bind vertex position attributes
  var aVertexPosition = gl.getAttribLocation(glProgram, 'aVertexPosition')
  gl.enableVertexAttribArray(aVertexPosition)
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer)
  gl.vertexAttribPointer(aVertexPosition, 3, gl.FLOAT, false, 0.0, 0.0)

  // identify and bind vertex color attributes
  var aVertexColor = gl.getAttribLocation(glProgram, 'aVertexColor')
  gl.enableVertexAttribArray(aVertexColor)
  gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
  gl.vertexAttribPointer(aVertexColor, 3, gl.FLOAT, false, 0.0, 0.0)

  // draw the data
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer)
  gl.drawElements(gl.TRIANGLES, vertexIndexBuffer.number_vertex_points,
    gl.UNSIGNED_SHORT, 0)
}

function getMatrixUniforms() {
  glProgram.pMatrixUniform = gl.getUniformLocation(glProgram, 'uPMatrix')
  glProgram.mvMatrixUniform = gl.getUniformLocation(glProgram, 'uMVMatrix')
}

function setMatrixUniforms() {
  gl.uniformMatrix4fv(glProgram.pMatrixUniform, false, pMatrix)
  gl.uniformMatrix4fv(glProgram.mvMatrixUniform, false, mvMatrix)
}

function render() {
  updatePositions()
  getBuffers()
  drawBuffers()
  setMatrixUniforms()
  requestAnimationFrame(render, canvas)
}

initWebgl()
initCamera()
initShaders()
initProgram()
getMatrixUniforms()
render()
* {
  margin: 0;
  padding: 0;
}

body, html {
  height: 100%;
  width: 100%;
  overflow: hidden;
  background: skyblue;
}
<script src="https://rawgit.com/duhaime/955402641534b89babd41c8de8bc91f6/raw/5d86d54f7237f4cf2b206dcf0a3d453ba95acd1d/gl-matrix.js"></script>

<script id='shader-vs' type='x-shader/x-vertex'>
  attribute vec3 aVertexPosition;
  attribute vec3 aVertexColor;

  uniform mat4 uMVMatrix;
  uniform mat4 uPMatrix;

  varying highp vec4 vColor;
  void main() {
    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    vColor = vec4(aVertexColor, 1.0);
  }
</script>

<script id='shader-fs' type='x-shader/x-fragment'>
  varying highp vec4 vColor;
  void main() {
    gl_FragColor = vColor;
  }
</script>
<canvas />

有谁知道我能做些什么来制作棱镜渲染?我很感激别人可以提供的任何指示!

1 个答案:

答案 0 :(得分:1)

哎呀,我正在将vertexIndexBuffer传递给着色器以指定位置属性,但是我应该通过vertexBuffer来指定位置属性。这是预期的结果:

var canvas,
        gl,
        fs,
        vs,
        glProgram,
        vertexBuffer,
        vertexIndexBuffer,
        colorBuffer,
        positionVal,
        colorVal,
        mvMatrix = mat4.create(),
        pMatrix = mat4.create(),
        angle = 0.01;

function initWebgl() {
  canvas = document.querySelector('canvas');
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  try {
    gl = canvas.getContext('webgl')
    gl.enable(gl.DEPTH_TEST)
    gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT)
  } catch(err) {
    alert('Your browser does not support Webgl')
    return;
  }
  // set the default background color
  gl.clearColor(0.9, 0.9, 0.9, 1.0)
  gl.clear(gl.COLOR_BUFFER_BIT)
}

function initCamera() {
  // set camera area, fov, near clip, far clip, and translation
  gl.viewport(0, 0, canvas.width, canvas.height)
  mat4.perspective(45, canvas.width/canvas.height, 0.1, 100, pMatrix);
  mat4.identity(mvMatrix);
  mat4.translate(mvMatrix, [0, 0, -2.0]);
}

function initShaders() {
  vs = buildShader('#shader-vs', gl.VERTEX_SHADER)
  fs = buildShader('#shader-fs', gl.FRAGMENT_SHADER)
}

function buildShader(selector, type) {
  var src = document.querySelector(selector).innerHTML;
  var shader = gl.createShader(type)
  gl.shaderSource(shader, src)
  gl.compileShader(shader)
  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    console.warn('Shader error', selector, gl.getShaderInfoLog(shader))
  }
  return shader;
}

function initProgram() {
  glProgram = gl.createProgram()
  gl.attachShader(glProgram, vs)
  gl.attachShader(glProgram, fs)
  gl.linkProgram(glProgram)
  if (!gl.getProgramParameter(glProgram, gl.LINK_STATUS)) {
    console.warn('Program link error')
  }
  gl.useProgram(glProgram)
}

function updatePositions() {
  mat4.identity(mvMatrix)
  mat4.translate(mvMatrix, [-1.0, -1.0, -7.0])
  mat4.rotate(mvMatrix, angle, [0.0, 1.0, 0.0])
  angle += 0.01;
}

function getBuffers() {
  // vertex buffer
  var vertexData = new Float32Array([
    // front
    -0.5, -0.5, 0.0,
    0.5, -0.5, 0.0,
    0, 0.5, 0.0,
    // back
    -0.5, -0.5, 5,
    0.5, -0.5, 5,
    0, 0.5, 5,
  ])
  vertexBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW)

  // vertex index buffer - creates prism
  var vertexIndices = new Uint16Array([
    // front
    0, 1, 2,
    // right
    1, 2, 4,
    2, 4, 5,
    // back
    3, 4, 5,
    // left
    2, 3, 5,
    0, 2, 3,
    // bottom
    0, 1, 3,
    1, 3, 4,
  ])
  vertexIndexBuffer = gl.createBuffer()
  vertexIndexBuffer.number_vertex_points = vertexIndices.length;
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer)
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, vertexIndices, gl.STATIC_DRAW)

  // color buffer
  colorVal = colorVal || 0.5;
  colorVal += 0.01;
  var colorData = new Float32Array([
    Math.sin(colorVal) + 1, Math.cos(colorVal) + 1, 1,
    1, Math.sin(colorVal) + 1, 0,
    Math.cos(colorVal) + 1, 1, 0,

    Math.sin(colorVal) + 1, Math.cos(colorVal) + 1, 1,
    1, Math.sin(colorVal) + 1, 0,
    Math.cos(colorVal) + 1, 1, 0,
  ])
  colorBuffer = gl.createBuffer()
  gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
  gl.bufferData(gl.ARRAY_BUFFER, colorData, gl.DYNAMIC_DRAW)
}

function drawBuffers() {
  // identify and bind vertex position attributes
  var aVertexPosition = gl.getAttribLocation(glProgram, 'aVertexPosition')
  gl.enableVertexAttribArray(aVertexPosition)
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
  gl.vertexAttribPointer(aVertexPosition, 3, gl.FLOAT, false, 0.0, 0.0)

  // identify and bind vertex color attributes
  var aVertexColor = gl.getAttribLocation(glProgram, 'aVertexColor')
  gl.enableVertexAttribArray(aVertexColor)
  gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
  gl.vertexAttribPointer(aVertexColor, 3, gl.FLOAT, false, 0.0, 0.0)

  // draw the data
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer)
  gl.drawElements(gl.TRIANGLES, vertexIndexBuffer.number_vertex_points,
    gl.UNSIGNED_SHORT, 0)
}

function getMatrixUniforms() {
  glProgram.pMatrixUniform = gl.getUniformLocation(glProgram, 'uPMatrix')
  glProgram.mvMatrixUniform = gl.getUniformLocation(glProgram, 'uMVMatrix')
}

function setMatrixUniforms() {
  gl.uniformMatrix4fv(glProgram.pMatrixUniform, false, pMatrix)
  gl.uniformMatrix4fv(glProgram.mvMatrixUniform, false, mvMatrix)
}

function render() {
  updatePositions()
  getBuffers()
  drawBuffers()
  setMatrixUniforms()
  requestAnimationFrame(render, canvas)
}

initWebgl()
initCamera()
initShaders()
initProgram()
getMatrixUniforms()
render()
* {
  margin: 0;
  padding: 0;
}

body, html {
  height: 100%;
  width: 100%;
  overflow: hidden;
  background: skyblue;
}
<script src="https://rawgit.com/duhaime/955402641534b89babd41c8de8bc91f6/raw/5d86d54f7237f4cf2b206dcf0a3d453ba95acd1d/gl-matrix.js"></script>
<script id='shader-vs' type='x-shader/x-vertex'>
  attribute vec3 aVertexPosition;
  attribute vec3 aVertexColor;

  uniform mat4 uMVMatrix;
  uniform mat4 uPMatrix;

  varying highp vec4 vColor;
  void main() {
    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
    vColor = vec4(aVertexColor, 1.0);
  }
</script>

<script id='shader-fs' type='x-shader/x-fragment'>
  varying highp vec4 vColor;
  void main() {
    gl_FragColor = vColor;
  }
</script>
<canvas />