Is there any way to make a quad sphere with BufferGeometry? - three.js

I am new to three.js and I want to build a quad sphere with the BufferGeometry(). I want to recreate sebastin lague cube sphere and implementing in three js.
Here is my TerrainFace.js code:
class {
constructor(resolution, radius, localUp, scene) {
this._resolution = resolution;
this._radius = radius;
this._scene = scene;
this._localUp = localUp;
this._axisA = new THREE.Vector3(localUp.y, localUp.z, localUp.x);
this._axisB = new THREE.Vector3().crossVectors(this._localUp, this._axisA);
this._geometry = new THREE.BufferGeometry();
}
Start() {
this._Initialize();
let plane = new THREE.Mesh(this._geometry, new THREE.MeshBasicMaterial({ color: 0xffffff, wireframe: true }));
this._scene.add(plane);
}
_Initialize() {
let i;
let triIndex = 0;
this._positions = [];
this._normals = [];
this._indices = [];
for (let y = 0; y < this._resolution; y++) {
for (let x = 0; x < this._resolution; x++) {
i = x + (y * this._resolution);
let xPercent = x / (this._resolution - 1);
let yPercent = y / (this._resolution - 1);
let _P = new THREE.Vector3();
let _C = new THREE.Vector3();
let _A = new THREE.Vector3(this._axisA.x, this._axisA.y, this._axisA.z).multiplyScalar(2 * (xPercent - 0.5));
let _B = new THREE.Vector3(this._axisB.x, this._axisB.y, this._axisB.z).multiplyScalar(2 * (yPercent - 0.5));
_C.addVectors(this._localUp, _A);
_P.addVectors(_C, _B);
// _P.normalize(); // this is for cube sphere
_P.multiplyScalar(this._radius);
this._positions[i] = _P.x;
this._positions[i + 1] = _P.y;
this._positions[i + 2] = _P.z;
let ad = new THREE.Mesh(new THREE.SphereGeometry(0.1), new THREE.MeshNormalMaterial({ side: THREE.DoubleSide }));
ad.position.set(this._positions[i], this._positions[i + 1], this._positions[i + 2]);
this._scene.add(ad);
if (x != (this._resolution - 1) && y != (this._resolution - 1)) {
const a = i;
const b = i + 1;
const c = i + this._resolution;
const d = i = this._resolution + 1;
// a - - b
// | |
// | |
// c - - d
this._indices[triIndex] = a;
this._indices[triIndex + 1] = d;
this._indices[triIndex + 2] = c;
this._indices[triIndex + 3] = a;
this._indices[triIndex + 4] = b;
this._indices[triIndex + 5] = d;
triIndex += 6;
}
}
}
this._geometry.setIndex(this._indices);
this._geometry.setAttribute("position", new THREE.Float32BufferAttribute(this._positions, 3));
}
}
This is the basic scene
let groups = new THREE.Group();
let directions = [
new THREE.Vector3(0, 1, 0),
new THREE.Vector3(0, -1, 0),
new THREE.Vector3(1, 0, 0),
new THREE.Vector3(-1, 0, 0),
new THREE.Vector3(0, 0, 1),
new THREE.Vector3(0, 0, -1),
]
for (let i = 0; i < directions.length; i++) {
let plane = new TerrainFace1(2, 10, directions[i], groups);
plane.Start();
}
this._scene.add(groups);
for some reason It is not working and it is creating some weird shapes and I dont know why. Thanks.

Follow SebastianLague sphere generation.

Related

Rotation animation on another axis

