Make parallel the crossing edges of opposite faces with three.js - three.js

As you can see in the example below, an edge crossing a face is never parallel to this of the opposite face. How can I get this done ?
"use strict";
const renderer = new THREE.WebGLRenderer({canvas: document.querySelector("canvas")});
const camera = new THREE.PerspectiveCamera(70, 1, 1, 1000);
camera.position.z = 400;
// Make a scene
const scene = new THREE.Scene();
// Make a cube.
const geometry = new THREE.BoxGeometry(200, 200, 200);
// Make a material
const material = new THREE.MeshBasicMaterial({
color: 0x00FF00,
wireframe: true,
});
// Create a mesh based on the geometry and material
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
function resize() {
var width = renderer.domElement.clientWidth;
var height = renderer.domElement.clientHeight;
if (renderer.domElement.width !== width || renderer.domElement.height !== height) {
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
}
}
function animate(time) {
time *= 0.001; // seconds
resize();
mesh.rotation.x = time * 0.5;
mesh.rotation.y = time * 1;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<canvas></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>

That's the way the BoxGeometry algorithm works in Three.js. If you want to override the way in which the vertices are connected, you're going to have to manually build your THREE.Geometry as outlined in the docs. The idea is as follows:
Init a Geometry object.
Add vertices to the geometry with Vector3
Define how the vertices will be connected with Face3
I got things started with 2 sides of the box in the demo below, but I'll leave the remaining 4 sides for you to figure out (it might help to draw it out with pen and paper to figure out how to connect the remaining Face3s).
"use strict";
const renderer = new THREE.WebGLRenderer({canvas: document.querySelector("canvas")});
const camera = new THREE.PerspectiveCamera(70, 1, 1, 1000);
camera.position.z = 400;
// Make a scene
const scene = new THREE.Scene();
// 1. Start with empty geometry
const geometry = new THREE.Geometry();
// 2. Add vertices to geometry
geometry.vertices.push(
// verts [0-3] are in in +z
new THREE.Vector3( -100, 100, 100 ),
new THREE.Vector3( -100, -100, 100 ),
new THREE.Vector3( 100, -100, 100 ),
new THREE.Vector3( 100, 100, 100 ),
// verts [4-7] in -z
new THREE.Vector3( -100, 100, -100 ),
new THREE.Vector3( -100, -100, -100 ),
new THREE.Vector3( 100, -100, -100 ),
new THREE.Vector3( 100, 100, -100 ),
);
// 3. Connect vertices in desired order to make faces
geometry.faces.push( new THREE.Face3( 0, 1, 2 ) );
geometry.faces.push( new THREE.Face3( 0, 2, 3 ) );
geometry.faces.push( new THREE.Face3( 4, 5, 6 ) );
geometry.faces.push( new THREE.Face3( 4, 6, 7 ) );
// Make a material
const material = new THREE.MeshBasicMaterial({
color: 0x00FF00,
wireframe: true,
});
// Create a mesh based on the geometry and material
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
function resize() {
var width = renderer.domElement.clientWidth;
var height = renderer.domElement.clientHeight;
if (renderer.domElement.width !== width || renderer.domElement.height !== height) {
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
}
}
function animate(time) {
time *= 0.001; // seconds
resize();
mesh.rotation.x = time * 0.5;
mesh.rotation.y = time * 1;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<canvas></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>

Related

How to project a texture to curved surface?

Screen capture
I tried to make a 3/4 cylinder surface, and I made it from extruting by a ellipe path,
but when I tried to load a texture to the surface, It does not as I exprected: uniformly painted to the surface, it's stretched
I know it's about texture projection, But I dont know how to set options.
class EllipseCurve3 extends THREE.Curve {
ellipse = null
constructor (ellipse) {
super()
this.ellipse = ellipse
}
getPoint(t, optionalTarget = new THREE.Vector3()) {
const point = this.ellipse.getPoint(t, optionalTarget)
return new THREE.Vector3(
point.x,
point.y,
0
)
}
}
// Scene
const scene = new THREE.Scene();
var shape = new THREE.Shape();
shape.moveTo(0, 0);
shape.moveTo(0, 1);
shape.lineTo(50, 1);
shape.moveTo(50, 0);
shape.lineTo(0, 0);
// var curve = new THREE.CatmullRomCurve3([
// new THREE.Vector3(0, 0, 50),
// new THREE.Vector3(-50, 0, 0),
// new THREE.Vector3(0, 0, -50)
// ]);
const arc = new THREE.EllipseCurve(
0,
0, // ax, aY
100,
100, // xRadius, yRadius
0,
1.5 * Math.PI, // aStartAngle, aEndAngle
false, // aClockwise
0 // aRotation
),
path = new EllipseCurve3(arc)
geometry = new THREE.ExtrudeGeometry(shape, {
bevelEnabled: false,
extrudePath: path,
steps: 50,
depth: 5,
amount: 20,
material: 0,
extrudeMaterial: 1
});
// Set up lights
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
const axesHelper = new THREE.AxesHelper(500);
scene.add(axesHelper);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight.position.set(100, 200, 100); // x, y, z
scene.add(directionalLight);
// Camera
const width = 200;
const height = width * (window.innerHeight / window.innerWidth);
const camera = new THREE.OrthographicCamera(
width / -2, // left
width / 2, // right
height / 2, // top
height / -2, // bottom
0.1, // near
1000 // far
);
camera.position.set(400, 400, 400);
camera.lookAt(0, 0, 0);
// Renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
const controls = new THREE.OrbitControls(camera, renderer.domElement);
renderer.render(scene, camera);
// Add it to HTML
document.body.appendChild(renderer.domElement);
var textureLoader = new THREE.TextureLoader();
textureLoader.crossOrigin = true;
const picture = 'https://threejs.org/examples/textures/uv_grid_opengl.jpg'
textureLoader.load(picture, function(texture) {
// repeat pattern
texture.wrapS = texture.wrapT = THREE.MirroredRepeatWrapping;
// zoom in on pattern
texture.repeat.set(.01, .01);
// assign texture via MeshBasicMaterial
var material = new THREE.MeshBasicMaterial({
map: texture,
needsUpdate: true,
// transparent: true,
// premultipliedAlpha: true,
// side: THREE.DoubleSide,
// blending: THREE.AdditiveBlending
});
// var material = new THREE.MeshPhongMaterial({ color: 0x0048ff });
var mesh = new THREE.Mesh(geometry, material)
mesh.rotation.x = Math.PI / 2
// mesh.rotation.z = Math.PI / 2
scene.add(mesh)
scene.add(cube)
})
function render() {
renderer.render(scene, camera);
// Rotate out group
// svgGroup.rotation.y -= 0.005
controls.update();
requestAnimationFrame(render);
}
render();
Code here
https://codepen.io/mike-xu/pen/RwQeEXJ
"I know it's about texture projection" - It's about computing UV, based on vertices coordinates.
CylinderGeometry also may help to achieve the result you described. With less code, and more convenient and predictable way.
body{
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three#0.136.0";
import {OrbitControls} from "https://cdn.skypack.dev/three#0.136.0/examples/jsm/controls/OrbitControls.js";
console.clear();
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 10, 10);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", event => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
let controls = new OrbitControls(camera, renderer.domElement);
scene.add(new THREE.AxesHelper(10));
let g = new THREE.CylinderGeometry(5, 5, 5, 100, 20, true, 0, Math.PI * 1.5);
let m = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
map: new THREE.TextureLoader().load(
"https://threejs.org/examples/textures/uv_grid_opengl.jpg",
tex => {
tex.wrapS = tex.wrapT = THREE.MirroredRepeatWrapping;
tex.repeat.set(3, 1);
}
)
});
let c = new THREE.Mesh(g, m);
scene.add(c);
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
});
</script>

