使用WebGL + GLSL,我试图使用以下顶点索引渲染棱镜:
到目前为止,我还没有能够使这个渲染棱镜 - 我得到了一个三角形的平面:
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 />
有谁知道我能做些什么来制作棱镜渲染?我很感激别人可以提供的任何指示!
答案 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 />