I'm trying to rotate objects on a different axis than the default one, and with animation.
Here is actually how i am doing it. You can click on buttons L and Li that actually work. But as you can see for the R button the axis of rotation should be changed. I can't figure how to do this. Am I doing things right about this kind of rotation animation ?
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.set(-2, 1, 3);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight - 60); // -60 to see buttons below
const divid = document.getElementById('myid');
divid.appendChild(renderer.domElement);
// show axis
scene.add(new THREE.AxesHelper(2))
let controls = new THREE.OrbitControls(camera, renderer.domElement);
// one triangle equilateral
const sideLength = 1
const x = 0
const y = 0
const geometry = new THREE.Geometry()
geometry.vertices.push(new THREE.Vector3(x, (Math.sqrt(3) / 2 * sideLength) - (sideLength / 2), 0))
geometry.vertices.push(new THREE.Vector3(x - (sideLength / 2), y - (sideLength / 2), 0))
geometry.vertices.push(new THREE.Vector3(x + (sideLength / 2), y - (sideLength / 2), 0))
geometry.faces.push(new THREE.Face3(0, 1, 2))
const facesColors = [
0xFFFF00, // yellow
0xFF0000, // red
0x0000FF, // blue
0x008000 // green
]
const pos = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 3
]
const d = 0.05 // écart entre les triangles
let face
const facesVectors = [
[0, 1, 2],
[0, 2, 3],
[0, 3, 1],
[1, 3, 2]
]
// https://stackoverflow.com/questions/60774560/drawing-a-pyraminx-with-triangles
// coords des points d'un tétrahèdre
const s89 = Math.sqrt(8 / 9)
const s29 = Math.sqrt(2 / 9)
const s23 = Math.sqrt(2 / 3)
const v = [
new THREE.Vector3(0, 0, 1),
new THREE.Vector3(s89, 0, -1 / 3),
new THREE.Vector3(-s29, s23, -1 / 3),
new THREE.Vector3(-s29, -s23, -1 / 3)
]
const computeMidPts = (pts) => {
const midPts = []
for (let i = 0; i < pts.length; ++i) {
midPts.push(new THREE.Vector3().lerpVectors(pts[i], pts[(i + 1) % 3], 0.5))
}
return midPts
}
const computeInnerPts = (pts, d) => {
const innerPts = []
for (let i = 0; i < pts.length; ++i) {
const va = new THREE.Vector3().lerpVectors(pts[i], pts[(i + 1) % 3], d)
const vb = new THREE.Vector3().lerpVectors(pts[i], pts[(i + 2) % 3], d)
innerPts.push(new THREE.Vector3().lerpVectors(va, vb, 0.5))
}
return innerPts
}
let allfaces = [];
for (let i = 0; i < 4; ++i) {
const pts = [v[facesVectors[i][0]], v[facesVectors[i][1]], v[facesVectors[i][2]]]
const outerPts = computeInnerPts(pts, d)
for (let j = 0; j < 3; ++j) {
const geometry = new THREE.Geometry()
geometry.vertices.push(outerPts[j])
geometry.vertices.push(new THREE.Vector3().lerpVectors(outerPts[j], outerPts[(j + 1) % 3], 0.5 - d / 2))
geometry.vertices.push(new THREE.Vector3().lerpVectors(outerPts[j], outerPts[(j + 2) % 3], 0.5 - d / 2))
geometry.faces.push(new THREE.Face3(0, 1, 2))
const material = new THREE.MeshBasicMaterial({ color: facesColors[i] })
face = new THREE.Mesh(geometry, material)
allfaces.push(face)
scene.add(face)
}
const midPts = computeMidPts(outerPts)
const innerPts = computeInnerPts(midPts, d / 2)
const geometry = new THREE.Geometry()
geometry.vertices.push(...innerPts)
geometry.faces.push(new THREE.Face3(0, 1, 2))
const material = new THREE.MeshBasicMaterial({ color: facesColors[i] })
face = new THREE.Mesh(geometry, material)
allfaces.push(face)
scene.add(face)
}
let movingL = false
let movingLi = false
let movingR = false
let pivot = null
renderer.setAnimationLoop(() => {
if (movingL) {
pivot.rotation.z += 0.05
if (pivot.rotation.z >= (2 * Math.PI) / 3) {
movingL = false
}
} else if (movingLi) {
pivot.rotation.z -= 0.05
if (pivot.rotation.z <= -(2 * Math.PI) / 3) {
movingLi = false
}
} else if (movingR) {
pivot.rotation.x -= 0.05
if (pivot.rotation.x <= -(2 * Math.PI) / 3) {
movingR = false
}
}
renderer.render(scene, camera);
});
document.getElementById("L").addEventListener("click", function(){
pivot = new THREE.Group();
scene.add(pivot);
// faces to move
pivot.attach(allfaces[0]);
pivot.attach(allfaces[4]);
pivot.attach(allfaces[8]);
movingL = true
});
document.getElementById("Li").addEventListener("click", function(){
pivot = new THREE.Group();
scene.add(pivot);
pivot.attach(allfaces[0]);
pivot.attach(allfaces[4]);
pivot.attach(allfaces[8]);
movingLi = true
});
document.getElementById("R").addEventListener("click", function(){
pivot = new THREE.Group();
scene.add(pivot);
pivot.attach(allfaces[1]);
pivot.attach(allfaces[10]);
pivot.attach(allfaces[12]);
movingR = true
});
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<div id="myid"></div>
<button id="L">L</button>
<button id="Li">Li</button>
<button id="R">R</button>
<button id="Ri">Ri</button>
...
You're going to have to use Quaternions, which are a much more robust method to apply rotations to objects.
Quaternions have a method called .setFromAxisAngle() that you can use to set whatever axis of rotation you want.
In the example below, each time you click a button, I set the axis of rotation and reset the angle of rotation with:
axisVector.set(x, y, z).normalize();
quatAngle = 0;
(normalize ensures the axis always has a total length of 1. Using an axis vector of (2, 0, 0) would break the rotation)
Once you have your axis established, you can rotate the pivot with
quatAngle += 0.05;
pivot.quaternion.setFromAxisAngle(axisVector, quatAngle);
I wasn't exactly sure where the axis of rotation is for R or U, so I just visually estimated them at (1, 0, -0.33) and (-0.4, 0.7, -0.3), then I used .normalize() to make its length 1.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.set(-2, 1, 3);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight - 60); // -60 to see buttons below
const divid = document.getElementById('myid');
divid.appendChild(renderer.domElement);
// show axis
scene.add(new THREE.AxesHelper(2))
let controls = new THREE.OrbitControls(camera, renderer.domElement);
// one triangle equilateral
const sideLength = 1
const x = 0
const y = 0
const geometry = new THREE.Geometry()
geometry.vertices.push(new THREE.Vector3(x, (Math.sqrt(3) / 2 * sideLength) - (sideLength / 2), 0))
geometry.vertices.push(new THREE.Vector3(x - (sideLength / 2), y - (sideLength / 2), 0))
geometry.vertices.push(new THREE.Vector3(x + (sideLength / 2), y - (sideLength / 2), 0))
geometry.faces.push(new THREE.Face3(0, 1, 2))
const facesColors = [
0xFFFF00, // yellow
0xFF0000, // red
0x0000FF, // blue
0x008000 // green
]
const pos = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 3
]
const d = 0.05 // écart entre les triangles
let face
const facesVectors = [
[0, 1, 2],
[0, 2, 3],
[0, 3, 1],
[1, 3, 2]
]
// https://stackoverflow.com/questions/60774560/drawing-a-pyraminx-with-triangles
// coords des points d'un tétrahèdre
const s89 = Math.sqrt(8 / 9)
const s29 = Math.sqrt(2 / 9)
const s23 = Math.sqrt(2 / 3)
const v = [
new THREE.Vector3(0, 0, 1),
new THREE.Vector3(s89, 0, -1 / 3),
new THREE.Vector3(-s29, s23, -1 / 3),
new THREE.Vector3(-s29, -s23, -1 / 3)
]
const computeMidPts = (pts) => {
const midPts = []
for (let i = 0; i < pts.length; ++i) {
midPts.push(new THREE.Vector3().lerpVectors(pts[i], pts[(i + 1) % 3], 0.5))
}
return midPts
}
const computeInnerPts = (pts, d) => {
const innerPts = []
for (let i = 0; i < pts.length; ++i) {
const va = new THREE.Vector3().lerpVectors(pts[i], pts[(i + 1) % 3], d)
const vb = new THREE.Vector3().lerpVectors(pts[i], pts[(i + 2) % 3], d)
innerPts.push(new THREE.Vector3().lerpVectors(va, vb, 0.5))
}
return innerPts
}
let allfaces = [];
for (let i = 0; i < 4; ++i) {
const pts = [v[facesVectors[i][0]], v[facesVectors[i][1]], v[facesVectors[i][2]]]
const outerPts = computeInnerPts(pts, d)
for (let j = 0; j < 3; ++j) {
const geometry = new THREE.Geometry()
geometry.vertices.push(outerPts[j])
geometry.vertices.push(new THREE.Vector3().lerpVectors(outerPts[j], outerPts[(j + 1) % 3], 0.5 - d / 2))
geometry.vertices.push(new THREE.Vector3().lerpVectors(outerPts[j], outerPts[(j + 2) % 3], 0.5 - d / 2))
geometry.faces.push(new THREE.Face3(0, 1, 2))
const material = new THREE.MeshBasicMaterial({ color: facesColors[i] })
face = new THREE.Mesh(geometry, material)
allfaces.push(face)
scene.add(face)
}
const midPts = computeMidPts(outerPts)
const innerPts = computeInnerPts(midPts, d / 2)
const geometry = new THREE.Geometry()
geometry.vertices.push(...innerPts)
geometry.faces.push(new THREE.Face3(0, 1, 2))
const material = new THREE.MeshBasicMaterial({ color: facesColors[i] })
face = new THREE.Mesh(geometry, material)
allfaces.push(face)
scene.add(face)
}
let movingL = false
let movingLi = false
let movingR = false
let movingU = false
let pivot = null
let quatAngle = 0;
let axisVector = new THREE.Vector3();
renderer.setAnimationLoop(() => {
if (movingL) {
quatAngle += 0.05
pivot.quaternion.setFromAxisAngle(axisVector, quatAngle);
if (quatAngle >= (2 * Math.PI) / 3) {
movingL = false
}
} else if (movingLi) {
quatAngle -= 0.05
pivot.quaternion.setFromAxisAngle(axisVector, quatAngle);
if (quatAngle <= -(2 * Math.PI) / 3) {
movingLi = false
}
} else if (movingR) {
quatAngle -= 0.05
pivot.quaternion.setFromAxisAngle(axisVector, quatAngle);
if (quatAngle <= -(2 * Math.PI) / 3) {
movingR = false
}
} else if (movingU) {
quatAngle -= 0.05
pivot.quaternion.setFromAxisAngle(axisVector, quatAngle);
if (quatAngle <= -(2 * Math.PI) / 3) {
movingU = false
}
}
renderer.render(scene, camera);
});
document.getElementById("L").addEventListener("click", function(){
pivot = new THREE.Group();
axisVector.set(0, 0, 1);
quatAngle = 0;
scene.add(pivot);
// faces to move
pivot.attach(allfaces[0]);
pivot.attach(allfaces[4]);
pivot.attach(allfaces[8]);
movingL = true
});
document.getElementById("Li").addEventListener("click", function(){
pivot = new THREE.Group();
axisVector.set(0, 0, 1);
quatAngle = 0;
scene.add(pivot);
pivot.attach(allfaces[0]);
pivot.attach(allfaces[4]);
pivot.attach(allfaces[8]);
movingLi = true
});
document.getElementById("R").addEventListener("click", function(){
pivot = new THREE.Group();
axisVector.set(1, 0, -0.33).normalize();
quatAngle = 0;
scene.add(pivot);
pivot.attach(allfaces[1]);
pivot.attach(allfaces[10]);
pivot.attach(allfaces[12]);
movingR = true
});
document.getElementById("U").addEventListener("click", function(){
pivot = new THREE.Group();
axisVector.set(-0.4, 0.7, -0.3).normalize();
quatAngle = 0;
scene.add(pivot);
pivot.attach(allfaces[2]);
pivot.attach(allfaces[5]);
pivot.attach(allfaces[14]);
movingU = true
});
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<div id="myid"></div>
<button id="L">L</button>
<button id="Li">Li</button>
<button id="R">R</button>
<button id="U">U</button>

