THREE JS - how to impement the automatic 3d model scale - object

I have implemented a simple 3D model viewer with three.js. The project contains a database of 3D models, divided into different categories. In one category, the models are tall (with a relatively small width, the height is much higher than the height of the other models), in another category, the models are small (relative to all products, their height and width are smaller than in others, these are small models), in another category, the models are large (their height and wider than many models from other categories.
The viewer has a fixed canvas width and height. For this reason, when loading a model in canvas, many models are immediately loaded at a small scale, which requires subsequent multiple zooming. There are also models, the upper part of which does not fit into the canvas, and the lower part does, at boot time. This also requires subsequent scaling.
It is necessary that the viewer first estimates the dimensions of the model, after that it automatically selects the scale for the model individually, after that it centers the model vertically and horizontally.
It is also necessary that the plane in which the model lies (the model has tangible width and height, the thickness is very small, all these models are close to flat) coincide with the plane of the screen. At boot time, many models have an offset for these planes. How do I implement this so that the viewer automatically expands the model?
Below I am attaching screenshots for models from different categories - where they are clearly recorded:
Below is the code of the viewer that is responsible for initializing the scene:
var objectUrl = $('#modelViewerModal').data('object-url');//'/storage/3d/qqq.obj';
var mesh, renderer, scene, camera, controls;
init();
animate();
function init() {
const screenshotPageWidth = $(document).width();
const screenshotPageHeight = $(document).height();
let modalBody = document.querySelector('#scene-container');
// renderer
renderer = new THREE.WebGLRenderer({modalBody});
var height = screenshotPageHeight / 2;
var width = screenshotPageWidth / 2;
if (screenshotPageHeight < screenshotPageWidth) { // landscape orientation
if (width > 3 * height / 2) {
width = 3 * height / 2;
} else if (width < 3 * height / 2) {
height = 2 * width / 3;
}
} else if (screenshotPageHeight > screenshotPageWidth) { // portrait orientation
if (height > 2 * width / 3) {
height = 2 * width / 3;
} else if (height < 2 * width / 3) {
width = 3 * height / 2;
}
}
// let limitHeight = screen.height - 137;
renderer.setSize(width, height);
modalBody.appendChild( renderer.domElement );
// scene
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x000000 );
// camera
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 20, 20, 20 );
// controls
controls = new OrbitControls( camera, renderer.domElement );
// ambient
scene.add( new THREE.AmbientLight( 0x222222 ) );
// light
var light = new THREE.DirectionalLight( 0xffffff, 1 );
light.position.set( 2000, 2000, 2000 );
scene.add( light );
var spotLight_01 = getSpotlight('rgb(145, 200, 255)', 1);
spotLight_01.name = 'spotLight_01';
var spotLight_02 = getSpotlight('rgb(255, 220, 180)', 1);
spotLight_02.name = 'spotLight_02';
scene.add(spotLight_01);
scene.add(spotLight_02);
// geometry
var geometry = new THREE.SphereGeometry( 5, 12, 8 );
// material
const material = new THREE.MeshPhongMaterial({
color: 0xeae8dc,
side: THREE.DoubleSide,
transparent: false,
flatShading: false,
opacity: 0
});
// mesh
var objLoader = new THREE.OBJLoader();
objLoader.load(objectUrl,
function ( obj ) {
mesh = obj;
mesh.scale.setScalar( 0.01 );
obj.traverse( function( child ) {
if ( child.isMesh ) child.material = material;
} );
// center the object
var aabb = new THREE.Box3().setFromObject( mesh );
var center = aabb.getCenter( new THREE.Vector3() );
mesh.position.x += (mesh.position.x - center.x);
mesh.position.y += (mesh.position.y - center.y);
mesh.position.z += (mesh.position.z - center.z);
scene.add( mesh );
animate();
} );
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
function getSpotlight(color, intensity) {
var light = new THREE.SpotLight(color, intensity);
light.castShadow = true;
light.shadow.mapSize.x = 4096;
light.shadow.mapSize.y = 4096;
return light;
}