Three.js bloom layer issue

I already tried my best to find a solution to my problem but without any luck, hope for your help with this.
In my three.js file I have a moon that is surrounded by stars.
The moon is a simple sphere geometry and the stars are a particle system that use a texture. However they just look like flat circles flying around.
So far so good, the particles were flying all around the moon, some in front of it and some behind it. Exactly what I want.
Then I added a bloom effect and worked with layers. So the moon (layer 0) has no bloom and the particles (layer 1) has bloom added to it.
However that way all the star particles are flying behind the moon and not around it anymore.
Does anyone know how to fix this?
Thanks a ton in advance!
Preview video gif-file of the issue
Here is the js code:
const canvas = document.querySelector("canvas.webgl");
const scene = new THREE.Scene();
const sizes = {
width: window.innerWidth,
height: window.innerHeight,
};
const camera = new THREE.PerspectiveCamera(
45,
sizes.width / sizes.height,
0.1,
1000
);
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 5;
camera.layers.enable(1);
scene.add(camera);
const params = {
exposure: 1,
bloomStrength: 2,
bloomThreshold: 0,
bloomRadius: 0,
};
let composer, mixer;
const light = new THREE.AmbientLight(0xffffff, 1);
scene.add(light);
const sgeometry = new THREE.SphereGeometry(15, 32, 16);
const smaterial = new THREE.MeshBasicMaterial({ color: 0xffffff });
const ssphere = new THREE.Mesh(sgeometry, smaterial);
const loader1 = new THREE.TextureLoader();
const circle = loader1.load("a.png");
const particlesGeometry = new THREE.BufferGeometry();
const particlesCnt = 3000;
const posArray = new Float32Array(particlesCnt * 3);
for (i = 0; i < particlesCnt * 3; i++) {
posArray[i] = (Math.random() - 0.5) * (Math.random() * 20);
}
particlesGeometry.setAttribute(
"position",
new THREE.BufferAttribute(posArray, 3)
);
const mat = new THREE.PointsMaterial({
size: 0.05,
map: circle,
transparent: true,
opacity: 1,
alpha: 0.8,
alphaTest: 0.9,
alphaToCoverage: 0.91,
Blending: THREE.AdditiveBlending,
});
const particlesMesh = new THREE.Points(particlesGeometry, mat);
particlesMesh.position.set(0, 0, -1);
particlesMesh.layers.set(1);
scene.add(particlesMesh);
const geometry = new THREE.SphereBufferGeometry(1, 64, 64);
const material = new THREE.MeshPhongMaterial({
map: THREE.ImageUtils.loadTexture("moon.jpg"),
side: THREE.DoubleSide,
shininess: 0,
opacity: 1,
transparent: true,
});
const sphere = new THREE.Mesh(geometry, material);
sphere.rotation.set(0, -2.7, 0);
sphere.layers.set(0);
scene.add(sphere);
const renderer = new THREE.WebGLRenderer({
canvas: canvas,
alpha: true,
antialias: true,
});
renderer.autoClear = false;
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.toneMapping = THREE.LinearToneMapping;
const renderScene = new THREE.RenderPass(scene, camera);
const effectFXAA = new THREE.ShaderPass(THREE.FXAAShader);
effectFXAA.uniforms.resolution.value.set(
1 / window.innerWidth,
1 / window.innerHeight
);
const bloomPass = new THREE.UnrealBloomPass(
new THREE.Vector2(window.innerWidth, window.innerHeight),
1.5,
0.4,
0.85
);
bloomPass.threshold = params.bloomThreshold;
bloomPass.strength = params.bloomStrength;
bloomPass.radius = params.bloomRadius;
composer = new THREE.EffectComposer(renderer);
composer.addPass(renderScene);
composer.addPass(effectFXAA);
composer.addPass(bloomPass);
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.toneMappingExposure = Math.pow(0.9, 4.0);
window.addEventListener("resize", () => {
sizes.width = window.innerWidth;
sizes.height = window.innerHeight;
camera.aspect = sizes.width / sizes.height;
camera.updateProjectionMatrix();
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
});
const clock = new THREE.Clock();
const tick = () => {
window.requestAnimationFrame(tick);
const deltaTime = clock.getDelta();
const elapsedTime = clock.getElapsedTime();
sphere.rotation.y = 0.08 * elapsedTime;
particlesMesh.rotation.y = 0.08 * elapsedTime;
renderer.clear();
camera.layers.set(1);
composer.render();
renderer.clearDepth();
camera.layers.set(0);
renderer.render(scene, camera);
};
tick();
The problem is probably that layer 0 (with the moon) is rendered AFTER layer 1 (with the stars). This makes the renderer paint the moon over the stars.
Try to change the order of the rendering so that layer 0 is first. Keep in mind that layer 1 must render in the composer, and layer 0 with the normal renderer. I think the code will be something like this:
renderer.clear();
camera.layers.set(0);
renderer.render(scene, camera);
renderer.clearDepth();
camera.layers.set(1);
composer.render();

