ThreeJS TextureLoader is black in .NET blazor application - javascript

When using textureloader from three.js in a blazor application. when trying to get a picture on a cube, it just gets displayed in black. I have tried a lot of things including:
new THREE.TextureLoader().load('https://images.pexels.com/photos/2422/sky-earth-galaxy-universe.jpg?auto=compress&cs=tinysrgb&dpr=1&w=500', function (texture) {
var objGeometry = new THREE.SphereBufferGeometry(11, 11, 11);
var objMaterial = new THREE.MeshPhongMaterial({
map: texture,
shading: THREE.FlatShading
});
moonMesh = new THREE.Mesh(objGeometry, objMaterial);
scene.add(moonMesh);
});
Local images that are preloaded don't work, tried with and without callback. Tried another browser.
The console is empty, if I log the texture, it's always define.
Still the sphere is always displayed in black. Maybe a light is missing, although they don't get used in any example. The js is loaded from a blazor page using the following code:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
object[] args = { canvasId };
await JSRuntime.InvokeVoidAsync("threeExample", args); // NOTE: call JavaScript function
}
And the scene and stuff load fine, I can use orbidcontrols, normal cubes with a color texture are visibe. Any ideas?
EDIT:
When using MeshBasicMaterial It works! So I guess I used the wrong type of material to use the texture.
Kind regards

Related

Texture won't load - Three.js

