I'm visualizing some paths using TubeGeometry from a CatmullRomCurve3. Some paths work fine, but some result in faceless geometries.
Here is one of the paths that doesn't work: https://jsfiddle.net/ot0ejgvb/1/
(Relevant code starts at line 1067)
Part of the code is replicated here:
let coords = [
[102.823, 82.058, 0.2],[102.823, 82.058, 0.2],[102.823, 82.058, 0.2],
[103.865, 81.876, 0.2],[146.022, 81.873, 0.2],[147.129, 82.045, 0.2],
[148.051, 82.44, 0.2],[148.89, 83.075, 0.2],[149.502, 83.802, 0.2],
[149.906, 84.535, 0.2],[152.654, 90.769, 0.2],[152.96, 91.93, 0.2],
[152.914, 93.091, 0.2],[150.307, 106.839, 0.2],[150.105, 107.545, 0.2],
[149.758, 108.186, 0.2],[134.594, 127.839, 0.2],[134.121, 128.348, 0.2],
[133.487, 128.793, 0.2],[132.444, 129.266, 0.2],[131.426, 129.413, 0.2],
[118.676, 129.416, 0.2],[117.579, 129.268, 0.2],[116.498, 128.783, 0.2],
[115.814, 128.29, 0.2],[115.199, 127.575, 0.2],[100.368, 108.359, 0.2],
[99.878, 107.448, 0.2],[99.702, 106.826, 0.2],[97.09, 93.11, 0.2],
[97.018, 92.208, 0.2],[97.275, 90.94, 0.2],[100.091, 84.543, 0.2],
[100.444, 83.885, 0.2],[101.077, 83.108, 0.2],[101.888, 82.475, 0.2],
[102.768, 82.082, 0.2],[102.768, 82.082, 0.2]
];
let curve = new THREE.CatmullRomCurve3(coords.map(([x, y, z]) => new THREE.Vector3(x, y, z)));
var geometry = new THREE.TubeGeometry(curve, coords.length, 2, 8, false);
What's going on, and how do I prevent it?
What's going on, and how do I prevent it?
TubeGeometry computes frenet frame in order to generate the vertex data. This computation produces invalid output if you have duplicated points in your array. If you remove these points, the generation works again.
const renderer = new THREE.WebGLRenderer({
antialias: true
});
const width = window.innerWidth;
const height = window.innerHeight;
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
camera.position.y = 160;
camera.position.z = 800;
camera.lookAt(new THREE.Vector3(100, 80, 0));
const controls = new THREE.OrbitControls(camera, renderer.domElement);
const light = new THREE.PointLight(0xffffff, 1, 0);
scene.add(light)
const coords = [
[102.823, 82.058, 0.2],
[103.865, 81.876, 0.2],
[146.022, 81.873, 0.2],
[147.129, 82.045, 0.2],
[148.051, 82.44, 0.2],
[148.89, 83.075, 0.2],
[149.502, 83.802, 0.2],
[149.906, 84.535, 0.2],
[152.654, 90.769, 0.2],
[152.96, 91.93, 0.2],
[152.914, 93.091, 0.2],
[150.307, 106.839, 0.2],
[150.105, 107.545, 0.2],
[149.758, 108.186, 0.2],
[134.594, 127.839, 0.2],
[134.121, 128.348, 0.2],
[133.487, 128.793, 0.2],
[132.444, 129.266, 0.2],
[131.426, 129.413, 0.2],
[118.676, 129.416, 0.2],
[117.579, 129.268, 0.2],
[116.498, 128.783, 0.2],
[115.814, 128.29, 0.2],
[115.199, 127.575, 0.2],
[100.368, 108.359, 0.2],
[99.878, 107.448, 0.2],
[99.702, 106.826, 0.2],
[97.09, 93.11, 0.2],
[97.018, 92.208, 0.2],
[97.275, 90.94, 0.2],
[100.091, 84.543, 0.2],
[100.444, 83.885, 0.2],
[101.077, 83.108, 0.2],
[101.888, 82.475, 0.2],
[102.768, 82.082, 0.2]
];
const curve = new THREE.CatmullRomCurve3(coords.map(([x, y, z]) => new THREE.Vector3(x, y, z)));
const material = new THREE.MeshLambertMaterial({
color: 0xff0000,
emissive: 0x555555,
emissiveIntensity: .5,
side: THREE.DoubleSide
});
const geometry = new THREE.TubeGeometry(curve, coords.length, 2, 8, false);
geometry.center();
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
body {
margin: 0;
}
canvas {
display: block;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.116.1/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.116.1/examples/js/controls/OrbitControls.js"></script>
Related
I have a BufferGeometry triangular prism; where I have specified the 6 vertices and then added indexes to create the 8 faces (2 triangle faces per square plane).
I have then setup 5 groups, so that each side of the prism is a group.
And it works here when I have a single material assigned to the whole object: https://jsfiddle.net/30ez17dw/1/
However I want to be able to assign an array of materials, so that each side (group) has it's own materials. But when I do this the object disappears:
https://jsfiddle.net/30ez17dw/2/
How can I fix my code to make the array of materials work?
You have not specified your groups correctly. Try it like so:
var camera, scene, renderer;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.01, 10);
camera.position.z = 5;
camera.position.y = 2;
camera.lookAt(0, 0, 0);
scene = new THREE.Scene();
var geometry = new THREE.BufferGeometry();
const y = 0.866025404;
const y2 = 0.5;
const h = 1;
const vertices = new Float32Array([
-y2, 0, 0,
y2, 0, 0,
0, 0, y,
-y2, h, 0,
y2, h, 0,
0, h, y,
]);
const indices = [
0, 1, 2, // Top
5, 4, 3, // Bottom
3, 1, 0, // Back
1, 3, 4, // Back
0, 2, 3, // Left
5, 3, 2, // Left
4, 2, 1, // Right
2, 4, 5, // Right
];
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.setIndex(indices);
geometry.computeVertexNormals();
geometry.clearGroups();
geometry.addGroup(0, 3, 0);
geometry.addGroup(3, 6, 1);
geometry.addGroup(6, 12, 2);
geometry.addGroup(12, 18, 3);
geometry.addGroup(18, 24, 4);
var material = [
new THREE.MeshBasicMaterial({
color: 0x00ff00
}),
new THREE.MeshBasicMaterial({
color: 0xff0000
}),
new THREE.MeshBasicMaterial({
color: 0x0000ff,
}),
new THREE.MeshBasicMaterial({
color: 0xffff00
}),
new THREE.MeshBasicMaterial({
color: 0x00ffff
})
];
var mesh = new THREE.Mesh(geometry, material); // , side: THREE.DoubleSide
scene.add(mesh);
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.132.0/build/three.min.js"></script>
The indices you pass to addGroup() are meant to be consecutive.
Trying to create a tetrahedron with three triangles. I could'nt orient faces. Here is the code :
HTML
<div id="myid"></div>
JAVASCRIPT
const divid = document.getElementById("myid");
let facesVectors = [ // triangles vertices
[0, 0, 0],
[-1, 0, 0],
[0, 1, 0],
]
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
1,
1000
);
let renderer = new THREE.WebGLRenderer({ alpha: true });
divid.appendChild(renderer.domElement);
camera.position.z = 2.5;
// equilateral triangle template
const geometry = new THREE.Geometry()
geometry.vertices.push(new THREE.Vector3(-0.48, 0, 0))
geometry.vertices.push(new THREE.Vector3(0.48, 0, 0))
geometry.vertices.push(new THREE.Vector3(0, 0.72, 0))
geometry.faces.push(new THREE.Face3(0, 1, 2))
let material, face, i
let faces = []
for (i = 0; i < facesVectors.length; i++) {
material = new THREE.MeshBasicMaterial({ color: 0x00FF00, side: THREE.DoubleSide })
face = new THREE.Mesh(geometry, material)
face.position.set(facesVectors[i][0], facesVectors[i][1], facesVectors[i][2])
if (i === 1) {
face.rotation.x = -(Math.PI / 2)
} else if (i === 2) {
face.rotation.x = -(Math.PI / 2)
}
faces.push(face)
scene.add(face)
}
let animate = function() {
requestAnimationFrame(animate);
faces.forEach((face)=>{
face.rotation.x += 0.005;
face.rotation.y += 0.01;
})
renderer.render(scene, camera);
};
animate();
demo : https://codepen.io/jeffprod/pen/GRJGYoQ
How to rotate triangles 1 and 2 so that i get a tetrahedron ? Is there a simplest way to do ?
Of course i don't want to use the TetrahedronBufferGeomety because i will need to manage faces colors and a lot of other triangles oriented differently.
Based on this forum topic. Just commented out two lines for faces and uvs:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.set(0, -1, 2);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
// tetrahedron
// ---------------------------------------------------------------------------------------
var pts = [ // https://en.wikipedia.org/wiki/Tetrahedron#Coordinates_for_a_regular_tetrahedron
new THREE.Vector3(Math.sqrt(8 / 9), 0, -(1 / 3)),
new THREE.Vector3(-Math.sqrt(2 / 9), Math.sqrt(2 / 3), -(1 / 3)),
new THREE.Vector3(-Math.sqrt(2 / 9), -Math.sqrt(2 / 3), -(1 / 3)),
new THREE.Vector3(0, 0, 1)
];
var faces = [ // triangle soup
//pts[0].clone(), pts[2].clone(), pts[1].clone(),
pts[0].clone(), pts[1].clone(), pts[3].clone(),
pts[1].clone(), pts[2].clone(), pts[3].clone(),
pts[2].clone(), pts[0].clone(), pts[3].clone()
];
var geom = new THREE.BufferGeometry().setFromPoints(faces);
geom.rotateX(-Math.PI * 0.5);
geom.computeVertexNormals();
geom.setAttribute("uv", new THREE.Float32BufferAttribute([ // UVs
//0.5, 1, 0.06698729810778059, 0.2500000000000001, 0.9330127018922194, 0.2500000000000001,
0.06698729810778059, 0.2500000000000001, 0.9330127018922194, 0.2500000000000001, 0.5, 1,
0.06698729810778059, 0.2500000000000001, 0.9330127018922194, 0.2500000000000001, 0.5, 1,
0.06698729810778059, 0.2500000000000001, 0.9330127018922194, 0.2500000000000001, 0.5, 1
], 2));
// ---------------------------------------------------------------------------------------
var tetrahedron = new THREE.Mesh(geom, new THREE.MeshBasicMaterial({
map: new THREE.TextureLoader().load("https://threejs.org/examples/textures/uv_grid_opengl.jpg"),
side: THREE.DoubleSide
}));
scene.add(tetrahedron);
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
});
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
It seems that when an object casts and receives shadows you get this bright edge that looks like light bleeding through. Is there any way to overcome this? In the snippet I give here you can see that the shadow from the cylinder on the two cubes doesn't have the issue in the picture, but on the back is where you see the line happening.
width = window.innerWidth
height = window.innerHeight
renderer = new THREE.WebGLRenderer({antialias: true})
renderer.setClearColor(0xeeeeee)
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(width, height)
document.body.appendChild(renderer.domElement)
scene = new THREE.Scene()
camera = new THREE.PerspectiveCamera(35, width / height, 0.1, 3000)
camera.position.set(-45, 47, 75)
controls = new THREE.OrbitControls(camera, renderer.domElement)
controls.minDistance = 40
controls.maxDistance = 1300
material = new THREE.MeshPhongMaterial({color: 0xFF0000, specular: 0x111111, shininess: 75})
scene.add(camera, new THREE.AmbientLight(0xffffff, 0.4))
light = new THREE.PointLight(0xffffff, 0.8)
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFShadowMap
light.castShadow = true
light.shadow.mapSize.width = 3072
light.shadow.mapSize.height = 3072
light.shadow.camera.left = 500
function shadow(w) {
w.castShadow = true
w.receiveShadow = true
}
camera.add(light)
light.position.y += 60
light.position.x += 70
requestAnimationFrame(function animate(){
requestAnimationFrame(animate)
renderer.render(scene, camera)
})
b = new THREE.Mesh(new THREE.BoxGeometry(20, 20, 20), material)
shadow(b)
scene.add(b)
c = new THREE.Mesh(new THREE.CylinderGeometry(5,5,10,32), material)
c.position.set(3,15,3)
shadow(c)
scene.add(c)
d = new THREE.Mesh(new THREE.BoxGeometry(20, 10, 1), material)
d.position.set(3,15,-5)
shadow(d)
scene.add(d)
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
I have a geometry of a cube that I need to texture,
In the top of the cube - need to be one image
And in each side of the cube - need to be a second image that vertically repeat based on the cube height
This is the texture:
This is what I need:
And this is what I have so far: three.js/texture1
Any ideas how to achieve what I need, but stay with one material and a few faces as possible?
Thanks.
My code:
function create_geometry() {
var geometry = new THREE.Geometry();
var w = 0.5;
var h = 1;
geometry.vertices.push(
new THREE.Vector3(w, h, w),
new THREE.Vector3(w, h, -w),
new THREE.Vector3(w, 0, w),
new THREE.Vector3(w, 0, -w),
new THREE.Vector3(-w, h, -w),
new THREE.Vector3(-w, h, w),
new THREE.Vector3(-w, 0, -w),
new THREE.Vector3(-w, 0, w)
);
geometry.faces.push(
// wall
new THREE.Face3(0, 2, 1),
new THREE.Face3(2, 3, 1),
// wall
new THREE.Face3(4, 6, 5),
new THREE.Face3(6, 7, 5),
// wall
new THREE.Face3(5, 7, 0),
new THREE.Face3(7, 2, 0),
// wall
new THREE.Face3(1, 3, 4),
new THREE.Face3(3, 6, 4),
//roof
new THREE.Face3(4, 5, 1),
new THREE.Face3(5, 0, 1),
);
geometry.computeFaceNormals();
geometry.faceVertexUvs[0] = [];
geometry.faces[0].materialIndex = 0;
geometry.faces[1].materialIndex = 0;
geometry.faces[2].materialIndex = 0;
geometry.faces[3].materialIndex = 0;
geometry.faces[4].materialIndex = 0;
geometry.faces[5].materialIndex = 0;
geometry.faces[6].materialIndex = 0;
geometry.faces[7].materialIndex = 0;
geometry.faces[8].materialIndex = 0;
geometry.faces[9].materialIndex = 0;
var roof = [
new THREE.Vector2(0.0,1.0),
new THREE.Vector2(0.0,0.5),
new THREE.Vector2(1.0,0.5),
new THREE.Vector2(1.0,1.0),
];
var wall = [
new THREE.Vector2(0.0,0.5),
new THREE.Vector2(0.0,0.0),
new THREE.Vector2(1.0,0.0),
new THREE.Vector2(1.0,0.5),
];
// wall
geometry.faceVertexUvs[0][0] = [ wall[0], wall[1], wall[3] ];
geometry.faceVertexUvs[0][1] = [ wall[1], wall[2], wall[3] ];
// wall
geometry.faceVertexUvs[0][2] = [ wall[0], wall[1], wall[3] ];
geometry.faceVertexUvs[0][3] = [ wall[1], wall[2], wall[3] ];
// wall
geometry.faceVertexUvs[0][4] = [ wall[0], wall[1], wall[3] ];
geometry.faceVertexUvs[0][5] = [ wall[1], wall[2], wall[3] ];
// wall
geometry.faceVertexUvs[0][6] = [ wall[0], wall[1], wall[3] ];
geometry.faceVertexUvs[0][7] = [ wall[1], wall[2], wall[3] ];
// roof
geometry.faceVertexUvs[0][8] = [ roof[0], roof[1], roof[3] ];
geometry.faceVertexUvs[0][9] = [ roof[1], roof[2], roof[3] ];
var matrix = new THREE.Matrix4();
//matrix.makeRotationX ( (270 * Math.PI)/180 );
geometry.applyMatrix( matrix );
geometry.uvsNeedUpdate = true;
return geometry;
}
var renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize(800,800);
var container = document.getElementById("container");
container.appendChild(renderer.domElement);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45,800/800,1,1000);
camera.position.set(0,10,20);
scene.add(camera);
var controls = new THREE.TrackballControls( camera, renderer.domElement );
controls.minDistance = 15;
controls.maxDistance = 100;
var stats = new Stats();
container.appendChild( stats.dom );
var rendererStats = new THREEx.RendererStats();
rendererStats.domElement.style.position = 'absolute';
rendererStats.domElement.style.right = '0px';
rendererStats.domElement.style.top = '0px';
document.body.appendChild( rendererStats.domElement );
// plane
var plane = new THREE.Mesh(
new THREE.PlaneGeometry( 80, 80, 1 ),
new THREE.MeshBasicMaterial( {color: 0x333333, side: THREE.DoubleSide} )
);
plane.rotation.x = (90 * Math.PI)/180;
scene.add(plane);
//
var geometry = create_geometry();
var texture = new THREE.TextureLoader().load( "texture1.png" );
var material = new THREE.MeshBasicMaterial({ map:texture });
for(var i=0; i<10; i++) {
var cube = new THREE.Mesh( geometry, material );
cube.position.x = i*1.5 - 5*1.5;
//cube.position.y = Math.random()*80 - 40;
cube.scale.y = i + 1;
scene.add( cube );
}
function render() {
controls.update();
stats.update();
rendererStats.update(renderer);
renderer.render( scene, camera );
requestAnimationFrame( render );
}
render();
I've been playing with THREE.InstancedBufferGeometry. I finally got an example to work, and have now been playing with the shader. The first thing I tried was setting transparency. My example code is below.
The initial state, and from a host of other camera angles (e.g. drag your mouse to the left), the transparency doesn't seem to have any effect. But then at other camera angles (e.g. reload and drag your mouse to the right), the shapes clearly overlap, which is what I was expecting.
Is depth-sorting handled differently for instanced shapes, or am I doing something wrong, or missing something? Do I somehow need to update the shapes so the camera knows their proper depth in the scene?
var cubeGeo = new THREE.InstancedBufferGeometry().copy(new THREE.BoxBufferGeometry(10, 10, 10));
//cubeGeo.maxInstancedCount = 8;
cubeGeo.addAttribute("cubePos", new THREE.InstancedBufferAttribute(new Float32Array([
25, 25, 25,
25, 25, -25, -25, 25, 25, -25, 25, -25,
25, -25, 25,
25, -25, -25, -25, -25, 25, -25, -25, -25
]), 3, 1));
var vertexShader = [
"precision highp float;",
"",
"uniform mat4 modelViewMatrix;",
"uniform mat4 projectionMatrix;",
"",
"attribute vec3 position;",
"attribute vec3 cubePos;",
"",
"void main() {",
"",
" gl_Position = projectionMatrix * modelViewMatrix * vec4( cubePos + position, 1.0 );",
"",
"}"
].join("\n");
var fragmentShader = [
"precision highp float;",
"",
"void main() {",
"",
" gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);",
"",
"}"
].join("\n");
var mat = new THREE.RawShaderMaterial({
uniforms: {},
vertexShader: vertexShader,
fragmentShader: fragmentShader,
transparent: true
});
var mesh = new THREE.Mesh(cubeGeo, mat);
scene.add(mesh);
html * {
padding: 0;
margin: 0;
width: 100%;
overflow: hidden;
}
#host {
width: 100%;
height: 100%;
}
<script src="http://threejs.org/build/three.js"></script>
<script src="http://threejs.org/examples/js/controls/TrackballControls.js"></script>
<script src="http://threejs.org/examples/js/libs/stats.min.js"></script>
<div id="host"></div>
<script>
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight,
FOV = 35,
NEAR = 1,
FAR = 1000;
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(WIDTH, HEIGHT);
document.getElementById('host').appendChild(renderer.domElement);
var stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0';
document.body.appendChild(stats.domElement);
var camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
camera.position.z = 250;
var trackballControl = new THREE.TrackballControls(camera, renderer.domElement);
trackballControl.rotateSpeed = 2.0; // need to speed it up a little
var scene = new THREE.Scene();
var light = new THREE.PointLight(0xffffff, 1, Infinity);
camera.add(light);
scene.add(light);
function render() {
if (typeof updateVertices !== "undefined") {
updateVertices();
}
renderer.render(scene, camera);
stats.update();
}
function animate() {
requestAnimationFrame(animate);
trackballControl.update();
render();
}
animate();
</script>
You are using InstancedBufferGeometry with meshes that are translucent.
The instances are rendered in the order they appear in the buffer. The faces of each instance are rendered in the ordered specified by the geometry.
Consequently, if you use instancing with translucency, you will likely have artifacts depending on the viewing angle.
Depending on your use case, you can try setting material.depthWrite = false, but that can lead to other artifacts.
If your mesh textures have areas of complete transparency (rather than partial) you should be able to use material.alphaTest to discard unwanted fragments without artifacts.
three.js r.84
After discussion with WestLangley in the comments, I added a sorter for my instances. It sorts the instances positions based on their distance from the camera.
(Side-note: If I had any other THREE.InstancedBufferAttributes I would need to re-order them at the same time.)
The biggest downside to this is that it becomes more and more expensive as the scene gets bigger, both in instanced and non-instanced shapes.
// Instances Sorter, called each frame
function sortObjectInstances(obj) {
if (obj.geometry) {
if (obj.geometry instanceof THREE.InstancedBufferGeometry) {
var array = obj.geometry.attributes.cubePos.array,
vecArray = [];
for (var i = 0, l = array.length / 3; i < l; ++i) {
vecArray.push(new THREE.Vector3(array[(i * 3)], array[(i * 3) + 1], array[(i * 3) + 2]));
}
vecArray.sort(function(a, b) {
if (a.distanceTo(camera.position) > b.distanceTo(camera.position)) {
return -1;
}
if (a.distanceTo(camera.position) < b.distanceTo(camera.position)) {
return 1;
}
return 0;
});
for (var i = 0, l = vecArray.length; i < l; ++i) {
array[(i * 3)] = vecArray[i].x;
array[(i * 3) + 1] = vecArray[i].y;
array[(i * 3) + 2] = vecArray[i].z;
}
obj.geometry.attributes.cubePos.needsUpdate = true;
}
} else {
for (var i = 0, l = obj.children.length; i < l; ++i) {
sortObjectInstances(obj.children[i]);
}
}
}
var cubeGeo = new THREE.InstancedBufferGeometry().copy(new THREE.BoxBufferGeometry(10, 10, 10));
//cubeGeo.maxInstancedCount = 8;
cubeGeo.addAttribute("cubePos", new THREE.InstancedBufferAttribute(new Float32Array([
25, 25, 25,
25, 25, -25, -25, 25, 25, -25, 25, -25,
25, -25, 25,
25, -25, -25, -25, -25, 25, -25, -25, -25
]), 3, 1));
var vertexShader = [
"precision highp float;",
"",
"uniform mat4 modelViewMatrix;",
"uniform mat4 projectionMatrix;",
"",
"attribute vec3 position;",
"attribute vec3 cubePos;",
"",
"void main() {",
"",
" gl_Position = projectionMatrix * modelViewMatrix * vec4( cubePos + position, 1.0 );",
"",
"}"
].join("\n");
var fragmentShader = [
"precision highp float;",
"",
"void main() {",
"",
" gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);",
"",
"}"
].join("\n");
var mat = new THREE.RawShaderMaterial({
uniforms: {},
vertexShader: vertexShader,
fragmentShader: fragmentShader,
transparent: true
});
var mesh = new THREE.Mesh(cubeGeo, mat);
scene.add(mesh);
html * {
padding: 0;
margin: 0;
width: 100%;
overflow: hidden;
}
#host {
width: 100%;
height: 100%;
}
<script src="http://threejs.org/build/three.js"></script>
<script src="http://threejs.org/examples/js/controls/TrackballControls.js"></script>
<script src="http://threejs.org/examples/js/libs/stats.min.js"></script>
<div id="host"></div>
<script>
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight,
FOV = 35,
NEAR = 1,
FAR = 1000;
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(WIDTH, HEIGHT);
document.getElementById('host').appendChild(renderer.domElement);
var stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0';
document.body.appendChild(stats.domElement);
var camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
camera.position.z = 250;
var trackballControl = new THREE.TrackballControls(camera, renderer.domElement);
trackballControl.rotateSpeed = 2.0; // need to speed it up a little
var scene = new THREE.Scene();
var light = new THREE.PointLight(0xffffff, 1, Infinity);
camera.add(light);
scene.add(light);
function render() {
if (typeof sortObjectInstances !== "undefined") {
sortObjectInstances(scene); // Sort the instances
}
renderer.render(scene, camera);
stats.update();
}
function animate() {
requestAnimationFrame(animate);
trackballControl.update();
render();
}
animate();
</script>