Transparant spritesheet animation for webgl - three.js

I'm just getting started with webgl and was trying to make an animation based on a spritesheet. I've found an example and changed the spritesheet to my own. However even though I removed the white background, saved it as a transparant png, the animation still shows up with a white background.
This is the example I used:
http://stemkoski.github.io/Three.js/Texture-Animation.html
Is there any way how I can get rid off the white background?
Thanks in advance.
EDIT:
var runnerTexture = new THREE.ImageUtils.loadTexture( 'images/run.png' );
annie = new TextureAnimator( runnerTexture, 10, 1, 10, 75 ); // texture, #horiz, #vert, #total, duration.
var runnerMaterial = new THREE.MeshBasicMaterial( { map: runnerTexture, side:THREE.DoubleSide } );
var runnerGeometry = new THREE.PlaneGeometry(50, 50, 1, 1);
var runner = new THREE.Mesh(runnerGeometry, runnerMaterial);
runner.position.set(-150,25,0);
scene.add(runner);

To support PNGs with an alpha-channel, you have to modify the MeshBasicMaterial accordingly: There is an attribute 'transparent' which you could set to 'true'.
Try using the following line instead:
var runnerMaterial = new THREE.MeshBasicMaterial( { map: runnerTexture, side:THREE.DoubleSide, transparent: true } );
See also the reference from Material:
.transparent
Defines whether this material is transparent. This has an effect on
rendering as transparent objects need special treatment and are
rendered after non-transparent objects. For a working example of this
behaviour, check the WebGLRenderer code. When set to true, the extent
to which the material is transparent is controlled by setting opacity.

Related

Applying Alpha Map to model using material causes model to show up as white

Attempting to use an alpha map to reveal reveal an underlying model according to the alpha maps. Currently the alpha map overrides the model texture and shows as all white.
I've tried loading the alpha map alone and applying it to a material which then gets attached to the object --> Shows the relevant alpha map as white, does not reveal the underlying model as expected
I've tried loading up the alpha map and also the texture into a MeshBasicMaterial --> Shows the full texture with none of it transparent
let material = new THREE.MeshBasicMaterial({
// map: iceTexture,
color: '0xffffff',
transparent : false,
side: THREE.DoubleSide,
alphaTest: 0.5,
alphaMap: this.alphaMaps[0]
});
The current result is that the alpha map shows as all white --> Current Output
This is the underlying texture I expect to be showing (just where the alpha map allows it to) --> Underlying Texture
NOTE: I am currently not using any shaders, the underlying model is a simple glb with the ice texture above applied
NOTE 2: In this answer It says to add in a second object behind the first object...that does not work, it just shows the object on top with no transparency applied
I think the line that's messing you up is transparent: false, when it should be transparent: true. I just tried the code below (click here for a live CodePen demo), and the transparency works as expected. I also don't think you need alphaTest: 0.5, since it seems you have an animation sequence that moves the gradient.
In the demo, I use this image as the alphaMap:
... and this image as the regular map:
The essence of the code is below:
// Load the textures
const texLoader = new THREE.TextureLoader();
var alphaTexture = texLoader.load("https://i.imgur.com/aH0jI5N.png");
var mapTexture = texLoader.load("https://i.imgur.com/qdWJkbc.jpg");
// Create geometry
var geometry = new THREE.PlaneBufferGeometry(10, 10, 10, 10);
// Create a basic material
var material = new THREE.MeshBasicMaterial({
map: mapTexture,
alphaMap: alphaTexture,
transparent: true
});
var plane = new THREE.Mesh( geometry, material );

Is it possible to render a shadow in three.js without it having to be cast from an object

