For a web project, I would like to draw random points with Three.js.
This is my code so far:
<script type="module">
import * as THREE from 'https://threejs.org/build/three.module.js';
import { TrackballControls } from 'https://threejs.org/examples/jsm/controls/TrackballControls.js';
let camera, scene, renderer, controls;
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xffffff );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 0, 0, 500 );
controls = new TrackballControls( camera, renderer.domElement );
controls.minDistance = 200;
controls.maxDistance = 500;
scene.add( new THREE.AmbientLight( 0x222222 ) );
const light = new THREE.PointLight( 0xffffff );
light.position.copy( camera.position );
scene.add( light );
//
//
const randomPoints = [];
for ( let i = 0; i < 10; i ++ ) {
randomPoints.push( new THREE.Vector3( ( i - 4.5 ) * 50, THREE.MathUtils.randFloat( - 50, 50 ), THREE.MathUtils.randFloat( - 50, 50 ) ) );
}
const randomSpline = new THREE.CatmullRomCurve3( randomPoints );
//
const extrudeSettings2 = {
steps: 120,
bevelEnabled: false,
extrudePath: randomSpline
};
const pts2 = [], numPts = 5;
for ( let i = 0; i < numPts * 2; i ++ ) {
const l = i % 2 == 1 ? 10 : 10;
const a = i / numPts * Math.PI;
pts2.push( new THREE.Vector2( Math.cos( a ) * l, Math.sin( a ) * l ) );
}
const shape2 = new THREE.Shape( pts2 );
const geometry2 = new THREE.ExtrudeGeometry( shape2, extrudeSettings2 );
const material2 = new THREE.MeshLambertMaterial( { color: 0xff8000, wireframe: false } );
const mesh2 = new THREE.Mesh( geometry2, material2 );
scene.add( mesh2 );
//
const materials = [ material2 ];
const extrudeSettings3 = {
depth: 40,
steps: 1,
bevelEnabled: true,
bevelThickness: 2,
bevelSize: 4,
bevelSegments: 1
};
const geometry3 = new THREE.ExtrudeGeometry( shape2, extrudeSettings3 );
const mesh3 = new THREE.Mesh( geometry3 );
mesh3.position.set( 150, 100, 0 );
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
</script>
Currently, everything is based on splines. The result should not be based on extrusion, but on random points. I don't really know how to get random points. Is there a special function for it? Or can another function be used for it?
I would be veeeery thankful for help! :)
I think a good place to start with is using ConvexGeometry. You give it an array of points / Vector3 ( which I see you have created under the variable randomPoints ) as a parameter and it will create a shape for you.
I see you used CatmullRomCurve3, this may be a good tool to create the curves between the points as you mentioned. We can combine both of these ideas to create a somewhat curvier model.
const divisions = 25; // The amount of divisions between points
const catmullPoints = new THREE.CatmullRomCurve3( randomPoints, true, "catmullrom", 0.5 ).getPoints(divisions);
const geometryConvex = new ConvexGeometry( randomPoints );
So now you have a geometry with a somewhat randomized shape. The thing about it is that it will look a bit more "geometrical" than the example shapes you provided. So what you can try to do is divide your randomPoints to chunks, i.e multiple sub-arrays, and do a similar approach as above, basically saving the created geometries to a separate array, let's call it geometries, and then you can use mergeBufferGeometries to create a single geometry out of these geometries, this will give a more abstract looking shape. The code:
const size = THREE.MathUtils.randInt(2,10); // the number of sub arrays can be another parameter to randomize
const pointsChunk = chunk([...randomPoints], size); // you can use lodash or other chunk algorithms found online
const geometries = [];
for ( let i = 0 ; i < pointsChunk.length ; i++) {
const divisions = 25;
const catmullPoints = new THREE.CatmullRomCurve3( pointsChunk[i], true, "catmullrom", 0.5 ).getPoints( divisions );
geometries.push(new ConvexGeometry( catmullPoints ));
}
const mergedGeometry = BufferGeometryUtils.mergeBufferGeometries( geometries );
There may be more ways to go about it, but I believe ConvexGeometry is definitely a good place to start.
Here is a fiddle of my attempt : https://jsfiddle.net/9rc503tn/2
Related
I'm trying to animate the movement of a sphere along a predefined set of vertices.
I'm able to animate from one point to another using the below code
function animate() {
requestAnimationFrame(animate)
sphere.position.lerp(new THREE.Vector3(100, 2, 0), 0.05)
render()
}
function render() {
renderer.render(scene, camera)
}
animate()
this works for a single animation from initial position to (100, 2, 0). How do i keep on adding vertices, so that it will be animated in sequence.
You can animate a mesh along a path with plain three.js by defining a curve based on your sequence of points and then using this curve for animation.
let camera, scene, renderer, clock;
let mesh, path;
const duration = 10;
let time = 0;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.set( 3, 2, 3 );
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
clock = new THREE.Clock();
const controls = new THREE.OrbitControls( camera, renderer.domElement );
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
scene.add( new THREE.AxesHelper( 2 ) );
// points and path
const points = [
new THREE.Vector3( 0, 0, 0 ),
new THREE.Vector3( 1, 2, - 2 ),
new THREE.Vector3( 2, 2, - 0.5 ),
new THREE.Vector3( 2, 1, - 2 )
];
path = new THREE.CatmullRomCurve3( points, true );
// visualize the path
const lineGeometry = new THREE.BufferGeometry().setFromPoints( path.getPoints( 32 ) );
const lineMaterial = new THREE.LineBasicMaterial();
const line = new THREE.Line( lineGeometry, lineMaterial );
scene.add( line );
}
function animate() {
requestAnimationFrame( animate );
time += clock.getDelta();
const t = Math.min( time / duration, 1 );
if ( t === 1 ) time = 0;
path.getPointAt( t, mesh.position ); // animating
renderer.render( scene, camera );
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.137.5/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.137.5/examples/js/controls/OrbitControls.js"></script>
My project uses geometry where each face is its own mesh. I need to clip the geometry to cut away a portion of it and have a stenciled cap face cover the clipped edges. I examined and tinkered with the Three.js clipping stencil example and I understand how to use a stencil to cap trimmed solid geometry, but when I try it on collections of face geometries it doesn't work. Here is some code I have been tinkering with, based on the example:
body { margin: 0; }
canvas { display: block; }
<script type="module">
import * as THREE from 'https://unpkg.com/three#0.120.1/build/three.module.js';
import { OrbitControls } from 'https://unpkg.com/three#0.120.1/examples/jsm/controls/OrbitControls.js';
import { BufferGeometryUtils } from 'https://unpkg.com/three#0.120.1/examples/jsm/utils/BufferGeometryUtils.js';
var camera, scene, renderer;
var planes, planeObjects;
init();
animate();
function createPlaneStencilGroup( geometry, plane, renderOrder )
{
var group = new THREE.Group();
var baseMat = new THREE.MeshBasicMaterial();
baseMat.depthWrite = false;
baseMat.depthTest = false;
baseMat.colorWrite = false;
baseMat.stencilWrite = true;
baseMat.stencilFunc = THREE.AlwaysStencilFunc;
// back faces
var mat0 = baseMat.clone();
mat0.side = THREE.BackSide;
mat0.clippingPlanes = [ plane ];
mat0.stencilFail = THREE.IncrementWrapStencilOp;
mat0.stencilZFail = THREE.IncrementWrapStencilOp;
mat0.stencilZPass = THREE.IncrementWrapStencilOp;
var mesh0 = new THREE.Mesh( geometry, mat0 );
mesh0.renderOrder = renderOrder;
group.add( mesh0 );
// front faces
var mat1 = baseMat.clone();
mat1.side = THREE.FrontSide;
mat1.clippingPlanes = [ plane ];
mat1.stencilFail = THREE.DecrementWrapStencilOp;
mat1.stencilZFail = THREE.DecrementWrapStencilOp;
mat1.stencilZPass = THREE.DecrementWrapStencilOp;
var mesh1 = new THREE.Mesh( geometry, mat1 );
mesh1.renderOrder = renderOrder;
group.add( mesh1 );
return group;
}
function init()
{
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 36, window.innerWidth / window.innerHeight, 1, 100 );
camera.position.set( 2, 2, 2 );
initLights();
planes = [
new THREE.Plane( new THREE.Vector3( 0, - 1, 0 ), 0.42 ),
new THREE.Plane( new THREE.Vector3( 0, 0, - 1 ), 0.25 )
];
var material = new THREE.MeshStandardMaterial( {
color: 0x00ff00,
metalness: 0.1,
roughness: 0.75,
side: THREE.DoubleSide,
clippingPlanes: planes,
clipShadows: true,
shadowSide: THREE.DoubleSide,
} );
// Simple sphere geometry. Something I know works, for comparison.
var sphereGeom = new THREE.SphereBufferGeometry( 0.5, 32, 32 );
sphereGeom.translate( -1.1, 0, 0 );
// Make a cube out of 6 planes and merge them together
var planeGeoms = [];
for(var i = 0; i < 6; i++)
{
planeGeoms.push( new THREE.PlaneBufferGeometry( 1, 1 ) );
}
var mergedBufferGeom = BufferGeometryUtils.mergeBufferGeometries( planeGeoms );
// Set up clip plane rendering
planeObjects = [];
var planeGeom = new THREE.PlaneBufferGeometry( 4, 4 );
for ( var i = 0; i < 2; i ++ )
{
var poGroup = new THREE.Group();
var plane = planes[ i ];
var stencilGroup_sphere = createPlaneStencilGroup( sphereGeom, plane, i + 1 );
var stencilGroup_Box = createPlaneStencilGroup( mergedBufferGeom, plane, i + 1 )
// plane is clipped by the other clipping planes
var planeMat = new THREE.MeshStandardMaterial( {
color: 0x0000ff,
metalness: 0.1,
roughness: 0.75,
clippingPlanes: planes.filter( p => p !== plane ),
stencilWrite: true,
stencilRef: 0,
stencilFunc: THREE.NotEqualStencilFunc,
stencilFail: THREE.ReplaceStencilOp,
stencilZFail: THREE.ReplaceStencilOp,
stencilZPass: THREE.ReplaceStencilOp,
} );
var po = new THREE.Mesh( planeGeom, planeMat );
po.onAfterRender = function ( renderer ) {
renderer.clearStencil();
};
po.renderOrder = i + 1.1;
plane.coplanarPoint( po.position );
po.lookAt(
po.position.x - plane.normal.x,
po.position.y - plane.normal.y,
po.position.z - plane.normal.z,
);
scene.add( stencilGroup_sphere );
scene.add( stencilGroup_Box );
poGroup.add( po );
planeObjects.push( po );
scene.add( poGroup );
}
var sphereMesh = new THREE.Mesh( sphereGeom, material );
sphereMesh.renderOrder = 6;
scene.add( sphereMesh );
var planeMeshes = [];
for(var i = 0; i < 6; i++)
{
planeMeshes.push( new THREE.Mesh(planeGeoms[i], material) );
}
planeMeshes[0].position.copy(new THREE.Vector3(.5, 0, 0));
planeMeshes[1].position.copy(new THREE.Vector3(0, .5, 0));
planeMeshes[2].position.copy(new THREE.Vector3(0, 0, .5));
planeMeshes[3].position.copy(new THREE.Vector3(-.5, 0, 0));
planeMeshes[4].position.copy(new THREE.Vector3(0, -.5, 0));
planeMeshes[5].position.copy(new THREE.Vector3(0, 0, -.5));
planeMeshes[0].lookAt(new THREE.Vector3(2, 0, 0));
planeMeshes[1].lookAt(new THREE.Vector3(0, 2, 0));
planeMeshes[2].lookAt(new THREE.Vector3(0, 0, 2));
planeMeshes[3].lookAt(new THREE.Vector3(-2, 0, 0));
planeMeshes[4].lookAt(new THREE.Vector3(0, -2, 0));
planeMeshes[5].lookAt(new THREE.Vector3(0, 0, -2));
for(var i = 0; i < 6; i++)
scene.add( planeMeshes[i] );
// Renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.shadowMap.enabled = true;
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0x263238 );
renderer.localClippingEnabled = true;
window.addEventListener( 'resize', onWindowResize, false );
document.body.appendChild( renderer.domElement );
// Controls
var controls = new OrbitControls( camera, renderer.domElement );
controls.minDistance = 2;
controls.maxDistance = 20;
controls.update();
}
function initLights()
{
scene.add( new THREE.AmbientLight( 0xffffff, 0.5 ) );
var dirLight = new THREE.DirectionalLight( 0xffffff, 1 );
dirLight.position.set( 5, 10, 7.5 );
dirLight.castShadow = true;
dirLight.shadow.camera.right = 2;
dirLight.shadow.camera.left = - 2;
dirLight.shadow.camera.top = 2;
dirLight.shadow.camera.bottom = - 2;
dirLight.shadow.mapSize.width = 1024;
dirLight.shadow.mapSize.height = 1024;
scene.add( dirLight );
}
function onWindowResize()
{
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate()
{
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
</script>
It contains 2 clipping planes, a cube made from 6 separate PlaneGeometries, and a solid sphere for comparison. I made the stencil for the cube using an additional BufferGeometry made from merging the planes together into a single geometry object. The stencil for the cube appears to be the right shape and size, but only one cap face is drawn and it is not at the location of either of the clipping planes. Is there anything else I'm supposed to do with the stencil or the clipping plane beyond what the example already does to make it work on geometry of this type?
Turns out the PlaneBufferGeometries that were getting merged for the stencil were not in the same positions as the plane meshes that used those geometries. That is why the cap face wasn't being drawn properly. I had not considered the fact that if you apply a transform to a Mesh, then get the Mesh's geometry to use elsewhere, that geometry won't reflect the transform applied to the Mesh. I got it to work by applying the transform matrices from the plane meshes to the PlaneBufferGeometries that needed to be merged.
Description of the problem
I have a simple box mesh with a morphTarget and a slider which adjusts the morphTargetInfluence. The morph affects the mesh as it should but it also shrinks any other mesh in the scene.
I've put together a jsfiddle (modified from the threejs morph target) example below to demo the issue. In this demo moving the slider correctly morphs the corner of the red cube but incorrectly shrinks the size of the blue cube. The cube meshes are entirely unrelated so I don't see how the morph could affect the blue cube.
https://jsfiddle.net/djmm7vv2/
// JS code from jsfiddle
var container, stats;
var camera, scene, renderer;
var geometry, objects;
var mesh, mesh2;
init();
animate();
function init() {
// Create cameras, lights, scene, ect.
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 15000 );
camera.position.z = 500;
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x222222 );
scene.fog = new THREE.Fog( 0x000000, 1, 15000 );
var light1 = new THREE.PointLight( 'white', 1);
light1.position.set( 100, 100, 100 );
var light2 = new THREE.PointLight( 'white', 1);
light2.position.set( -100, 100, 100 );
scene.add( light1 );
scene.add( light2 );
// Create first mesh (red cube)
var geometry = new THREE.BoxGeometry( 100, 100, 100 );
var material = new THREE.MeshLambertMaterial( { color: 'red', morphTargets: true } );
// Create 1 blend shape
for ( var i = 0; i < 1; i ++ ) {
var vertices = [];
for ( var v = 0; v < geometry.vertices.length; v ++ ) {
vertices.push( geometry.vertices[ v ].clone() );
if ( v === i ) {
vertices[ vertices.length - 1 ].x *= 2;
vertices[ vertices.length - 1 ].y *= 2;
vertices[ vertices.length - 1 ].z *= 2;
}
}
geometry.morphTargets.push( { name: "target" + i, vertices: vertices } );
}
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
// Add second mesh (blue cube)
var blue = new THREE.MeshLambertMaterial( { color: 'blue', morphTargets: true } );
var box2 = new THREE.BoxGeometry( 100, 100, 100 );
mesh2 = new THREE.Mesh( box2, blue );
scene.add( mesh2 );
mesh2.position.x = 150
// Create simple GUI slider to change morph influence on mesh (red cube)
var params = {
influence1: 0,
};
var gui = new dat.GUI();
var folder = gui.addFolder( 'Morph Targets' );
folder.add( params, 'influence1', 0, 1 ).step( 0.01 ).onChange( function( value ) { mesh.morphTargetInfluences[ 0 ] = value; } );
folder.open();
// Render it all
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
mesh.rotation.y += 0.01;
renderer.render( scene, camera );
}
...And here's the answer https://github.com/mrdoob/three.js/issues/12691#issuecomment-345416590. My blue mesh material had morphTargets set to true. Changing it to false corrected the issue.
var blue = new THREE.MeshLambertMaterial( { color: 'blue', morphTargets: false } );
If anyone knows why this is the case I would love to know more. The documentation on MeshLambertMaterials is sparse. Maybe this has to do with keeping material textures from freaking out when the morph is applied?
Simple Program to display the bars in a certain location with a certain height, with a certain color. New to Three.js, so learning about the framework.
When I run my script to load the bar position, colors, the lights, camera and the controls. I find that the Box colors are constant, with the basic mesh so I tried with a MeshPhongMaterial also constant. So I need a little help.
// Begin
function plotRF(bar_data){
// Bar Data
this.bars = bar_data
// Call the canvas for screan sizing
this.canvas = document.getElementById("BarCanvas")
// create the scene
scene = new THREE.Scene();
// Define the camera
camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 8000 );
camera.position.z = 500;
camera.position.y = 500;
//camera.rotation.x = 90 * Math.PI / 180;
// Set the render engine
var renderer = new THREE.WebGLRenderer({ canvas: BarCanvas });
// Set the render size
renderer.setSize( this.canvas.width, this.canvas.height);
// Add some Lights
this.add_lights()
// Add controls
controls = new THREE.OrbitControls( camera, renderer.domElement );
// Define Geometry
//this.coords()
this.add_bars();
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
};
render();
};
plotRF.prototype.add_bars = function(){
// Bar height
var multiplier = 20;
// Bar Size
var lw = 5;
// loop through the Javascript data
for (i = 0; i< this.bars.length; i++){
var geo = new THREE.BoxGeometry( lw, lw, this.bars[i][0]*multiplier );
//geo.add(
var rfcolour = this.colorTable(this.bars[i][0]);
var mat = new THREE.MeshPhongMaterial( {
color: rfcolour,
emissive: 0x072534,
side: THREE.DoubleSide,
shading: THREE.FlatShading} );
//mat.wireframe = true;
cube = new THREE.Mesh( geo, mat );
cube.position.x = this.bars[i][1]/10;
cube.position.y = this.bars[i][2]/10;
cube.position.z = this.bars[i][0]*multiplier/2;
scene.add( cube );
console.log("bar added, x:" + this.bars[i][1] +", y:" + this.bars[i][2] + ", RF:" + this.bars[i][0]) ;
}
};
plotRF.prototype.colorTable = function(RF){
if (RF < 1 ) {
return new THREE.Color(255,0,0);
} else if (RF < 1.2) {
return new THREE.Color(240,50,50);
} else if (RF < 1.4) {
return new THREE.Color(230,100,100);
} else if (RF < 1.6) {
return new THREE.Color(220,150,150);
} else if (RF < 1.8) {
return new THREE.Color(210,200,200);
} else if (RF < 2.0) {
return new THREE.Color(200,220,220);
} else if (RF < 3.0) {
return new THREE.Color(150,220,220);
} else {
return new THREE.Color(100,240,240);
}
plotRF.prototype.add_lights = function(RF){
var lights = [];
lights[ 0 ] = new THREE.PointLight( 0xffffff, 0.8, 500 );
lights[ 1 ] = new THREE.PointLight( 0xffffff, 0.8, 500 );
lights[ 2 ] = new THREE.PointLight( 0xffffff, 0.8, 500 );
lights[ 0 ].position.set( 0, 2000, 0 );
lights[ 1 ].position.set( 1000, 2000, 1000 );
lights[ 2 ].position.set( - 1000, - 2000, - 1000 );
scene.add( lights[ 0 ] );
scene.add( lights[ 1 ] );
scene.add( lights[ 2 ] );
}
Figure of the constant colors is below. Note the colors are registering correctly the R,G,B values are correct in the THREE.Color function.
you have to set colors like it described in documentation, for example:
return new THREE.Color("rgb(255, 0, 0)"); // red
When passing r,g,b directly in the THREE.Color method the values must be between 0 and 1.
I am trying to implement a WebGl viewer using three.js + colladaloader.js but i am having some problems when trying to import and view my own collada object. I can load the example correctly, but when adding my own model to it (without changing the code) i get a
Can not convert Transform of type lookat
WebGLRenderingContext: GL ERROR :GL_INVALID_OPERATION :
glDrawElements: attempt to access out of range vertices in attribute 0
Any ideas how to get my own model working
I should add that my ColladaLoader.js is a patched version hosted here https://raw.github.com/jihoonl/three.js/6e5a02427f2b9626a3fccc9c09d8654cc02d2109/examples/js/loaders/ColladaLoader.js
Here is the model i am trying to load: http://sketchup.google.com/3dwarehouse/details?mid=bad38a0b2a3d753c8857d6b1c783b210&ct=mdsa&prevstart=0
Here is my code:
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, scene, renderer, objects;
var particleLight, pointLight;
var dae, skin;
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load( '/site_media/models/model.dae', function ( collada ) {
dae = collada.scene;
skin = collada.skins[ 0 ];
dae.scale.x = dae.scale.y = dae.scale.z = 0.002;
dae.updateMatrix();
init();
animate();
} );
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.set( 2, 2, 3 );
scene = new THREE.Scene();
// Grid
var size = 14, step = 1;
var geometry = new THREE.Geometry();
var material = new THREE.LineBasicMaterial( { color: 0x303030 } );
for ( var i = - size; i <= size; i += step ) {
geometry.vertices.push( new THREE.Vector3( - size, - 0.04, i ) );
geometry.vertices.push( new THREE.Vector3( size, - 0.04, i ) );
geometry.vertices.push( new THREE.Vector3( i, - 0.04, - size ) );
geometry.vertices.push( new THREE.Vector3( i, - 0.04, size ) );
}
var line = new THREE.Line( geometry, material, THREE.LinePieces );
scene.add( line );
// Add the COLLADA
scene.add( dae );
particleLight = new THREE.Mesh( new THREE.SphereGeometry( 4, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0xffffff } ) );
scene.add( particleLight );
// Lights
scene.add( new THREE.AmbientLight( 0xcccccc ) );
var directionalLight = new THREE.DirectionalLight(/*Math.random() * 0xffffff*/0xeeeeee );
directionalLight.position.x = Math.random() - 0.5;
directionalLight.position.y = Math.random() - 0.5;
directionalLight.position.z = Math.random() - 0.5;
directionalLight.position.normalize();
scene.add( directionalLight );
pointLight = new THREE.PointLight( 0xffffff, 4 );
pointLight.position = particleLight.position;
scene.add( pointLight );
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//
var t = 0;
var clock = new THREE.Clock();
function animate() {
var delta = clock.getDelta();
requestAnimationFrame( animate );
if ( t > 1 ) t = 0;
if ( skin ) {
// guess this can be done smarter...
// (Indeed, there are way more frames than needed and interpolation is not used at all
// could be something like - one morph per each skinning pose keyframe, or even less,
// animation could be resampled, morphing interpolation handles sparse keyframes quite well.
// Simple animation cycles like this look ok with 10-15 frames instead of 100 ;)
for ( var i = 0; i < skin.morphTargetInfluences.length; i++ ) {
skin.morphTargetInfluences[ i ] = 0;
}
skin.morphTargetInfluences[ Math.floor( t * 30 ) ] = 1;
t += delta;
}
render();
stats.update();
}
function render() {
var timer = Date.now() * 0.0005;
camera.position.x = Math.cos( timer ) * 10;
camera.position.y = 2;
camera.position.z = Math.sin( timer ) * 10;
camera.lookAt( scene.position );
particleLight.position.x = Math.sin( timer * 4 ) * 3009;
particleLight.position.y = Math.cos( timer * 5 ) * 4000;
particleLight.position.z = Math.cos( timer * 4 ) * 3009;
renderer.render( scene, camera );
}
</script>
fixed it by making my texture BIGGER (and placing it on the same folder as my model and renaming to the same name as my model)
It seems like ColladaLoader.js does not load small textures for some reason
Another thing there is a bug https://github.com/mrdoob/three.js/issues/3106 but this is the fix https://raw.github.com/jihoonl/three.js/6e5a02427f2b9626a3fccc9c09d8654cc02d2109/examples/js/loaders/ColladaLoader.js , and it seems that it doesnt work without this fix