I'm trying to load a texture for my mesh using three.js, but instead of loaded texture I'm getting plain black object. I did it as it is in three.js docs (https://threejs.org/docs/?q=texture#api/en/loaders/TextureLoader - Example) and also tried different solutions but nothing worked. Here is the code
//Creating The Sun model
const sunGeometry = new THREE.SphereGeometry(16, 30, 30);
const texture = new THREE.TextureLoader().load('assets/images/sun.jpg');
const sunMaterial = new THREE.MeshBasicMaterial({ map: texture }); // not working
//const sunMaterial = new THREE.MeshBasicMaterial({ color: 'skyblue' }); //working
const sun = new THREE.Mesh(sunGeometry, sunMaterial);
//Adding The Sun to the Scene
scene.add(sun);
renderer.render(scene, camera);
Setting a mesh color works perfectly fine tho. Also tried using urls, no difference.
I'm using Angular and that code is in a constructor
Edit: image path is correct
You're calling renderer.render(scene, camera); immediately after creating your Mesh, but at that time the texture hasn't loaded yet. Textures can take a fraction of a second to load, so by the time they're loaded the rendering has already taken place. If you're calling render() at 60 frames per second, you probably won't notice this delay, but if you're calling it only once, then you'll get a black material.
If you only want to call render() once after the texture has loaded, you should just use the onLoad callback in the method outlined in the code example of the docs page.

Three.js – Applying texture to Collada mesh yields unexpected result

Following the Three.js ColladaLoader example, I've exported a Cinema4D soda
can model (consisting of 4 meshes) to a .dae file. One of the meshes, the body of the can, I want to add a texture to.
In Cinema4D I've already made a texture based on a UV map of the mesh (spherical). However, when I try to apply the texture to the mesh, it simply shows a solid white fill. I've added the entire code in this Codepen. Relevant code below, edited for brevity:
loader = new THREE.ColladaLoader();
loader.load('can.dae', function (collada) {
can = collada.scene;
can.traverse(function (node) {
var textureLoader
if (node.name == 'wrapper') {
textureLoader = new THREE.TextureLoader();
textureLoader.load('wrapper.png', function (texture) {
node.material = new THREE.MeshBasicMaterial({
map: texture
});
node.material.needsUpdate = true;
});
}
});
scene.add(can);
});
Illustration of the result. As you can see, the wrapper of the can isn't the red wrapper.png provided, but a solid white fill. I've tried experimenting with mapping and wrapping modes, but to no avail. Any help very much appreciated!
FYI: I've already ruled out CORS issues.
I added a cube in your loader and gave it that material and it worked.. so the implication is that your can mesh does not have proper UV coordinates assigned to it.. Perhaps it is using an automatic cylindrical mapping in your authoring software which is not exporting it's UVs? What software are you authoring in?
scene.add(new THREE.Mesh(new THREE.BoxGeometry(1,1,1),node.material));
https://codepen.io/manthrax/pen/ePBZbZ?editors=1001

Using CanvasTexture with a Sprite

I am upgrading some code that used to work with three.js r61 to three.js r74. I know, it's a big jump, but things are not always as they should be.
One of the remaining things that I still didn't get to work properly is a texture built using a canvas, used in a SpriteMaterial which is then used for a THREE.Sprite.
So far, I did the following:
Changed Texture to CanvasTexture
In SpriteMaterial, commented out the usage of useScreenCoordinates, alignment and sizeAttenuation
I tried various stuff, but it seems like this thing just doesn't display at all. Is there any such example anywhere? I just want to display an artifact that is built in a canvas.
Update: the code below is what I tried so far:
var loader = new THREE.TextureLoader();
loader.load(canvas.toDataURL(), function(texture) {
var material = new THREE.SpriteMaterial({
map: texture,
blending: THREE.AdditiveBlending,
color: me.color,
opacity: me.opacity,
transparent: me.transparent,
visible: me.visible
});
var sprite = new THREE.Sprite(material);
scene.add(sprite);
});
You're quite light on details but here's one good way to do it:
https://jsfiddle.net/_jered/xcej4ec6/
var loader = new THREE.TextureLoader();
loader.load(canvas.toDataURL(), function(d){
// 'd' is the loaded texture
// apply it to the object here
});
Basically, just use the built in Loader classes to load the assets you need, including from canvas. It's important to use Loaders and callbacks because assets will become ready asynchronously, and you need to wait until they're done before you make use of them. In my example, I create the mesh with a placeholder texture, and apply it in the Loader's callback.

Why won't a normalMap render correctly when using THREE.SubdivisionModifier?

I need to render a 'soft' cube with a normal map. I'm not getting any errors or warnings when running the code, but when I specify the normal map parameter in the function call and refresh the browser, I see a black object. If I remove the normal map, I can successfully render a cube with a Phong material. Interestingly, if I change the material to a Normal material, and attempt to texture the cube, the actual RGB normal map that I'm tring to use otherwise is applied. Also, I can get the normal map to work properly if I don't use THREE.SubdivisionModifier() on the cube, and simply render a sharp-edged cube. Any ideas? Thanks in advance. Here's my code:
var cube_geo = new THREE.BoxGeometry(.1, .1, .1, 5, 5, 5);
var smooth = cube_geo.clone();
var modifier = new THREE.SubdivisionModifier(5);
modifier.modify(smooth);
var cube_mat = new THREE.MeshPhongMaterial(
{
color: 0x000000,
specular: 0x222222,
normalMap: cube_normal_map,
}
);
cube = new THREE.Mesh(smooth, cube_mat);
scene.add(cube);
Three.SubdivisionModifier currently has a limitation in that is does not handle UVs.
See the note in the source code of SubdivisionModifier.js.
three.js r.70

How to texture animated js model exported from blender ? [Three.js]

I have successfully animated a model in blender using bone animation technique and i have also textured it in blender using uv texturing. Then Using three.js export add-on in blender i have exported the model making sure uv and animation in checked in. However i don't know the technique to load the texture for the animated model. I viewed the morph normal example included in three.js where there is simple color texture is used using Lambert material. I have texture from external file. How do i load the texture. In js animated model file there is location for the texture and it is in same location. But it doesn't load. i used the face material technique as well.
the location for three.js example that i used to modify:
http://threejs.org/examples/webgl_morphnormals.html
Here is my code:
var loader = new THREE.JSONLoader();
loader.load( "bird_final.js", function( geometry, materials ) {
morphColorsToFaceColors( geometry );
geometry.computeMorphNormals();
// the old code to set color to the model
//var material = new THREE.MeshLambertMaterial( { color: 0xffffff, morphTargets: true, morphNormals: true, vertexColors: THREE.FaceColors, shading: THREE.SmoothShading } );
// my code
var meshAnim = new THREE.MorphAnimMesh( geometry, new THREE.MeshFaceMaterial( materials ) );
meshAnim.duration = 500;
meshAnim.scale.set( 20, 20, 20 );
meshAnim.position.y = 150;
meshAnim.position.x = -100;
scene1.add( meshAnim );
morphs.push( meshAnim );
} );
Except the documentation and some basic tutorials scattered across the web, is there anywhere i can learn three.js from ground up. like i know setting up scene and creating basic geometry stuffs but some detail info like loading textured model loading scenes etc.
I have created a series of commented examples for Three.js that illustrate features one at a time, starting with very basic features and progressing to more advanced ones (including loading models).
http://stemkoski.github.io/Three.js
Hope this helps!
Working with complex geometry, materials, textures, and animations are some of the hardest things to figure out in THREE.js - that's why we started there with our editor.
We make all of these easy. Export an FBX file (or OBJ/MTL, or Collada) from Blender. Bring it into a project in Verold Studio, then load it into your THREE.js program using our loader. Service is free for use, you pay us if you want enablement services or have a client who wants a maintenance/support agreement.
See the example below, couldn't be easier to bring your scene to THREE.js,
http://jsfiddle.net/rossmckegney/EeMCk/
// 1. Set and then start the animation :)
this.model.setAnimation("mixamo.com");
this.model.playAnimation(true);
//this.model.pauseAnimation();
// 2. Get the threedata for a model
console.log(this.model.threeData);
// 3. Move the model
this.tweenObjectTo(
this.model.threeData, // the model
new THREE.Vector3(1, 0, 0), // go to
new THREE.Quaternion(), // rotation
1, // time, in seconds
false, // smooth start
true); // smooth end
// 4. Clone the model
that = this;
this.model2 = this.model.clone({
success_hierarchy: function(clonedModel) {
that.veroldEngine.getActiveScene().addChildObject(clonedModel);
}
});

Categories