Three Js update vertices,normals and indices

this Code renders this :
render of the code
the problem i'm having is can't update the vertices,
in my code i'm trying to update three points just to see if it works.
the geometry has a normal vector and indices so maybe i should update those too.
export default (scene) => {
const noise = new Noise(Math.random());
const geometry = new THREE.BufferGeometry();
let indices = [];
let vertices = [];
let normals = [];
const size = 50;
const segments = 32;
const halfSize = size / 2;
const segmentSize = size / segments;
let xoff = 0,
yoff = 0,
zofff = 0.01;
for (let i = 0; i <= segments; i++) {
const y = i * segmentSize - halfSize;
yoff += 0.01;
for (let j = 0; j <= segments; j++) {
xoff += 0.01;
const dd = noise.perlin3(xoff, yoff, zofff) * 3;
const x = j * segmentSize - halfSize;
vertices.push(x, dd, -y);
normals.push(1, 0, 1);
}
}
for (let i = 0; i < segments; i++) {
for (let j = 0; j < segments; j++) {
const a = i * (segments + 1) + (j + 1);
const b = i * (segments + 1) + j;
const c = (i + 1) * (segments + 1) + j;
const d = (i + 1) * (segments + 1) + (j + 1);
// generate two faces (triangles) per iteration
indices.push(a, b, d); // face one
indices.push(b, c, d); // face two
}
}
geometry.setIndex(indices);
geometry.addAttribute(
'position',
new THREE.Float32BufferAttribute(vertices, 3).setDynamic(true),
);
geometry.addAttribute(
'normal',
new THREE.Float32BufferAttribute(normals, 3).setDynamic(true),
);
const material = new THREE.MeshPhongMaterial({
side: THREE.DoubleSide,
wireframe: true,
color: '0xffffff',
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
let zoff = 0;
function update() {
zoff += 0.1;
vertices[1] = Math.random() * 10;
vertices[4] = Math.random() * 10;
vertices[7] = Math.random() * 10;
mesh.geometry.attributes.position.needsUpdate = true;
mesh.geometry.verticesNeedUpdate = true;
}
Seems, you have to change the buffer attribute with positions, not the initial array.
Thus in your update it should look like this:
function update() {
zoff += 0.1; // the reason to have it here is unknown
geometry.attributes.position.setY(0, Math.random() * 10);
geometry.attributes.position.setY(1, Math.random() * 10);
geometry.attributes.position.setY(2, Math.random() * 10);
geometry.attributes.position.needsUpdate = true;
}

How to make transparent hole to object which has image texture in THREE.js?

I made a house with walls, ceiling and floor.
Now I am trying to make holes in walls for windows/doors.
But there is an issue in textures of the walls.
This is function to build wall:
function build_wall(start, end, materialFront, id){
var dx = end.x - start.x;
var dy = end.y - start.y;
var wall_length = Math.sqrt(dx*dx + dy*dy);
var centroid_x = start.x + dx/2;
var centroid_y = (start.y + dy/2) * -1;
var ry = Math.atan2(dy, dx);
var materialBack = new THREE.MeshLambertMaterial( { color: 0xd9d9d9, shading: THREE.FlatShading, side: THREE.BackSide} );
var materialTop = new THREE.MeshBasicMaterial({color: 0xb3b3b3, side: THREE.DoubleSide});
var materials = [materialFront, materialBack, materialTop];
var material = new THREE.MeshFaceMaterial(materials);
var rectShape = new THREE.Shape();
rectShape.moveTo( 0, 0 );
rectShape.lineTo( 0, wall_height );
rectShape.lineTo( wall_length, wall_height );
rectShape.lineTo( wall_length, 0 );
rectShape.lineTo( 0, 0 );
var windowHole = new THREE.Path();
windowHole.moveTo(20, 180);
windowHole.lineTo(20, 160);
windowHole.lineTo(40, 160);
windowHole.lineTo(40, 180);
rectShape.holes.push(windowHole);
var extrudeSettings = { amount: 5, bevelEnabled: true, bevelSegments: 0, steps: 1, bevelSize: 0, bevelThickness: 1 };
var wall = new THREE.ExtrudeGeometry( rectShape, extrudeSettings );
for ( var face in wall.faces ) {
if (wall.faces[ face ].normal.z > 0.9) wall.faces[ face ].materialIndex = 0;
else if (wall.faces[ face ].normal.z < -0.9) wall.faces[ face ].materialIndex = 1;
else wall.faces[ face ].materialIndex = 2;
}
var wall_mesh = new THREE.Mesh(wall, material);
wall_mesh.position.set( start.x, 0, -start.y );
wall_mesh.rotation.set(0, ry, 0);
wall_mesh.name = id;
wall_mesh.data = 'wall';
scene.add(wall_mesh);
}
and I am calling this function in init():
//------Add Walls
coordArray.push(coordArray[0]); //push the first corner to close loop
for(var i = 0; i < coordArray.length-1; i++){ //iterate over the coordinate array, pushing vertices to the geometry
var start_wall = coordArray[i];
var end_wall = coordArray[(i+1)];
if(!Rooms[r].wall_show || Rooms[r].wall_show[i] == 1){
var wallTexture = new THREE.TextureLoader().load( "images/room_" + r + "_wall_" + i + ".jpg" );
var wall_material = new THREE.MeshBasicMaterial({
map: wallTexture,
side: THREE.FrontSide,
overdraw: 0.5
});
build_wall( start_wall, end_wall, wall_material, scene_id);
}
//find tour boundary, find center target
if(start_wall.x > maxX) maxX = start_wall.x;
if(start_wall.y > maxY) maxY = start_wall.y;
if(start_wall.x < minX) minX = start_wall.x;
if(start_wall.y < minY) minY = start_wall.y;
}
The result is as following:
The screenshot of the result
Sorry, It was cuz I didn't adjust the UVs to the [ 0, 1 ] range.
var uvs = wall.faceVertexUvs[0];
for (var i = 0; i < uvs.length; i++) {
uv = uvs[i];
for (var j = 0; j < uv.length; j++) {
u = uv[j];
u.x = u.x / wall_length;
u.y = u.y/ wall_height;
}
}
var wall_mesh = new THREE.Mesh(wall, material);
wall_mesh.position.set( start.x, 0, -start.y );
wall_mesh.rotation.set(0, ry, 0);
wall_mesh.name = id;
wall_mesh.data = 'wall';
scene.add(wall_mesh);

Wrong location of texture on the second triangle of BufferGeometry square

I'm trying to add texture to a THREE.BufferGeometry. This is a working fiddle of what I'm accomplished so far.
This is my code:
var Test = new function () {
var scene = new THREE.Scene(),
camera = new THREE.PerspectiveCamera(10, window.innerWidth / window.innerHeight, 1, 1000),
renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true
camera.position.set(-5, 5, 5);
camera.rotation.order = 'YXZ';
camera.rotation.y = -Math.PI / 4;
camera.rotation.x = Math.atan(-1 / Math.sqrt(2));
scene.add(camera)
scene.add(new THREE.AmbientLight(0x222222));
var light = new THREE.PointLight(0xffffff, 0.7);
camera.add(light);
this.init = function () {
$('body').append(renderer.domElement);
Test.render();
}
this.render = function () {
requestAnimationFrame(Test.render);
renderer.render(scene, camera);
}
this.getScene = function getScene() {
return scene
}
}
var CreateSimpleMesh = new function () {
var grassGeometry = new THREE.BufferGeometry(),
grassVertexPositions = [],
imageArray = [
[0, 0],
[1, 0],
[1, 1],
[0, 1]
],
image = new Image()
this.init = function () {
image.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wwLAi03pl5F1AAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAEkklEQVR42u3dTWzTdRzH8XfXdW03t3XPbmyMlLkNZA9kcwuKBBVBEjXEGDExEAwH44GDJpp4QYnCQcIZoiZGUaKeCFHjIBB5UnnSKW5zj7AVWvfvxsbWre22Dg+1SmHA/iwbHD7v2+/fZYfvK/+n9vCzrDmx7hrqvilBIxCIuk2JGsHsNth0hcvf9dB/1iBkBLFnOkgrc+HeWEr6oow7gwy1DuJt8NB/zs+oJ4DFmoAjx4GrMoviF92klqRryiY69dqxuHXICBIyghgnfFS/X0feyoLbg/y8+ccbjkwy0hNgpCfA5e+7qdxaS/6qQk16mrmWZFL4fDGZNTnYM+wEuodp2fUHg39eof2j5juDpJW7mLd2PlmP5ODMT2FyPMJIT4AL+9rpPeKlbXeTQExUv2dF/HwfclGxtYbjLx0i+PfonS9Zyz5ZGX/XtyWQXp7B4jer6D3iZWJkQlOe6Y3bGR178rwU8zf1ieAEwcsjXNjXDkD+ap0dM+3iVx0APDjFleaWIA3L98etnQXJlL6+mOL1JZroDPIe9HDhy3aSC1NY8HLJ3b+HjA2ECfeHQe/1M8I4/8E5rA4r1dvrsNqt0z9D1pxYF4UYGmPor0HadjfR/U0nWKB8S4WmazLPgYs072wEC1S+W0vqwvS7e1NPSksiuy6XpTvqAPAduqTpmr1nfN1B84eNcA0efnspuY/nz/xNfXI8eq2KjOopy0ydn7XS8XELAIvfqqbw2WJzX52cfeMk819wk74kE1uqjYnhcQabB2jf0xR90anM0pRNFMMAaN7ZGL1sXdcT364lyWW/NUj/GT/9Z/xT/nNbmo3yLUs05VnMcuPvIQPn+7l0oJsrv/oJ94VIsCXgLEghuz6XBetLsGc7NLXZfGm88UBGRRYZFbos3av0e4hAlEAEogQiECUQgSiBCEQJRAlEIEogAlECEYgSiECUQJRABKIEIhAlEIEogQhECUQJRCBKIAJRAhGIEohAlECUQASiBCIQJRCBKIEIRAlECUQgSiACUQIRiBKIQJRAlEAEogQiECUQgSiBCETdu6bcFGxyLELX3ja8P3gI+YM4cpwUPFOEe2MZCTYZmi3QPYxxzIdx3MfV5gHg/20JpwXy+7azGEd9/62DvlE6P20l0DVM9fY6TdhkJ185fPeXLP8vvRhHfViTE6nZtYxVh5+jZtcyrMmJ9B710nfa0IRNlrIglYWvlvHY50+aB/Ed9ADg3lBKdn0eVruV7Po83BtKAfA2eDRhky3/4ilKNi/iAXeaeZCrLYMA5DyaF3c8th5qGdCE5/IpK9wXBMBZEL/Xd2wd8oc0tbkEiYQiADftZBxbR8LaenVOQayO2OAj8VDhGFSipjaXIPZsZ/RR1zsSdzy2duRop885BUlf5Io+/v7UG/84/O86rdylqc0lSP7TRQB07W2j77TB5FiEvtMGXXvbop+vLtLUZrGbNicG+O2dUxjHfTf9ce6KfJbuqNfUTNawfP9tP7/+a5Qpv5iq2laLe1MZjjwnFqsFR54T96Yyqt6r1XTvxRmi7qN7iBKIEohA1DT7B5cwUaoY0hehAAAAAElFTkSuQmCC'
var texture = new THREE.Texture();
texture.image = image;
image.onload = function () {
texture.needsUpdate = true;
};
// first triangle
grassVertexPositions.push([0, 0, 0])
grassVertexPositions.push([1, 0, 0])
grassVertexPositions.push([0, 1, 0])
// second triangle
grassVertexPositions.push([1, 1, 0])
grassVertexPositions.push([0, 1, 0])
grassVertexPositions.push([1, 0, 0])
var grassVertices = new Float32Array(grassVertexPositions.length * 3),
normals = new Float32Array(grassVertexPositions.length * 3),
colors = new Float32Array(grassVertexPositions.length * 3),
uvs = new Float32Array(grassVertexPositions.length * 2)
for (var i = 0; i < grassVertexPositions.length; i++) {
var index = 3 * i
grassVertices[index + 0] = grassVertexPositions[i][0]
grassVertices[index + 1] = grassVertexPositions[i][1]
grassVertices[index + 2] = grassVertexPositions[i][2]
}
uvs[0] = imageArray[0][0]
uvs[1] = imageArray[0][1]
uvs[2] = imageArray[1][0]
uvs[3] = imageArray[1][1]
uvs[4] = imageArray[3][0]
uvs[5] = imageArray[3][1]
uvs[6] = imageArray[1][0]
uvs[7] = imageArray[1][1]
uvs[8] = imageArray[2][0]
uvs[9] = imageArray[2][1]
uvs[10] = imageArray[3][0]
uvs[11] = imageArray[3][1]
grassGeometry.addAttribute('position', new THREE.BufferAttribute(grassVertices, 3))
grassGeometry.addAttribute('normal', new THREE.BufferAttribute(normals, 3))
grassGeometry.addAttribute('color', new THREE.BufferAttribute(colors, 3))
grassGeometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 2))
grassGeometry.computeVertexNormals()
//var textureLoader = new THREE.TextureLoader();
//textureLoader.load('/img/testface.png', function (texture) {
var grassMaterial = new THREE.MeshLambertMaterial({map: texture}),
grassMesh = new THREE.Mesh(grassGeometry, grassMaterial)
grassMesh.rotation.x = -Math.PI / 2;
Test.getScene().add(grassMesh)
var helper = new THREE.WireframeHelper(grassMesh, 0xff00ff); // alternate
helper.material.linewidth = 1;
Test.getScene().add(helper);
console.log(grassMesh.geometry.attributes)
//});
}
}
$(document).ready(function () {
Test.init()
CreateSimpleMesh.init()
});
The problem is that texture on first triangle of the rectangle is correct but on the second triangle something strange is happening with the texture.
This is how it should look like
This is how it look now
Try these texture coordinates (same as x and y of vertex coordinates):
uvs[0] = 0
uvs[1] = 0
uvs[2] = 1
uvs[3] = 0
uvs[4] = 0
uvs[5] = 1
uvs[6] = 1
uvs[7] = 1
uvs[8] = 0
uvs[9] = 1
uvs[10] = 1
uvs[11] = 0

ThreeJS test works fine in Chrome, but nothing shows in IE10

I have this little test script which I'll try to include below. It works fine in Chrome but not in IE10. IE10 gives me a nice white screen. I tried putting in the meta-equiv thing to help IE10 get the hint, but that did not change anything (in either browser). Please help.
<!-- language: lang-js -->
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="three.min.js"></script>
<script defer="defer">
// http://www.aerotwist.com/tutorials/getting-started-with-three-js/
var cubes = [];
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// camera
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 5000);
camera.position.z = 800;
// scene
var scene = new THREE.Scene();
// material
var phongMaterial = new THREE.MeshPhongMaterial({ambient: 0x555555,
color: 0x555555,
specular: 0xffffff,
shininess: 50,
side: THREE.FrontSide,
shading: THREE.SmoothShading});
var phongBack = new THREE.MeshPhongMaterial({ambient: 0x555555,
color: 0x995555,
specular: 0xffffff,
shininess: 50,
side: THREE.BackSide,
shading: THREE.SmoothShading});
var materials = [phongMaterial, phongBack];
// cube
//var cube = new THREE.Mesh(new THREE.CubeGeometry(200, 200, 200), material);
var geom = new THREE.Geometry();
var a = 100;
var b = 100;
var c = 300;
var geom = new THREE.Geometry();
var halfPi = (Math.PI / 2.0);
var u = -halfPi;
var uInc = Math.PI / 200.0;
var v = - Math.PI;
var vInc = uInc * 2.0;
var vertexNdx = 0;
var vs = [];
var on = true;
while (u < halfPi) {
var oneLine = [];
vs.push(oneLine);
while (v < Math.PI) {
var x = a * Math.cos(u) * Math.cos(v);
var y = b * Math.cos(u) * Math.sin(v);
var z = c * Math.sin(v) * Math.sin(u);
x += Math.random();
y += Math.random();
z += Math.random();
var v1 = new THREE.Vector3(x, y, z);
geom.vertices.push(v1);
oneLine.push(vertexNdx++);
if (on)
{
if (vs.length > 1 && oneLine.length > 1)
{
var uNdx = vs.length - 1;
var vNdx = oneLine.length - 1;
geom.faces.push(new THREE.Face3(vs[uNdx - 1][vNdx - 1],
vs[uNdx - 1][vNdx],
vs[uNdx][vNdx - 1]));
geom.faces.push(new THREE.Face3(vs[uNdx][vNdx - 1],
vs[uNdx - 1][vNdx],
vs[uNdx][vNdx]));
}
//on = false;
}
else
{
on = true;
}
v += vInc;
}
v = -Math.PI;
u += uInc;
}
var oneLine = vs[0];
var uNdx = vs.length - 1;
for (var vNdx = 1; vNdx < oneLine.length; vNdx++)
{
geom.faces.push(new THREE.Face3(vs[0][vNdx - 1],
vs[0][vNdx],
vs[uNdx][vNdx - 1]));
geom.faces.push(new THREE.Face3(vs[uNdx][vNdx - 1],
vs[0][vNdx],
vs[uNdx][vNdx]));
}
geom.computeFaceNormals();
var cube = new THREE.SceneUtils.createMultiMaterialObject(geom, materials);
cube.overdraw = true;
cube.rotation.x = Math.PI * 0.1;
scene.add(cube);
cubes.push(cube);
var geom = new THREE.Geometry();
var a = 100;
var b = 100;
var c = 300;
var geom = new THREE.Geometry();
var halfPi = (Math.PI / 2.0);
var u = -halfPi;
var uInc = Math.PI / 200.0;
var v = - Math.PI;
var vInc = uInc * 2.0;
var vertexNdx = 0;
var vs = [];
var on = true;
while (u < halfPi) {
var oneLine = [];
vs.push(oneLine);
var xRand = Math.random();
while (v < Math.PI) {
var x = a * Math.cos(u) * Math.cos(v);
var y = b * Math.cos(u) * Math.sin(v);
var z = c * Math.sin(v) * Math.sin(u);
x += xRand;
y += Math.random();
z += Math.random();
var v1 = new THREE.Vector3(x, y, z);
geom.vertices.push(v1);
oneLine.push(vertexNdx++);
if (on)
{
if (vs.length > 1 && oneLine.length > 1)
{
var uNdx = vs.length - 1;
var vNdx = oneLine.length - 1;
geom.faces.push(new THREE.Face3(vs[uNdx - 1][vNdx - 1],
vs[uNdx - 1][vNdx],
vs[uNdx][vNdx - 1]));
geom.faces.push(new THREE.Face3(vs[uNdx][vNdx - 1],
vs[uNdx - 1][vNdx],
vs[uNdx][vNdx]));
}
//on = false;
}
else
{
on = true;
}
v += vInc;
}
v = -Math.PI;
u += uInc;
}
var oneLine = vs[0];
var uNdx = vs.length - 1;
for (var vNdx = 1; vNdx < oneLine.length; vNdx++)
{
geom.faces.push(new THREE.Face3(vs[0][vNdx - 1],
vs[0][vNdx],
vs[uNdx][vNdx - 1]));
geom.faces.push(new THREE.Face3(vs[uNdx][vNdx - 1],
vs[0][vNdx],
vs[uNdx][vNdx]));
}
geom.applyMatrix(new THREE.Matrix4().translate(new THREE.Vector3(200, 0, 0)));
geom.computeFaceNormals();
var cube = new THREE.SceneUtils.createMultiMaterialObject(geom, materials);
cube.overdraw = true;
cube.rotation.x = Math.PI * 0.1;
scene.add(cube);
cubes.push(cube);
var geom = new THREE.Geometry();
var a = 100;
var b = 100;
var c = 300;
var geom = new THREE.Geometry();
var halfPi = (Math.PI / 2.0);
var u = -halfPi;
var uInc = Math.PI / 200.0;
var v = - Math.PI;
var vInc = uInc * 2.0;
var vertexNdx = 0;
var vs = [];
var on = true;
while (u < halfPi) {
var oneLine = [];
vs.push(oneLine);
var yRand = Math.random();
while (v < Math.PI) {
var x = a * Math.cos(u) * Math.cos(v);
var y = b * Math.cos(u) * Math.sin(v);
var z = c * Math.sin(v) * Math.sin(u);
x += Math.random();
y += yRand;
z += Math.random();
var v1 = new THREE.Vector3(x, y, z);
geom.vertices.push(v1);
oneLine.push(vertexNdx++);
if (on)
{
if (vs.length > 1 && oneLine.length > 1)
{
var uNdx = vs.length - 1;
var vNdx = oneLine.length - 1;
geom.faces.push(new THREE.Face3(vs[uNdx - 1][vNdx - 1],
vs[uNdx - 1][vNdx],
vs[uNdx][vNdx - 1]));
geom.faces.push(new THREE.Face3(vs[uNdx][vNdx - 1],
vs[uNdx - 1][vNdx],
vs[uNdx][vNdx]));
}
//on = false;
}
else
{
on = true;
}
v += vInc;
}
v = -Math.PI;
u += uInc;
}
var oneLine = vs[0];
var uNdx = vs.length - 1;
for (var vNdx = 1; vNdx < oneLine.length; vNdx++)
{
geom.faces.push(new THREE.Face3(vs[0][vNdx - 1],
vs[0][vNdx],
vs[uNdx][vNdx - 1]));
geom.faces.push(new THREE.Face3(vs[uNdx][vNdx - 1],
vs[0][vNdx],
vs[uNdx][vNdx]));
}
geom.applyMatrix(new THREE.Matrix4().translate(new THREE.Vector3(-200, 0, 0)));
geom.computeFaceNormals();
var cube = new THREE.SceneUtils.createMultiMaterialObject(geom, materials);
cube.overdraw = true;
cube.rotation.x = Math.PI * 0.1;
scene.add(cube);
cubes.push(cube);
// add subtle ambient lighting
var ambientLight = new THREE.AmbientLight(0xdddddd);
scene.add(ambientLight);
// directional lighting
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
var screenW = window.innerWidth;
var screenH = window.innerHeight;
var spdx = 0, spdy = 0, mouseX = 0, mouseY = 0, mouseDown = false;
document.addEventListener('mousemove', function(event) {
mouseX = event.clientX;
mouseY = event.clientY;
}, false);
document.body.addEventListener('mousedown', function(event) {
mouseDown = true;
}, false);
document.body.addEventListener('mouseup', function(event) {
mouseDown = false;
}, false);
function animate() {
spdy = (screenH / 2 - mouseY) / 40;
spdx = (screenW / 2 - mouseX) / 40;
if (mouseDown) {
for (var loop = 0; loop < cubes.length; loop++) {
var cube = cubes[loop];
cube.rotation.x = spdy;
cube.rotation.y = spdx;
}
}
renderer.render(scene, camera);
requestAnimationFrame(function(){
animate();
});
};
// start animation
animate();
</script>
</body>
</html>
And feel free to steal my little play test code if you like it. If you make something that looks cool, let me see it! I'm looking for organic-looking shapes that are made mathematically.
IE10 does not support WebGL. I think your code will work if you just switch from WebGLRenderer to CanvasRenderer, but the lighting won't be as accurate.

Resources