This can be done with just two things - the camera object, and the mesh object. What you need to do use use the camera frustum (the representation of the viewable area of the camera https://en.wikipedia.org/wiki/Viewing_frustum) to calculate the distance at which it is the same height (or width) as your model. The height of the model can easily be acquired from the geometry.
// Get the size of the model
mesh.geometry.computeBoundingBox()
const modelSize = mesh.geometry.boundingBox.getSize()
const width = modelSize.x // the exact axis will depend on which angle you are viewing it from, using x for demonstration here
// Compute necessary camera parameters
const fov = camera.fov
const aspect = camera.aspect // camera aspect ratio (width / height)
// three.js stores camera fov as vertical fov. We need to calculate horizontal fov
const hfov = (2 * Math.atan(Math.tan(MathUtils.degToRad(fov) / 2) * aspect) * 180) / Math.PI;
// calculate the distance from the camera at which the frustum is the same width as your model
const dist = (width * 0.5) / Math.tan(MathUtils.degToRad(hfov * 0.5));
// Position camera exactly based on model. There are more elegant ways to do this, but this is a quick and dirty solution
// Camera looks down its own negative Z axis, adding Z effectively "zooms out"
camera.position.copy(mesh.position).translateZ(dist)
These fov and frustum calculations may appear daunting, but these are well-solved problems in 3D engines, and the exact algorithms can be looked up pretty quickly with a few searches.
This solution obviously only works with width, and uses a rigid method for moving the camera, but hopefully it provides you with the tools to apply the solution in a way that works for your application.

Related

How to fit my big data into the screen that fits end to end?

const scene = new THREE.Scene();
// create a camera, which defines where we're looking at.
const camera = new THREE.PerspectiveCamera( 25, window.innerWidth /
window.innerHeight, 0.5, 1000 );
// create a render and set the size
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
// add the output of the renderer to the html element
document.body.appendChild( renderer.domElement );
// create orbiting camera controls
const controls = new OrbitControls( camera, renderer.domElement );
// position the camera
camera.position.z = 100;
camera.position.y = 10;
camera.position.x = 10;
// get the data using fetch
fetch( './json/HLE.json' )
.then( response => response.json() )
.then( data => {
// callback that is called once the data has been fetched
// iterate through the data
let i = 0;
data.forEach( row => {
// do something for each row
console.log(row.Country_Code);
console.log(row.YR2019);
// create a cube with dimensions according to the row
const max = 90;
const height = row.YR2019 / max;
const geometry = new THREE.BoxGeometry( 0.5, height, 0.5 );
const material = new THREE.MeshBasicMaterial( { color: 0x336699 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
// offset the cube to the right by the index i times offset width (to spread)
const offsetWidth = 1.0;
cube.position.x = i * offsetWidth;
// shift the cube upwards by half it's height
cube.position.y = height / 2;
// increment the index i
i += 1;
} );
} )
// Now we're ready to render our scene
//This function will be called every frame
function animate() {
// ask the browser to call this function again when it's ready to draw the next frame
requestAnimationFrame( animate );
// update the camera controls
controls.update();
// render the scene
renderer.render( scene, camera );
}
// call the animate function
animate();

THREE: Using worldmap.svg as material on sphere but there are too many pixels, how do i reduce them?

I am using an svg so I can color single countries.
I know WebGL doesn't support svg, thats why it gets pixeled but the borderlines are pixeled too much, any idea how I can make it look better?
"THREE.WebGLRenderer: Texture has been resized from (2000x1001) to (1024x512)"?
The image gets cropped, is that the problem?
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
let scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var geometry = new THREE.SphereGeometry( 5,32,32 );
let texture = new THREE.TextureLoader().load("/img/world-background.5375a735.svg");
var material = new THREE.MeshBasicMaterial( { map: texture, color: "white"} );
var sphere = new THREE.Mesh( geometry, material );
sphere.rotation.y = 4.5;
sphere.rotation.x = 0.5;
scene.add( sphere );
To avoid the resize, try to set the minFilter property of your texture to THREE.LinearFilter. This should noticeably improve the final texture resolution in your case. Alternatively, you can try to change your texture to POT (power-of-two) by default. That would mean using a resolution like 2048x1024.
three.js R112

three.js orbit object around a changing axis

I have a simple 3D object and I am able to rotate i.e., move with my left mouse button, around the centre of axis - works fine. When I pan using the right mouse button the axis also shifts, as such it no longer moves around it’s present axis.
How can I move the object around it’s current axis, no matter where I drag the object?
Below is the complete code of script.js
var scene = new THREE.Scene();
var axisHelper = new THREE.AxisHelper(100);
scene.add(axisHelper);
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.y = -200;
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = true;
var keyLight = new THREE.DirectionalLight(new THREE.Color('hsl(30, 100%, 75%)'), 1.0);
keyLight.position.set(-100, 0, 100);
var fillLight = new THREE.DirectionalLight(new THREE.Color('hsl(240, 100%, 75%)'), 0.75);
fillLight.position.set(100, 0, 100);
var backLight = new THREE.DirectionalLight(0xffffff, 1.0);
backLight.position.set(100, 0, -100).normalize();
scene.add(keyLight);
scene.add(fillLight);
scene.add(backLight);
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setTexturePath('assets/');
mtlLoader.setPath('assets/');
mtlLoader.load('180319_object01.mtl', function (materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('assets/');
objLoader.load('180319_object01.obj', function (object) {
object.scale.set( 200, 200, 200 );
scene.add(object);
object.position.x = -100;
object.position.y = -100;
object.position.z = 0;
});
});
var animate = function () {
requestAnimationFrame( animate );
controls.update();
renderer.render(scene, camera);
};
animate();
It is because your camera is being moved by the controller and not the object itself, rather than update the cameras position and direction ((ie which is what the orbit controller is doing).in your render method you'll want to update position and Euler angle on the object itself to achieve the desired effect. To do this you'll want to track and update the position and angle of rotation about the (y?) Axis of the object,in the object (model) space.hope that makes sense, let me know if you need me to elaborate.

Three.js scene does not render in Safari 11.0.2

I'm trying to determine why a Three.js scene does not render in Safari 11.0.2 (OSX 10.12.6).
/**
* Generate a scene object with a background color
**/
function getScene() {
var scene = new THREE.Scene();
scene.background = new THREE.Color(0x111111);
return scene;
}
/**
* Generate the camera to be used in the scene. Camera args:
* [0] field of view: identifies the portion of the scene
* visible at any time (in degrees)
* [1] aspect ratio: identifies the aspect ratio of the
* scene in width/height
* [2] near clipping plane: objects closer than the near
* clipping plane are culled from the scene
* [3] far clipping plane: objects farther than the far
* clipping plane are culled from the scene
**/
function getCamera() {
var aspectRatio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 10000);
camera.position.set(0,150,400);
camera.lookAt(scene.position);
return camera;
}
/**
* Generate the light to be used in the scene. Light args:
* [0]: Hexadecimal color of the light
* [1]: Numeric value of the light's strength/intensity
* [2]: The distance from the light where the intensity is 0
* #param {obj} scene: the current scene object
**/
function getLight(scene) {
var lights = [];
lights[0] = new THREE.PointLight( 0xffffff, 0.6, 0 );
lights[0].position.set( 100, 200, 100 );
scene.add( lights[0] );
var ambientLight = new THREE.AmbientLight(0x111111);
scene.add(ambientLight);
return light;
}
/**
* Generate the renderer to be used in the scene
**/
function getRenderer() {
// Create the canvas with a renderer
var renderer = new THREE.WebGLRenderer({antialias: true});
// Add support for retina displays
renderer.setPixelRatio(window.devicePixelRatio);
// Specify the size of the canvas
renderer.setSize(window.innerWidth, window.innerHeight);
// Add the canvas to the DOM
document.body.appendChild(renderer.domElement);
return renderer;
}
/**
* Generate the controls to be used in the scene
* #param {obj} camera: the three.js camera for the scene
* #param {obj} renderer: the three.js renderer for the scene
**/
function getControls(camera, renderer) {
var controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.zoomSpeed = 0.4;
controls.panSpeed = 0.4;
return controls;
}
/**
* Get grass
**/
function getPlane(scene, loader) {
var texture = loader.load('grass.jpg');
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 10, 10 );
var material = new THREE.MeshBasicMaterial({
map: texture, side: THREE.DoubleSide
});
var geometry = new THREE.PlaneGeometry(1000, 1000, 10, 10);
var plane = new THREE.Mesh(geometry, material);
plane.position.y = -0.5;
plane.rotation.x = Math.PI / 2;
scene.add(plane);
return plane;
}
/**
* Add background
**/
function getBackground(scene, loader) {
var imagePrefix = '';
var directions = ['right', 'left', 'top', 'bottom', 'front', 'back'];
var imageSuffix = '.bmp';
var geometry = new THREE.BoxGeometry( 1000, 1000, 1000 );
var materialArray = [];
for (var i = 0; i < 6; i++)
materialArray.push( new THREE.MeshBasicMaterial({
map: loader.load(imagePrefix + directions[i] + imageSuffix),
side: THREE.BackSide
}));
var sky = new THREE.Mesh( geometry, materialArray );
scene.add(sky);
}
/**
* Add a character
**/
function getSphere(scene) {
var geometry = new THREE.SphereGeometry( 30, 12, 9 );
var material = new THREE.MeshPhongMaterial({
color: 0xd0901d,
emissive: 0xaf752a,
side: THREE.DoubleSide,
flatShading: true
});
var sphere = new THREE.Mesh( geometry, material );
// create a group for translations and rotations
var sphereGroup = new THREE.Group();
sphereGroup.add(sphere)
sphereGroup.position.set(0, 24, 100);
scene.add(sphereGroup);
return [sphere, sphereGroup];
}
/**
* Store all currently pressed keys
**/
function addListeners() {
window.addEventListener('keydown', function(e) {
pressed[e.key.toUpperCase()] = true;
})
window.addEventListener('keyup', function(e) {
pressed[e.key.toUpperCase()] = false;
})
}
/**
* Update the sphere's position
**/
function moveSphere() {
var delta = clock.getDelta(); // seconds
var moveDistance = 200 * delta; // 200 pixels per second
var rotateAngle = Math.PI / 2 * delta; // pi/2 radians (90 deg) per sec
// move forwards/backwards/left/right
if ( pressed['W'] ) {
sphere.rotateOnAxis(new THREE.Vector3(1,0,0), -rotateAngle)
sphereGroup.translateZ( -moveDistance );
}
if ( pressed['S'] )
sphereGroup.translateZ( moveDistance );
if ( pressed['Q'] )
sphereGroup.translateX( -moveDistance );
if ( pressed['E'] )
sphereGroup.translateX( moveDistance );
// rotate left/right/up/down
var rotation_matrix = new THREE.Matrix4().identity();
if ( pressed['A'] )
sphereGroup.rotateOnAxis(new THREE.Vector3(0,1,0), rotateAngle);
if ( pressed['D'] )
sphereGroup.rotateOnAxis(new THREE.Vector3(0,1,0), -rotateAngle);
if ( pressed['R'] )
sphereGroup.rotateOnAxis(new THREE.Vector3(1,0,0), rotateAngle);
if ( pressed['F'] )
sphereGroup.rotateOnAxis(new THREE.Vector3(1,0,0), -rotateAngle);
}
/**
* Follow the sphere
**/
function moveCamera() {
var relativeCameraOffset = new THREE.Vector3(0,50,200);
var cameraOffset = relativeCameraOffset.applyMatrix4(sphereGroup.matrixWorld);
camera.position.x = cameraOffset.x;
camera.position.y = cameraOffset.y;
camera.position.z = cameraOffset.z;
camera.lookAt(sphereGroup.position);
}
// Render loop
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
moveSphere();
moveCamera();
};
// state
var pressed = {};
var clock = new THREE.Clock();
// globals
var scene = getScene();
var camera = getCamera();
var light = getLight(scene);
var renderer = getRenderer();
// add meshes
var loader = new THREE.TextureLoader();
var floor = getPlane(scene, loader);
var background = getBackground(scene, loader);
var sphereData = getSphere(scene);
var sphere = sphereData[0];
var sphereGroup = sphereData[1];
addListeners();
render();
body { margin: 0; overflow: hidden; }
canvas { width: 100%; height: 100%; }
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js'></script>
<script src='https://threejs.org/examples/js/controls/TrackballControls.js'></script>
More generally, all of the examples at shadertoy.com [example] either do not appear or appear very faintly and almost entirely in white on Safari 11.0.2.
The same holds for the "Safari Technology Preview" even after I turn on all experimental web features, including WebGL 2.0.
I'd like to figure out how to make the scene render, but I'm more interested in learning how others attempt to debug this kind of problem. Are there tools or resources that can help one pinpoint this kind of problem (like a developer tools just for WebGL)?
This looks like a compositing bug in Safari. Hopefully Apple will fix it.
There are several workrounds. The easist seems to be to set the background color of the body or canvas to black.
/**
* Generate a scene object with a background color
**/
function getScene() {
var scene = new THREE.Scene();
scene.background = new THREE.Color(0x111111);
return scene;
}
/**
* Generate the camera to be used in the scene. Camera args:
* [0] field of view: identifies the portion of the scene
* visible at any time (in degrees)
* [1] aspect ratio: identifies the aspect ratio of the
* scene in width/height
* [2] near clipping plane: objects closer than the near
* clipping plane are culled from the scene
* [3] far clipping plane: objects farther than the far
* clipping plane are culled from the scene
**/
function getCamera() {
var aspectRatio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 10000);
camera.position.set(0,150,400);
camera.lookAt(scene.position);
return camera;
}
/**
* Generate the light to be used in the scene. Light args:
* [0]: Hexadecimal color of the light
* [1]: Numeric value of the light's strength/intensity
* [2]: The distance from the light where the intensity is 0
* #param {obj} scene: the current scene object
**/
function getLight(scene) {
var lights = [];
lights[0] = new THREE.PointLight( 0xffffff, 0.6, 0 );
lights[0].position.set( 100, 200, 100 );
scene.add( lights[0] );
var ambientLight = new THREE.AmbientLight(0x111111);
scene.add(ambientLight);
return light;
}
/**
* Generate the renderer to be used in the scene
**/
function getRenderer() {
// Create the canvas with a renderer
var renderer = new THREE.WebGLRenderer({antialias: true});
// Add support for retina displays
renderer.setPixelRatio(window.devicePixelRatio);
// Specify the size of the canvas
renderer.setSize(window.innerWidth, window.innerHeight);
// Add the canvas to the DOM
document.body.appendChild(renderer.domElement);
return renderer;
}
/**
* Generate the controls to be used in the scene
* #param {obj} camera: the three.js camera for the scene
* #param {obj} renderer: the three.js renderer for the scene
**/
function getControls(camera, renderer) {
var controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.zoomSpeed = 0.4;
controls.panSpeed = 0.4;
return controls;
}
/**
* Get grass
**/
function getPlane(scene, loader) {
var texture = loader.load('grass.jpg');
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 10, 10 );
var material = new THREE.MeshBasicMaterial({
map: texture, side: THREE.DoubleSide
});
var geometry = new THREE.PlaneGeometry(1000, 1000, 10, 10);
var plane = new THREE.Mesh(geometry, material);
plane.position.y = -0.5;
plane.rotation.x = Math.PI / 2;
scene.add(plane);
return plane;
}
/**
* Add background
**/
function getBackground(scene, loader) {
var imagePrefix = '';
var directions = ['right', 'left', 'top', 'bottom', 'front', 'back'];
var imageSuffix = '.bmp';
var geometry = new THREE.BoxGeometry( 1000, 1000, 1000 );
var materialArray = [];
for (var i = 0; i < 6; i++)
materialArray.push( new THREE.MeshBasicMaterial({
map: loader.load(imagePrefix + directions[i] + imageSuffix),
side: THREE.BackSide
}));
var sky = new THREE.Mesh( geometry, materialArray );
scene.add(sky);
}
/**
* Add a character
**/
function getSphere(scene) {
var geometry = new THREE.SphereGeometry( 30, 12, 9 );
var material = new THREE.MeshPhongMaterial({
color: 0xd0901d,
emissive: 0xaf752a,
side: THREE.DoubleSide,
flatShading: true
});
var sphere = new THREE.Mesh( geometry, material );
// create a group for translations and rotations
var sphereGroup = new THREE.Group();
sphereGroup.add(sphere)
sphereGroup.position.set(0, 24, 100);
scene.add(sphereGroup);
return [sphere, sphereGroup];
}
/**
* Store all currently pressed keys
**/
function addListeners() {
window.addEventListener('keydown', function(e) {
pressed[e.key.toUpperCase()] = true;
})
window.addEventListener('keyup', function(e) {
pressed[e.key.toUpperCase()] = false;
})
}
/**
* Update the sphere's position
**/
function moveSphere() {
var delta = clock.getDelta(); // seconds
var moveDistance = 200 * delta; // 200 pixels per second
var rotateAngle = Math.PI / 2 * delta; // pi/2 radians (90 deg) per sec
// move forwards/backwards/left/right
if ( pressed['W'] ) {
sphere.rotateOnAxis(new THREE.Vector3(1,0,0), -rotateAngle)
sphereGroup.translateZ( -moveDistance );
}
if ( pressed['S'] )
sphereGroup.translateZ( moveDistance );
if ( pressed['Q'] )
sphereGroup.translateX( -moveDistance );
if ( pressed['E'] )
sphereGroup.translateX( moveDistance );
// rotate left/right/up/down
var rotation_matrix = new THREE.Matrix4().identity();
if ( pressed['A'] )
sphereGroup.rotateOnAxis(new THREE.Vector3(0,1,0), rotateAngle);
if ( pressed['D'] )
sphereGroup.rotateOnAxis(new THREE.Vector3(0,1,0), -rotateAngle);
if ( pressed['R'] )
sphereGroup.rotateOnAxis(new THREE.Vector3(1,0,0), rotateAngle);
if ( pressed['F'] )
sphereGroup.rotateOnAxis(new THREE.Vector3(1,0,0), -rotateAngle);
}
/**
* Follow the sphere
**/
function moveCamera() {
var relativeCameraOffset = new THREE.Vector3(0,50,200);
var cameraOffset = relativeCameraOffset.applyMatrix4(sphereGroup.matrixWorld);
camera.position.x = cameraOffset.x;
camera.position.y = cameraOffset.y;
camera.position.z = cameraOffset.z;
camera.lookAt(sphereGroup.position);
}
// Render loop
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
moveSphere();
moveCamera();
};
// state
var pressed = {};
var clock = new THREE.Clock();
// globals
var scene = getScene();
var camera = getCamera();
var light = getLight(scene);
var renderer = getRenderer();
// add meshes
var loader = new THREE.TextureLoader();
var floor = getPlane(scene, loader);
var background = getBackground(scene, loader);
var sphereData = getSphere(scene);
var sphere = sphereData[0];
var sphereGroup = sphereData[1];
addListeners();
render();
body { margin: 0; overflow: hidden; }
canvas { width: 100%; height: 100%; background: black; }
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js'></script>
<script src='https://threejs.org/examples/js/controls/TrackballControls.js'></script>
As for how to know how to find this bugs, in this particular case I don't know how I knew except experience. I know it's unfortunately common for browsers to get compositing bugs with WebGL because it's very hard to test. Most browsers test on servers without GPUs which means they don't test WebGL enough. They built their testing systems before compositing was GPU accelerated. Another reason is testing compositing is something that's browser specific so the WebGL tests can't include a test for it. It's something each browser vendor has to implement their own tests for and often their testing systems run the browsers in non-release modes or the APIs that might make it possible to test don't actually go through the same code as the code the draws to the screen .
For WebGL, you should generally get the same results across browsers and compositing issues are the most common place they get it wrong. Especially when not using the defauts. So, first I checked the if the context was set up non-default as in either alpha: false or premultipliedAlpha: false etc.. To do that I just opened Chrome's dev tools and selected the snippet context
Once I had the correct debugger context I just got the WebGL context from the first canvas
I saw alpha: false which is not the default so that was the first clue. If there was more than one canvas I would have had to use 'querySelectorAll' and try each canvas until I got the WebGL one.
Then I also saw your CSS is different than I would do it. I would have used
body { margin: 0; }
canvas { width: 100vw; height: 100vw; display: block; }
No need for overflow: hidden and clearly states what I want. I have strong opinions that the way most three.js apps size the canvas is an anti-pattern.
I saw that you set your css to make the canvas height 100% but you didn't set the body height and so if nothing else was done your canvas would have zero height. So, I set the background color of the canvas so I could see how big it was. I was assuming it was actually zero. That's when (a) I saw it was rendering and setting the background color made it appear and (b) your canvas appears because three.js is hacking in the canvas sizes based on window.innerHeight and also mucking with your css