I am making a horror game and want to make a shadow move on a wall but I want it to appear as if it originated from no particular object. Is this possible and if so how do I implement this?
I have the feeling that dynamic textures will probably be the way to go but I am hoping there is some way using the three.js shadow map
You want a scene object to cast a shadow but be invisible.
First make sure your object will cast a proper shadow, then make the object invisible by adding:
object.material.colorWrite = false;
object.material.depthWrite = false;
The depthWrite setting is required if there are other objects in the scene. That property is not considered by the shadow mapping code.
Alternatively, you can try this, instead:
object.material.colorWrite = false;
object.material.transparent = true; // only needed if there are other transparent objects
object.renderOrder = Infinity;
three.js r.92
There's two ways to achieve this. One of them is by going "under the hood" of THREE.js and rendering the ShadowMap separately, with the object visibility = true, then setting visibility to false, then rendering the scene.
A much easier way is by assigning your object's opacity to something really low. Try 0.0001. It'll cast shadows, but be virtually invisible:
var ghostGeom = new THREE.BoxBufferGeometry(1, 1, 1);
var ghostMat = new THREE.MeshBasicMaterial({
color: 0x000000,
transparent: true,
opacity: 0.0001
});
var ghostMesh = new THREE.Mesh(ghostGeom, ghostMat);
ghostMesh.castShadow = true;
Alternatively, you can use AdditiveBlending on the material, with the color set to pitch black. This will add 0 color to the final render, while still casting shadows:
var ghostMat = new THREE.MeshBasicMaterial({
color: 0x000000,
transparent: true,
blending: THREE.AdditiveBlending
});
I think what you need is a Projector which will cast a quad texture onto the ground or the wall.

Simple Background Color in Three.js/WebGL Globe

I'm implementing this WebGL Globe Chrome Experiments on my page and simply need to change the background color.
The standard is black, but this example managed to have a nice either transparent or white background. Ideally, I'd really prefer transparent, but white works too.
If you want white on the background then use
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor( 0xffffff );
if you want transparent then use
var renderer = new THREE.WebGLRenderer( { alpha: true } );
renderer.setClearColor( 0x000000, 0 ); // the second parameter is opacity

Three.js: Add a texture to an object just on the outside

I'm very new with Three.js and I'm trying to make a ring:
http://www.websuvius.it/atma/myring/preview.html
I have a background texture ( the silver one ) and another one with a text.
I want the text only on the ring external face.
This is part of my code:
var loader = new THREE.OBJLoader( manager );
var textureLoader = new THREE.TextureLoader( manager );
loader.load( 'assets/3d/ring.obj', function ( event ) {
var object = event;
var geometry = object.children[ 0 ].geometry;
var materials = [];
var backgroundTexture = textureLoader.load('img/texture/silver.jpg');
backgroundTexture.flipY = false;
var background = new THREE.MeshBasicMaterial({
map: backgroundTexture,
color: 0xffffff
});
materials.push(background);
var customTexture = textureLoader.load('img/text.png');
customTexture.flipY = false;
var custom = new THREE.MeshBasicMaterial({
map: customTexture,
transparent: true,
opacity: 1,
color: 0xffffff
});
materials.push(custom);
mesh = THREE.SceneUtils.createMultiMaterialObject(geometry, materials);
mesh.position.y=-50;
scene.add(mesh);
}, onProgress, onError );
It is possible?
Thanks
The reason behind your issue appears to be in your .obj file. Judging from a quick glance at the texture coordinates stored in the file, the inside of the ring uses the same part of the texture image as the outside of the ring.
Increasing the transparent parts of the image won't help. Neither will the attempts to stop the texture from repeating. Those would help if the texture coordinates were larger than 1 but this is not your case unfortunately.
However, there are several solutions:
Split the object in a 3D modeling software to two objects - outside and inside of the ring - and apply the texture only to the first one.
Adjust the UV coordinates of the object in a 3D modeling software.
Adjust the UV coordinates of the vertices programmatically after loading the object to Three.JS

text in three.js: transparency lost when rotating

I'm trying the second approach to use Text in three.js, drawing on a canvas and using the result as a texture. It basically works, except for the following problem -don't know if it's a bug:
I create two texts, with transparent background, and overlap then. They show ok, but when I rotate one of them, the transparency is messed up.
I create the text objects with following (excerpt) function
function createText(text, ...){
var textHolder = document.createElement( 'canvas' );
var ctext = textHolder.getContext('2d');
...
var tex = new THREE.Texture(textHolder);
var mat = new THREE.MeshBasicMaterial( { map: tex, overdraw: true});
mat.transparent = true;
mat.map.needsUpdate = true;
var textBoard = new THREE.Mesh(new THREE.PlaneGeometry(textHolder.width, textHolder.height),mat);
textBoard.dynamic = true;
textBoard.doubleSided = true;
return textBoard;
}
and add them to the scene.
See demonstration with full code in jsfiddle
Transparency is tricky in webGL.
The best solution in your case is to do the following for your transparent text material:
mat.depthTest = false;
updated fiddle: http://jsfiddle.net/SXA8n/4/
three.js r.55

Resources