BufferGeometry не виден
Некоторое время я использовал BufferGeometry, и я подумал, что довольно хорошо с ним знаком. Сейчас я пытаюсь создать простую квадратную плоскость, и она ничего не делает - ни видимой плоскости, ни ошибок, ни очевидных проблем, насколько я вижу. Я видел другие посты здесь, которые похожи, но ни одно из решений не было успешным.
Когда я осматриваю сцену, сетка там, у нее есть подходящий материал, и ее геометрия, кажется, настроена правильно. Но все, что я получаю, это черный видовой экран. Я должен пропустить болезненно очевидный / простой шаг, но сейчас он уклоняется от меня. Что я делаю неправильно?
Скрипка + код: http://jsfiddle.net/TheJim01/kafybhge/34/
// BufferGeometry Tester
var hostDiv, scene, renderer, camera, root, controls, light;
var WIDTH = 500;//window.innerWidth,
HEIGHT = 500;//window.innerHeight,
FOV = 35,
NEAR = 1,
FAR = 1000;
function createBufferGeometryMesh(){
var geo = new THREE.BufferGeometry();
var vertices =
[
-10., 10., 0., // 0 - top left
10., 10., 0., // 1 - top right
10., -10., 0., // 2 - bottom right
-10., -10., 0. // 3 - bottom left
],
normals =
[
0., 0., 1.,
0., 0., 1.,
0., 0., 1.,
0., 0., 1.
],
indices = [ 0, 1, 2, 0, 2, 3 ];
geo.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
geo.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
geo.addAttribute( 'index', new THREE.BufferAttribute( new Uint32Array( indices ), 1 ) );
var mat = new THREE.MeshPhongMaterial( {
color: 0xffffff,
ambient: 0xffffff,
specular: 0xffffff,
shininess: 50,
side: THREE.DoubleSide
} );
var msh = new THREE.Mesh(geo, mat);
return msh;
}
function init() {
hostDiv = document.createElement('div');
document.body.appendChild(hostDiv);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(WIDTH, HEIGHT);
hostDiv.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
camera.position.z = 50;
controls = new THREE.TrackballControls(camera, renderer.domElement);
light = new THREE.PointLight(0xffffff, 1, 1000);
light.position.copy(camera.position);
scene = new THREE.Scene();
scene.add(camera);
scene.add(light);
var square = createBufferGeometryMesh();
scene.add(square);
animate();
}
function render() {
renderer.render(scene, camera);
}
function animate() {
light.position.copy(camera.position);
requestAnimationFrame(animate);
render();
controls.update();
}
init();
Просто чтобы показать, что я не новичок в BufferGeometry, вот кое-что, что я сделал ранее, и это работает, если я вставлю его в свой код вместо createBufferGeometryMesh()
выше. Я попытался определить буферы, как показано ниже (и даже явно), но это ничего не изменило.
function colorCube(scale){
scale = scale || 1;
var geo = new THREE.BufferGeometry();
var positions = new Float32Array( 72 );
var normals = new Float32Array( 72 );
var colors = new Float32Array( 72 );
var indices = new Uint16Array( 36 );
var face = 0, idx = 0, vert = 0;
var x = 0, r = 0, y = 1, g = 1, z = 2, b = 2;
// front face (RED)
positions[vert + x] = 0.5; positions[vert + y] = 0.5; positions[vert + z] = 0.5;
normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = 1.;
colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 0.;
vert += 3;
positions[vert + x] = -0.5; positions[vert + y] = 0.5; positions[vert + z] = 0.5;
normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = 1.;
colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 0.;
vert += 3;
positions[vert + x] = -0.5; positions[vert + y] = -0.5; positions[vert + z] = 0.5;
normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = 1.;
colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 0.;
vert += 3;
positions[vert + x] = 0.5; positions[vert + y] = -0.5; positions[vert + z] = 0.5;
normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = 1.;
colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 0.;
vert += 3;
indices[idx + 0] = (face * 4) + 0; indices[idx + 1] = (face * 4) + 1; indices[idx + 2] = (face * 4) + 2;
indices[idx + 3] = (face * 4) + 0; indices[idx + 4] = (face * 4) + 2; indices[idx + 5] = (face * 4) + 3;
idx += 6;
++face;
// back face (BLUE)
positions[vert + x] = -0.5; positions[vert + y] = 0.5; positions[vert + z] = -0.5;
normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = -1.;
colors[vert + r] = 0.; colors[vert + g] = 0.; colors[vert + b] = 1.;
vert += 3;
positions[vert + x] = 0.5; positions[vert + y] = 0.5; positions[vert + z] = -0.5;
normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = -1.;
colors[vert + r] = 0.; colors[vert + g] = 0.; colors[vert + b] = 1.;
vert += 3;
positions[vert + x] = 0.5; positions[vert + y] = -0.5; positions[vert + z] = -0.5;
normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = -1.;
colors[vert + r] = 0.; colors[vert + g] = 0.; colors[vert + b] = 1.;
vert += 3;
positions[vert + x] = -0.5; positions[vert + y] = -0.5; positions[vert + z] = -0.5;
normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = -1.;
colors[vert + r] = 0.; colors[vert + g] = 0.; colors[vert + b] = 1.;
vert += 3;
indices[idx + 0] = (face * 4) + 0; indices[idx + 1] = (face * 4) + 1; indices[idx + 2] = (face * 4) + 2;
indices[idx + 3] = (face * 4) + 0; indices[idx + 4] = (face * 4) + 2; indices[idx + 5] = (face * 4) + 3;
idx += 6;
++face;
// right face (GREEN)
positions[vert + x] = 0.5; positions[vert + y] = 0.5; positions[vert + z] = -0.5;
normals[vert + x] = 1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 0.;
vert += 3;
positions[vert + x] = 0.5; positions[vert + y] = 0.5; positions[vert + z] = 0.5;
normals[vert + x] = 1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 0.;
vert += 3;
positions[vert + x] = 0.5; positions[vert + y] = -0.5; positions[vert + z] = 0.5;
normals[vert + x] = 1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 0.;
vert += 3;
positions[vert + x] = 0.5; positions[vert + y] = -0.5; positions[vert + z] = -0.5;
normals[vert + x] = 1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 0.;
vert += 3;
indices[idx + 0] = (face * 4) + 0; indices[idx + 1] = (face * 4) + 1; indices[idx + 2] = (face * 4) + 2;
indices[idx + 3] = (face * 4) + 0; indices[idx + 4] = (face * 4) + 2; indices[idx + 5] = (face * 4) + 3;
idx += 6;
++face;
// left face (MAGENTA)
positions[vert + x] = -0.5; positions[vert + y] = 0.5; positions[vert + z] = 0.5;
normals[vert + x] = -1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 1.;
vert += 3;
positions[vert + x] = -0.5; positions[vert + y] = 0.5; positions[vert + z] = -0.5;
normals[vert + x] = -1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 1.;
vert += 3;
positions[vert + x] = -0.5; positions[vert + y] = -0.5; positions[vert + z] = -0.5;
normals[vert + x] = -1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 1.;
vert += 3;
positions[vert + x] = -0.5; positions[vert + y] = -0.5; positions[vert + z] = 0.5;
normals[vert + x] = -1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 1.;
vert += 3;
indices[idx + 0] = (face * 4) + 0; indices[idx + 1] = (face * 4) + 1; indices[idx + 2] = (face * 4) + 2;
indices[idx + 3] = (face * 4) + 0; indices[idx + 4] = (face * 4) + 2; indices[idx + 5] = (face * 4) + 3;
idx += 6;
++face;
// top face (CYAN)
positions[vert + x] = 0.5; positions[vert + y] = 0.5; positions[vert + z] = -0.5;
normals[vert + x] = 0.; normals[vert + y] = 1.; normals[vert + z] = 0.;
colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 1.;
vert += 3;
positions[vert + x] = -0.5; positions[vert + y] = 0.5; positions[vert + z] = -0.5;
normals[vert + x] = 0.; normals[vert + y] = 1.; normals[vert + z] = 0.;
colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 1.;
vert += 3;
positions[vert + x] = -0.5; positions[vert + y] = 0.5; positions[vert + z] = 0.5;
normals[vert + x] = 0.; normals[vert + y] = 1.; normals[vert + z] = 0.;
colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 1.;
vert += 3;
positions[vert + x] = 0.5; positions[vert + y] = 0.5; positions[vert + z] = 0.5;
normals[vert + x] = 0.; normals[vert + y] = 1.; normals[vert + z] = 0.;
colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 1.;
vert += 3;
indices[idx + 0] = (face * 4) + 0; indices[idx + 1] = (face * 4) + 1; indices[idx + 2] = (face * 4) + 2;
indices[idx + 3] = (face * 4) + 0; indices[idx + 4] = (face * 4) + 2; indices[idx + 5] = (face * 4) + 3;
idx += 6;
++face;
// bottom face (YELLOW)
positions[vert + x] = 0.5; positions[vert + y] = -0.5; positions[vert + z] = 0.5;
normals[vert + x] = 0.; normals[vert + y] = -1.; normals[vert + z] = 0.;
colors[vert + r] = 1.; colors[vert + g] = 1.; colors[vert + b] = 0.;
vert += 3;
positions[vert + x] = -0.5; positions[vert + y] = -0.5; positions[vert + z] = 0.5;
normals[vert + x] = 0.; normals[vert + y] = -1.; normals[vert + z] = 0.;
colors[vert + r] = 1.; colors[vert + g] = 1.; colors[vert + b] = 0.;
vert += 3;
positions[vert + x] = -0.5; positions[vert + y] = -0.5; positions[vert + z] = -0.5;
normals[vert + x] = 0.; normals[vert + y] = -1.; normals[vert + z] = 0.;
colors[vert + r] = 1.; colors[vert + g] = 1.; colors[vert + b] = 0.;
vert += 3;
positions[vert + x] = 0.5; positions[vert + y] = -0.5; positions[vert + z] = -0.5;
normals[vert + x] = 0.; normals[vert + y] = -1.; normals[vert + z] = 0.;
colors[vert + r] = 1.; colors[vert + g] = 1.; colors[vert + b] = 0.;
vert += 3;
indices[idx + 0] = (face * 4) + 0; indices[idx + 1] = (face * 4) + 1; indices[idx + 2] = (face * 4) + 2;
indices[idx + 3] = (face * 4) + 0; indices[idx + 4] = (face * 4) + 2; indices[idx + 5] = (face * 4) + 3;
idx += 6;
++face;
geo.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) );
geo.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
geo.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
geo.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
var mat = new THREE.MeshPhongMaterial( {
color: 0xffffff,
ambient: 0xffffff,
specular: 0xffffff,
shininess: 50,
side: THREE.DoubleSide,
vertexColors: THREE.VertexColors
} );
var msh = new THREE.Mesh(geo, mat);
msh.scale.multiplyScalar(scale);
return msh;
}
1 ответ
Поскольку WestLangley скромен, вот что пошло не так в моем коде выше.
Моим главным умственным препятствием было то, что у меня было неправильное представление о функции нормалей в отношении рисования лиц. Я пришел к мысли, что нормали вершин могут определять направление лица, но это просто неправда. Вершинные нормали используются для расчета освещения на поверхности и не имеют никакого отношения к определению направления лица. Это порядок вершин, который определяет направление лица (нормаль лица). Чтобы добавить к этому, я использовал левую систему, когда three.js использует правую систему.
В моем исходном коде у меня было:
indices = [ 0, 1, 2, 0, 2, 3 ];
Чтобы нарисовать грани в правильном направлении, это должно было быть:
indices = [ 0, 2, 1, 0, 3, 2 ];
Различия невелики, но в моем примере они означают разницу между нормалью лица, указывающей в направлениях -Z и +Z соответственно. Лица были обращены не туда, чтобы получить свет. Явные нормали даже не вступили в игру, потому что поверхность все равно не отражала свет. Индексирование с использованием правой системы фиксировало направления лица.
С вопросом о направлении лица позади меня я выполнил упражнение, чтобы укрепить свое понимание, где я перевернул свои вершинные нормали, чтобы (еще раз) указать в противоположном направлении нормали лица. Как и ожидалось (на этот раз), квадрат стал черным. Несмотря на то, что лица указывали в правильном направлении, нормали в основном указывали GL отражать освещение в направлении объекта, превращая его в черную дыру.
Вкратце об этом я расскажу так: направление лица (лицо нормальное) рассчитывается по порядку вершин, составляющих лицо, и использует RHS. Нормы вершин влияют на освещение на поверхности лица и не имеют никакого отношения к определению направления лица.