Three JS rotation on specific axis

How can I have an ThreeJS object rotate on an axis that is at angle.
Like from this codepen I made, the left square rotates on its center and moved up when you click on the "rotate up" button.
I want the left cure rotate along the red axis in the image attached and move along on that axis when click on the "Rotate 45 degree" button. I can make up move along the axis, but the rotation is wrong. How can I make the cute rotate along the red axis?
****EDIT:
PS: Sorry I cannot get the snippet working here. Please use the codepen link for the demo.
https://codepen.io/eforblue/pen/MWpYggY
var upTl = gsap.timeline();
var degreeTl = gsap.timeline();
var width = window.innerWidth;
var height = window.innerHeight;
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
var scene = new THREE.Scene();
var cubeGeometry = new THREE.CubeGeometry(100, 100, 100);
var cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff });
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
scene.add(cube);
var cube2 = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube2.position.set(200, 200, 0);
cube2.rotation.z = 45;
scene.add(cube2);
var camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 10000);
camera.position.set(0, 500, 3000);
camera.lookAt(cube.position);
scene.add(camera);
var skyboxGeometry = new THREE.CubeGeometry(100, 100, 100);
var skyboxMaterial = new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.BackSide });
var skybox = new THREE.Mesh(skyboxGeometry, skyboxMaterial);
var pointLight = new THREE.PointLight(0xffffff);
pointLight.position.set(0, 300, 200);
scene.add(pointLight);
var clock = new THREE.Clock();
function render() {
requestAnimationFrame(render);
// cube.rotation.y -= clock.getDelta();
renderer.render(scene, camera);
}
render();
$('.up').on('click', () => {
console.log('click')
upTl.to( cube.rotation, 1, { y: Math.PI * 3 }, 0 )
.to( cube.position, 1, { y: cube.position.y + 400 }, 0 )
})
$('.degree').on('click', () => {
degreeTl.to( cube2.rotation, 1, { y: Math.PI * 3 }, 0 )
.to( cube2.position, 1, { x: cube2.position.x + 300, y:cube2.position.y + 300 }, 0 )
});
canvas {
position: fixed;
top: 0;
left: 0;
}
button {
position:relative;
z-index: 99;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.6.1/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="./main.js"></script>
<button class="up">rotate up</button>
<button class="degree">rotate 45deg</button>
In your case it's easier to use quaternions to rotate around your red axis, you can use the following function and define your rotation axis in the "axis" parameter.
static rotateAroundWorldAxis(mesh, point, axis, angle) {
const q = new Quaternion();
q.setFromAxisAngle(axis, angle);
mesh.applyQuaternion(q);
mesh.position.sub(point);
mesh.position.applyQuaternion(q);
mesh.position.add(point);
return mesh;
}

Three.js : Pepper's Ghost Effect with OrbitControls : problem with camera translation/rotation

I would like to have an effect similar to Pepper's Ghost Effect, like here:
https://threejs.org/examples/webgl_effects_peppersghost.html
but with the possibility to rotate and scale the cube with the mouse (i.e. with OrbitControl).
But the cube does not rotate as excepted around some axes.
I set up a jsfiddle : https://jsfiddle.net/vesx5y8j/7/
'use strict';
var container;
var camera, scene, renderer, effect, cubetest, _controls;
var group;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( );
camera.position.set( 0, 0, 6 );
camera.up.set(0,1,0);
camera.lookAt( new THREE.Vector3(0,0,0) );
_controls = new THREE.OrbitControls(camera);
_controls.autoRotate = false;
_controls.autoRotateSpeed = 1.0;
_controls.noPan = true;
_controls.enabled = true;
_controls.update();
var axisHelper = new THREE.AxisHelper(100);
scene.add(axisHelper);
var cubeMaterials = [
new THREE.MeshBasicMaterial({color:0xff0000, transparent:true, opacity:0.8, side: THREE.DoubleSide}),
new THREE.MeshBasicMaterial({color:0x00ff00, transparent:true, opacity:0.8, side: THREE.DoubleSide}),
new THREE.MeshBasicMaterial({color:0x0000ff, transparent:true, opacity:0.8, side: THREE.DoubleSide}),
new THREE.MeshBasicMaterial({color:0xffff00, transparent:true, opacity:0.8, side: THREE.DoubleSide}),
new THREE.MeshBasicMaterial({color:0xff00ff, transparent:true, opacity:0.8, side: THREE.DoubleSide}),
new THREE.MeshBasicMaterial({color:0x00ffff, transparent:true, opacity:0.8, side: THREE.DoubleSide}),
];
// Create a MeshFaceMaterial, which allows the cube to have different materials on each face
var cubeMaterial = new THREE.MeshFaceMaterial(cubeMaterials);
cubetest = new THREE.Mesh( new THREE.CubeGeometry( 1, 2, 0.5), cubeMaterial );
cubetest.position.set( 0, 0, 0 );
scene.add( cubetest );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
container.appendChild( renderer.domElement );
effect = new THREE.PeppersGhostEffect( renderer );
effect.setSize( window.innerWidth, window.innerHeight );
effect.cameraDistance = 6;
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
effect.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
//cubetest.rotation.x += 0.01;
_controls.update();
effect.render( scene, camera );
}
body {
background: #777;
padding: 0;
margin: 0;
font-weight: bold;
overflow: hidden;
}
#info {
position: absolute;
top: 0px;
width: 100%;
color: #ffffff;
padding: 5px;
font-family: Monospace;
font-size: 13px;
text-align: center;
z-index: 1000;
}
a {
color: #ffffff;
}
#webglmessage a {
color: #da0
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script data-name="PeppersGhostEffect.js">
THREE.PeppersGhostEffect = function ( renderer ) {
var scope = this;
// Internals
var _halfWidth, _width, _height;
var _cameraF = new THREE.PerspectiveCamera(); //front
var _cameraB = new THREE.PerspectiveCamera(); //back
var _cameraL = new THREE.PerspectiveCamera(); //left
var _cameraR = new THREE.PerspectiveCamera(); //right
var _position = new THREE.Vector3();
var _quaternion = new THREE.Quaternion();
var _scale = new THREE.Vector3();
// Initialization
renderer.autoClear = false;
this.setSize = function ( width, height ) {
_halfWidth = width / 2;
if ( width < height ) {
_width = width / 3;
_height = width / 3;
} else {
_width = height / 3;
_height = height / 3;
}
renderer.setSize( width, height );
};
this.render = function ( scene, camera ) {
scene.updateMatrixWorld();
if ( camera.parent === null ) camera.updateMatrixWorld();
camera.matrixWorld.decompose( _position, _quaternion, _scale );
renderer.clear();
renderer.enableScissorTest( true );
//front camera
_cameraF.position.copy( _position );
_cameraF.quaternion.copy( _quaternion );
_cameraF.lookAt( new THREE.Vector3(0,0,0) );
// back camera
_cameraB.position.copy( _position );
_cameraB.quaternion.copy( _quaternion );
_cameraB.translateZ( -2.*scope.cameraDistance);
// _cameraB.translateZ( -2.*_position.z);
_cameraB.up.set(0,-1,0);
_cameraB.lookAt( new THREE.Vector3(0,0,0) );
// left camera
_cameraL.position.copy( _position );
_cameraL.quaternion.copy( _quaternion );
_cameraL.translateZ( - scope.cameraDistance);
_cameraL.translateX( - scope.cameraDistance);
// _cameraL.translateZ( -_position.z);
// _cameraL.translateX( - _position.x);
_cameraL.up.set(0,0,-1);
_cameraL.lookAt( new THREE.Vector3(0,0,0));
//right camera
_cameraR.position.copy( _position );
_cameraR.quaternion.copy( _quaternion );
_cameraR.translateZ( - scope.cameraDistance);
_cameraR.translateX( scope.cameraDistance);
_cameraR.up.set(0,0,-1);
_cameraR.lookAt( new THREE.Vector3(0,0,0) );
renderer.setScissor( _halfWidth - ( _width / 2 ), 0, _width, _height );
renderer.setViewport( _halfWidth - ( _width / 2 ), 0, _width, _height );
renderer.render( scene, _cameraF );
renderer.setScissor( _halfWidth - ( _width / 2 ), ( _height * 2 ), _width, _height );
renderer.setViewport( _halfWidth - ( _width / 2 ), ( _height * 2 ), _width, _height);
renderer.render( scene, _cameraB);
renderer.setScissor( _halfWidth - ( _width / 2 ) - _width, _height, _width, _height);
renderer.setViewport( _halfWidth - ( _width / 2 ) - _width, _height, _width,_height);
renderer.render( scene, _cameraL);
renderer.setScissor( _halfWidth + ( _width / 2 ), _height, _width, _height );
renderer.setViewport( _halfWidth + ( _width / 2 ), _height, _width, _height );
renderer.render( scene, _cameraR );
renderer.enableScissorTest( false );
};
};
</script>
The front camera (at the bottom of screen) is the camera in the original position.
Before starting rotating or scaling, the cubes show as expected.
Concerning the back camera:
It works as expected when I rotate, but scaling is inverted (it grows when the front cube decreases)
When I put in line 60 of html :
_cameraB.translateZ( -2.*_position.z);
instead of
_cameraB.translateZ( -2.*scope.cameraDistance);
then scaling works fine, but rotating gives strange results.
Concerning the left and right cameras:
Rotation works fine, when I rotate around the green axis, but not when I turn around the red axis (then the left and right cubes do not move; they should turn 90 degres).
I do not know if I just miss something (maybe due to the fact that I use quaternions without knowing how they work) or maybe it is just not possible to combine a camera move with OrbitControls ?
An alternative could be, instead of rotating camera with OrbitControls, to rotate the cube instead. But I did not find something similar to OrbitControls (with rotation and scaling possibilities) that can be applied to an object.
Thank you very much for any help !

