我有一个用Javascript和WebGL编写的3D Serpinski Triangle,使用位于https://github.com/esangel/WebGL/tree/master/Common
的Common文件夹每面应该具有不同的颜色。三角形可以渲染和旋转,但是问题在于背面是透明的。
我尝试过更改三角函数内baseColors中的vec3,甚至尝试将另一种颜色压入colors数组。我在另一篇文章中读到,绘制某些多边形时可能会发生这种情况。我唯一的猜测是,需要重新排列几行代码。
"use strict";
var canvas;
var gl;
var theta = 0.0;
var dtheta = 0.1;
var thetaLoc;
var speed = 50;
var bufferId;
var vertices;
var dir = 1;
var points = [];
var colors = [];
var NumTimesToSubdivide = 3;
window.onload = function init()
{
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if (!gl) { alert("WebGL isn't available"); }
//
// Initialize our data for the Sierpinski Gasket
//
// First, initialize the vertices of our 3D gasket
// Four vertices on unit circle
// Intial tetrahedron with equal length sides
var vertices = [
vec3( 0.0000, 0.0000, -1.0000 ),
vec3( 0.0000, 0.9428, 0.3333 ),
vec3( -0.8165, -0.4714, 0.3333 ),
vec3( 0.8165, -0.4714, 0.3333 )
];
divideTetra( vertices[0], vertices[1], vertices[2], vertices[3],
NumTimesToSubdivide);
//
// Configure WebGL
//
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
// enable hidden-surface removal
gl.enable(gl.DEPTH_TEST);
// Load shaders and initialize attribute buffers
var program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
// Create a buffer object, initialize it, and associate it with the
// associated attribute variable in our vertex shader
var cBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );
gl.vertexAttribPointer( vColor, 3, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vColor );
var vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 3, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray(vPosition);
thetaLoc = gl.getUniformLocation(program, "theta");
gl.uniform1f(thetaLoc, theta);
render();
};
function triangle( a, b, c, color )
{
// add colors and vertices for one triangle
var baseColors = [
vec3(1.0, 0.0, 0.0),
vec3(0.0, 1.0, 0.0),
vec3(0.0, 0.0, 1.0),
vec3(1.0, 1.0, 0.0)
];
colors.push( baseColors[color] );
points.push( a );
colors.push( baseColors[color] );
points.push( b );
colors.push( baseColors[color] );
points.push(c);
//colors.push(baseColors[color]);
// points.push(a);
}
function tetra( a, b, c, d )
{
// tetrahedron with each side using
// a different color
triangle( a, c, b, 0 );
triangle( a, c, d, 1 );
triangle( a, b, d, 2 );
triangle( b, c, d, 3 ); //bcd
}
function divideTetra( a, b, c, d, count )
{
// check for end of recursion
if ( count === 0 ) {
tetra( a, b, c, d );
}
// find midpoints of sides
// divide four smaller tetrahedra
else {
var ab = mix( a, b, 0.5 );
var ac = mix( a, c, 0.5 );
var ad = mix( a, d, 0.5 );
var bc = mix( b, c, 0.5 );
var bd = mix( b, d, 0.5 );
var cd = mix( c, d, 0.5 );
--count;
divideTetra( a, ab, ac, ad, count );
divideTetra( ab, b, bc, bd, count );
divideTetra( ac, bc, c, cd, count );
divideTetra( ad, bd, cd, d, count );
}
}
function render()
{
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
//gl.drawArrays(gl.TRIANGLES, 0, points.length);
theta += dir * dtheta * (speed / 100);
gl.uniform1f(thetaLoc, theta);
gl.drawArrays(gl.TRIANGLES, 0, points.length);
requestAnimFrame(render);
}
这是HTML:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>3D Sierpinski Gasket</title>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec3 vPosition;
attribute vec3 vColor;
varying vec4 color;
uniform float theta;
void
main()
{
gl_Position = vec4(vPosition, 1.0);
color = vec4(vColor, 1.0);
float s = sin( theta );
float c = cos( theta );
gl_Position.x = -s * vPosition.z + c * vPosition.x;
gl_Position.z = s * vPosition.x + c * vPosition.z;
gl_Position.z = 0.0;
gl_Position.w = 1.0;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 color;
void
main()
{
gl_FragColor = color;
}
</script>
<script type="text/javascript" src="Common/webgl-utils.js"></script>
<script type="text/javascript" src="Common/initShaders.js"></script>
<script type="text/javascript" src="Common/MV.js"></script>
<script type="text/javascript" src="3DSierpinskiTriangle.js"></script>
</head>
<body>
<canvas id="gl-canvas" width="512" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
三角形的背面是透明的,但是如果您查看baseColors数组,则会看到背面有额外的颜色。
答案 0 :(得分:3)
我不是WebGL专家,但是您似乎正在覆盖顶点着色器中的gl_Position.z
值。
gl_Position.x = -s * vPosition.z + c * vPosition.x;
gl_Position.z = s * vPosition.x + c * vPosition.z;
gl_Position.z = 0.0; // <--- REMOVE THIS LINE
gl_Position.w = 1.0;
正确删除该行将呈现所有4个面的四面体。