So I am trying to load an image. Originally it is out of S3/Cloudfront but im discovering that its not even working locally.
var imageTexture = new THREE.TextureLoader();
imageTexture.load('/mypicture.jpg');
imageTexture.minFilter = THREE.LinearFilter;
var img = new THREE.MeshBasicMaterial({
map:imageTexture
});
img.map.needsUpdate = true;
This is the error I am getting.
three.js:18053 THREE.WebGLProgram: shader error: 0 gl.VALIDATE_STATUS false gl.getProgramInfoLog invalid shaders
ERROR: 0:269: 'mapTexelToLinear' : no matching overloaded function found
ERROR: 0:269: '=' : dimension mismatch
ERROR: 0:269: 'assign' : cannot convert from 'const mediump float' to 'highp 4-component vector of float'
When I use this
var imageTexture = THREE.ImageUtils.loadTexture('/mypicture');
It works but when I try and load in image on CloudFront I get CORS errors.
Any ideas?
You are sending the loader to the shader, not a texture.
The THREE.TextureLoader() load() function returns a texture.
Try something like this:
var loader = new THREE.TextureLoader();
var texture = loader.load('/mypicture.jpg');
texture.minFilter = THREE.LinearFilter;
var img = new THREE.MeshBasicMaterial({
map:texture
});
img.map.needsUpdate = true;
Related
I am trying to apply a texture to my 3D model with Three JS.
I tried a lot of ways from the Three JS Examples but for any reasons nothing is working.
Here is how I apply the texture to my model:
//LOADING TEXTURE
var textureLoader = new THREE.TextureLoader();
var diffuse = textureLoader.load( "models/Carbon.png" );
diffuse.encoding = THREE.sRGBEncoding;
diffuse.wrapS = THREE.RepeatWrapping;
diffuse.wrapT = THREE.RepeatWrapping;
diffuse.repeat.x = 1;
diffuse.repeat.y = 1;
var normalMap = textureLoader.load( "models/Carbon_Normal.png" );
normalMap.wrapS = THREE.RepeatWrapping;
normalMap.wrapT = THREE.RepeatWrapping;
var material = new THREE.MeshPhysicalMaterial({
roughness: 0.5,
clearcoat: 1.0,
clearcoatRoughness: 0.1,
map: diffuse,
normalMap: normalMap
});
// LOADING MODEL
var loader = new THREE.GLTFLoader();
loader.load("models/stairs.gltf", function(gltf){
model = gltf.scene
model.traverse((newModel) => {
if (newModel.isMesh){
newModel.material = material;
newModel.castShadow = true;
newModel.receiveShadow = true;
}
});
scene.add(model);
});
I appreciate any help!
When loading a texture for a glTF model, you have to set Texture.flipY to false to satisfy the uv convention of glTF.
diffuse.flipY = false;
normalMap.flipY = false;
Besides, you always have to ensure that your model has texture coordinates. You can do this by checking if the geometries of your meshes have an uv attribute. If this attribute is missing, I suggest you generate texture coordinates in a DCC tool like Blender.
three.js R112
Do I have to set up the anisotropic texture filtering for each texture?
I think it would be cool If you can set the anisotropic level for a material or even for the global scene. Any Ideas?
maxA = renderer.getMaxAnisotropy();
var texture1 = THREE.ImageUtils.loadTexture('models/folder/m67/o1.jpg');
texture1.anisotropy = maxA;
var texture2 = THREE.ImageUtils.loadTexture('models/folder/m67/o2.jpg');
texture2.anisotropy = maxA;
var texture3 = THREE.ImageUtils.loadTexture('models/folder/m67/c1.jpg');
texture3.anisotropy = maxA;
var texture4 = THREE.ImageUtils.loadTexture('models/folder/m67/c2.jpg');
texture4.anisotropy = maxA;
var material = {
"logoprint": new THREE.MeshPhongMaterial({
map: texture1
}),
}
you can wrap the load into a function, imageutils just gives you another utility function
function loadTexture( url ){
var tex = THREE.ImageUtils.loadTexture(url);
tex.anisotropy = MAXANISO;
return tex;
}
To clarify what's happening here, and what to do about the ImageUtils depreciation warning:
var tl = new THREE.TextureLoader();
//calling load on it immediately returns a THREE.Texture object
var myTexture = tl.load( 'name.jpg' );
//you can also pass a callback
function onTextureLoaded( tex ){
//tex.image contains data, because textureLoader updated it, before passing it to the callback
handleTexture( tex )...
}
var myTexture = tl.load( 'name.jpg' , onTextureLoaded );
// myTexture is now an instance of THREE.Texture
// myTexture.image contains no data
myTexture.aniso = ...; //texture is configured , but probably waiting for data
The texture object itself holds all these 3d properties like wrapping, mapping type and filtering. The image data itself has nothing to do with this, it stays the same regardless of how you use it.
When you call load on the texture loader, it gives you back a proxy - a reference to an object that can be configured, manipulated, and passed to other objects (like materials) to be used.
A material can render an empty texture. When the image data is loaded, the texture is updated and the very next frame will reflect that.
var tl = new THREE.TextureLoader()
function myCustomLoad( url ){
var newTex = tl.load(url); //make the proxy
newTex.prop = ... ;//config
return newTex; //return configured texture, it will update itself
}
Three.js r72
I'm trying to use the same texture with different offsets and repeats, but after I clone the texture and apply needsUpdate I keep getting an error "Texture marked for update but image is undefined". I check the cloned texture and the image property is undefined. Shouldn't the clone method have referenced the source image from the texture in the textures Object.
var textures = {}
var materials = {}
textures.skin = THREE.ImageUtils.loadTexture('skin.png');
textures.skin.minFilter = THREE.NearestFilter;
textures.skin.magFilter = THREE.NearestFilter;
skin.map_data.forEach(function(item) {
var mats = []
item.maps.forEach(function(item) {
var tex = textures.skin.clone();
tex.needsUpdate = true;
tex.offset.x = ((1 / skin.width) * item.offset_x)
tex.offset.y = ((1 / skin.height) * item.offset_y)
tex.repeat.x = ((1 / skin.width) * item.width);
tex.repeat.y = ((1 / skin.height) * item.height);
var mat = new THREE.MeshBasicMaterial({
map: tex
});
mats.push(mat);
})
materials[item.name] = new THREE.MeshFaceMaterial(mats)
})
Texture loading is asynchronous. You need to put the bulk of your code in the loader callback.
texture = THREE.ImageUtils.loadTexture( 'filename.jpg', undefined, function() {
// the rest of your code here...
var tex = texture.clone();
tex.needsUpdate = true;
}
See how it is done in http://threejs.org/examples/misc_ubiquity_test2.html.
three.js r.72
i created a scene in blender it contains some meshs with out materials then i exported it to collada, i load it to three.js scene with colladaloader everything is ok but when i put some materials to children using the following code :
loader.load( "../models/islands/"+islandselected.getAttribute("data-model")+".dae", function(object){
scene.remove("island");
plane=object.scene;
plane.name=islandselected.innerHTML;
plane.traverse(function(child){
if(child.children[0]){
if(child.children[0].geometry){
console.log(child)
var t = new THREE.ImageUtils.loadTexture( '../models/islands/'+child.name+'.jpg' );
t.wrapS = t.wrapT = THREE.RepeatWrapping;
t.repeat.set( 50, 50 );
var ma= new THREE.MeshBasicMaterial( {map:t} );
child.children[0].material=ma
}
}
});
plane.scale.set(100,100,100);
scene.add(plane);
});
i get errors in console :
[.WebGLRenderingContext]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1
empcreator.jsp:1 WebGL: too many errors, no more errors will be reported to the console for this context.
var model,mat;
var loader = new THREE.ColladaLoader();
var lastTimestamp = 0;
var progress = 0;
loader.load( 'obj/mymodel.dae', function ( collada ) {
model = collada.scene;
model.children[3].children[0].material = new THREE.MeshPhongMaterial({map:THREE.ImageUtils.loadTexture('obj/images/myimage.jpg')});
console.log(model.material);
model.scale.x = model.scale.y = model.scale.z = 0.10;
model.rotation.y = 0.80;
scene.add( model );
}
//you will need to modify a little to work it, i took it from my old project
I would like to add some shading to my 3D model in Three JS.
I'm using this code:
var loader = new THREE.JSONLoader();
loader.load("peer.js", createScene);
function createScene( geometry ) {
geometry.materials[0][0].shading = THREE.FlatShading;
geometry.materials[0][0].morphTargets = true;
var material = new THREE.MeshFaceMaterial();
//var material = new THREE.MeshLambertMaterial({color: 0|(0xffffff*Math.random())})
var cube = new THREE.Mesh( geometry, material );
cube.scale.set(50, 50, 50);
cube.position.z = -50;
m.model.matrixAutoUpdate = false;
m.model.add(cube);
scene.add(m.model);
}
And I'm getting the error message 'Cannot read propery 0 of undefined'.
It has something to do wit this line: geometry.materials[0][0].shading = THREE.FlatShading;
And I think the [0][0] has to be changed in something else, only I don't know what because I don't know what [0][0] is standing for. Does someone know how to fix this problem?