如何在波前对象中加载 Canvas 纹理 (three.js)
how to load Canvas texture in wavefront obj (three.js)
感谢您的关注。我想使用 three.js 来显示从 Blender 导出的 obj 文件和从 canvas 映射纹理。我尝试 post obj 中的图像,它成功了。但是当我将 canvas 纹理放在 obj 上时,模型变黑了。我也试过通过toDataURL把canvas转成图片再映射,还是不行work.Any有帮助,不胜感激。
function convertCanvasToImage(ele) {
var image = new Image();
image.src = ele.toDataURL("image/png");
return image;
}
function changeCanvas() {
canvas = document.getElementById('canvas_id'),
ctx = canvas.getContext('2d');
ctx.font = '20pt Arial';
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'white';
ctx.fillRect(10, 10, canvas.width - 20, canvas.height - 20);
ctx.fillStyle = 'black';
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(new Date().getTime(), canvas.width / 2, canvas.height / 2);
image_t = convertCanvasToImage(canvas);
return image_t;
}
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 250;
// scene
scene = new THREE.Scene();
scene.background = new THREE.Color( 'red' );
var ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
scene.add(ambientLight);
var pointLight = new THREE.PointLight(0xffffff, 0.8);
camera.add(pointLight);
scene.add(camera);
// manager
function loadModel() {
object.traverse(function (child) {
if (child.isMesh) child.material.map = texture;
});
object.position.y = -95;
scene.add(object);
}
var manager = new THREE.LoadingManager(loadModel);
manager.onProgress = function (item, loaded, total) {
console.log(item, loaded, total);
};
// texture
// texture = new THREE.Texture(canvas); //it's my initial try,but it didn't work
var textureLoader = new THREE.TextureLoader();
texture = textureLoader.load("three.js-master/examples/models/obj/clothes/426_con.png");//this works!!!
// img = changeCanvas()
texture = textureLoader.load(image_t);//but this doesn't work!!!
// model
function onProgress(xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log('model ' + Math.round(percentComplete, 2) + '% downloaded');
}
}
function onError() {
}
var loader = new THREE.OBJLoader(manager);
loader.load('three.js-master/examples/models/obj/clothes/426_con.obj', function (obj) {
object = obj;
}, onProgress, onError);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
function animate() {
requestAnimationFrame(animate);
camera.lookAt(scene.position);
changeCanvas();
texture.needsUpdate = true;
renderer.render(scene, camera);
}
我想知道如果three.js有直接在obj文件上纹理canvas的方法,需要任何翻译吗?
texture = new THREE.CanvasTexture(yourCanvas) ?
应该说我对JS不精通,真是粗心大意。感谢gman和manthrax,你们帮了大忙,你们的回答让我静下心来分析问题。虽然我能找到的所有 Three.js Canvas 纹理示例都是用于 gemotry 的纹理贴图,但也可以用于 obj。原来canvas生成的纹理和图片的纹理没有区别
<script>
var container;
var camera, scene, renderer,texture,canvas;
var object;
function changeCanvas() {
canvas = document.getElementById('canvas_id');
ctx = canvas.getContext('2d');
img = new Image();
img.onload = function(){ctx.drawImage(img, 0, 0)};
img.src = "../assets/UV.png";//img address
}
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 250;
// scene
scene = new THREE.Scene();
scene.background = new THREE.Color( 'black' );
var ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
scene.add(ambientLight);
var pointLight = new THREE.PointLight(0xffffff, 0.8);
camera.add(pointLight);
scene.add(camera);
// manager
function loadModel() {
object.traverse(function (child) {
if (child.isMesh) child.material.map = texture;
});
object.position.y = -95;
scene.add(object);
}
var manager = new THREE.LoadingManager(loadModel);
manager.onProgress = function (item, loaded, total) {
console.log(item, loaded, total);
};
//texture
changeCanvas();
texture = new THREE.CanvasTexture(canvas);
// model
function onProgress(xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log('model ' + Math.round(percentComplete, 2) + '% downloaded');
}
}
function onError() {}
var loader = new THREE.OBJLoader(manager);
loader.load('../assets/426.obj', function (obj) {
object = obj;
}, onProgress, onError);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls( camera, renderer.domElement );
}
function animate() {
// changeCanvas();
texture.needsUpdate = true;
camera.lookAt(scene.position);
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
init();
animate();
</script>
感谢您的关注。我想使用 three.js 来显示从 Blender 导出的 obj 文件和从 canvas 映射纹理。我尝试 post obj 中的图像,它成功了。但是当我将 canvas 纹理放在 obj 上时,模型变黑了。我也试过通过toDataURL把canvas转成图片再映射,还是不行work.Any有帮助,不胜感激。
function convertCanvasToImage(ele) {
var image = new Image();
image.src = ele.toDataURL("image/png");
return image;
}
function changeCanvas() {
canvas = document.getElementById('canvas_id'),
ctx = canvas.getContext('2d');
ctx.font = '20pt Arial';
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'white';
ctx.fillRect(10, 10, canvas.width - 20, canvas.height - 20);
ctx.fillStyle = 'black';
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(new Date().getTime(), canvas.width / 2, canvas.height / 2);
image_t = convertCanvasToImage(canvas);
return image_t;
}
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 250;
// scene
scene = new THREE.Scene();
scene.background = new THREE.Color( 'red' );
var ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
scene.add(ambientLight);
var pointLight = new THREE.PointLight(0xffffff, 0.8);
camera.add(pointLight);
scene.add(camera);
// manager
function loadModel() {
object.traverse(function (child) {
if (child.isMesh) child.material.map = texture;
});
object.position.y = -95;
scene.add(object);
}
var manager = new THREE.LoadingManager(loadModel);
manager.onProgress = function (item, loaded, total) {
console.log(item, loaded, total);
};
// texture
// texture = new THREE.Texture(canvas); //it's my initial try,but it didn't work
var textureLoader = new THREE.TextureLoader();
texture = textureLoader.load("three.js-master/examples/models/obj/clothes/426_con.png");//this works!!!
// img = changeCanvas()
texture = textureLoader.load(image_t);//but this doesn't work!!!
// model
function onProgress(xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log('model ' + Math.round(percentComplete, 2) + '% downloaded');
}
}
function onError() {
}
var loader = new THREE.OBJLoader(manager);
loader.load('three.js-master/examples/models/obj/clothes/426_con.obj', function (obj) {
object = obj;
}, onProgress, onError);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
function animate() {
requestAnimationFrame(animate);
camera.lookAt(scene.position);
changeCanvas();
texture.needsUpdate = true;
renderer.render(scene, camera);
}
我想知道如果three.js有直接在obj文件上纹理canvas的方法,需要任何翻译吗?
texture = new THREE.CanvasTexture(yourCanvas) ?
应该说我对JS不精通,真是粗心大意。感谢gman和manthrax,你们帮了大忙,你们的回答让我静下心来分析问题。虽然我能找到的所有 Three.js Canvas 纹理示例都是用于 gemotry 的纹理贴图,但也可以用于 obj。原来canvas生成的纹理和图片的纹理没有区别
<script>
var container;
var camera, scene, renderer,texture,canvas;
var object;
function changeCanvas() {
canvas = document.getElementById('canvas_id');
ctx = canvas.getContext('2d');
img = new Image();
img.onload = function(){ctx.drawImage(img, 0, 0)};
img.src = "../assets/UV.png";//img address
}
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 250;
// scene
scene = new THREE.Scene();
scene.background = new THREE.Color( 'black' );
var ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
scene.add(ambientLight);
var pointLight = new THREE.PointLight(0xffffff, 0.8);
camera.add(pointLight);
scene.add(camera);
// manager
function loadModel() {
object.traverse(function (child) {
if (child.isMesh) child.material.map = texture;
});
object.position.y = -95;
scene.add(object);
}
var manager = new THREE.LoadingManager(loadModel);
manager.onProgress = function (item, loaded, total) {
console.log(item, loaded, total);
};
//texture
changeCanvas();
texture = new THREE.CanvasTexture(canvas);
// model
function onProgress(xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log('model ' + Math.round(percentComplete, 2) + '% downloaded');
}
}
function onError() {}
var loader = new THREE.OBJLoader(manager);
loader.load('../assets/426.obj', function (obj) {
object = obj;
}, onProgress, onError);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls( camera, renderer.domElement );
}
function animate() {
// changeCanvas();
texture.needsUpdate = true;
camera.lookAt(scene.position);
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
init();
animate();
</script>