Loading SVG (Scalable Vector Graphics) into AndEngine

I am trying to load some SVG's into my game, but I am having truoble. I have tried reading the Android cook book, docs and answers from the forum, but I can't find a solution. I'm now at a state where I can actually load the images in and the game builds, but now I cannot display them. See as follows:
Loading in the .svg image:
BuildableBitmapTextureAtlas bitmapTextureAtlas = new BuildableBitmapTextureAtlas(
engine.getTextureManager(), 1024, 1024, TextureOptions.BILINEAR); //setting up texture atlas
try {
this.mBuildableBitmapTextureAtlas
.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(
0, 0, 1));
} catch (final TextureAtlasBuilderException e) {
Debug.e(e);
}
SVGBitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/game/");
mLowResTextureRegion = SVGBitmapTextureAtlasTextureRegionFactory
.createFromAsset(bitmapTextureAtlas, activity,
"spinningarrow.svg", 32, 32);
mMedResTextureRegion = SVGBitmapTextureAtlasTextureRegionFactory
.createFromAsset(bitmapTextureAtlas, activity, "spinningarrow.svg",
128, 128);
// Create a high-res (256x256) texture region of svg_image.svg
mHiResTextureRegion = SVGBitmapTextureAtlasTextureRegionFactory
.createFromAsset(bitmapTextureAtlas, activity, "spinningarrow.svg",
256, 256);
bitmapTextureAtlas.load();
Actually attaching it to the scene:
float currentSpritePosition = (WIDTH / ((SPRITE_SIZE) * SPRITE_COUNT)) + SPRITE_SIZE * 0.5f;
Sprite lowResSprite = new Sprite(currentSpritePosition, HEIGHT / 2, SPRITE_SIZE, SPRITE_SIZE, rM.mLowResTextureRegion, rM.engine.getVertexBufferObjectManager());
attachChild(lowResSprite);
currentSpritePosition += SPRITE_SIZE;
// Create & attach the med-res sprite to the scene (mid)
Sprite medResSprite = new Sprite(currentSpritePosition, HEIGHT / 2, SPRITE_SIZE, SPRITE_SIZE, rM.mMedResTextureRegion, rM.engine.getVertexBufferObjectManager());
attachChild(medResSprite);
currentSpritePosition += SPRITE_SIZE;
// Create & attach the high-res sprite to the scene (right side)
Sprite hiResSprite = new Sprite(currentSpritePosition, HEIGHT / 2, SPRITE_SIZE, SPRITE_SIZE, rM.mHiResTextureRegion, rM.engine.getVertexBufferObjectManager());
attachChild(hiResSprite);
This builds, but I cannot see the image; even if I hard code its coordinates.
The svg in question is at http://www.sendspace.com/file/nnjsfe

Resources