How to change three.js THREE.Face3 color

I've just create a sample which draw a triangle using THREE.Face3 with three.js.
Here is my code snippet
var scene, camera, renderer;
var cube;
var controls;
function initScene() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 30;
renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
controls = new THREE.OrbitControls(camera);
controls.update();
document.body.appendChild(renderer.domElement);
}
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
function draw() {
var material = new THREE.MeshStandardMaterial( { color : 0x00cc00, side: THREE.DoubleSide } );
//create a triangular geometry
var geometry = new THREE.Geometry();
geometry.vertices.push( new THREE.Vector3( -5, -5, 0 ) );
geometry.vertices.push( new THREE.Vector3( 5, -5, 0 ) );
geometry.vertices.push( new THREE.Vector3( 5, 5, 0 ) );
//create a new face using vertices 0, 1, 2
var normal = new THREE.Vector3( 0, 1, 0 ); //optional
var color = new THREE.Color( 0xffaa00 ); //optional
var materialIndex = 0; //optional
var face = new THREE.Face3( 0, 1, 2);
//add the face to the geometry's faces array
geometry.faces.push( face );
//the face normals and vertex normals can be calculated automatically if not supplied above
geometry.computeFaceNormals();
geometry.computeVertexNormals();
scene.add( new THREE.Mesh( geometry, material ) );
}
initScene();
draw();
render();
body {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/94/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>
I've refered the sample code in three.js Face3 documentation, I think the sample code try to set color is 0x00cc00 or 0xffaa00, but the color of triangle in my sample is black.
How to change it?

Resources