使用fabric js canvas作为threejs 3d模型纹理
Posted
技术标签:
【中文标题】使用fabric js canvas作为threejs 3d模型纹理【英文标题】:use fabric js canvas as a threejs 3d model texture 【发布时间】:2021-09-16 15:31:55 【问题描述】:刚开始学习threejs,因此决定结合fabric js构建一个T恤配置器。我的目标是用户可以将图片上传到画布(cnvs),该画布将映射到 T 恤的 gltf 模型问题是纹理不显示。 代码:
var canvas2 = new fabric.Canvas('cnvs',
backgroundColor: 'red'
);
fabric.Image.fromURL('eo.png', function(myImg)
//i create an extra var for to change some image properties
var img1 = myImg.set( left: 0, top: 0 ,width:150,height:150);
canvas2.add(img1);
canvas2.renderAll();
);
var canvasTexture = new THREE.CanvasTexture(canvas2);
canvasTexture.wrapS = THREE.RepeatWrapping;
canvasTexture.wrapT = THREE.RepeatWrapping;
const gltfLoader2 = new GLTFLoader();
gltfLoader2.load('tshirt2.gltf', (gltf2) =>
model = gltf2.scene;
model.traverse(child =>
console.log(child.material);
if (child.material && child.material.name === 'Pattern2D_13095')
// Pattern2D_13095
child.material.map = new TextureLoader().load( new THREE.MeshStandardMaterial(
map: canvasTexture,
));
);
canvas2.on("after:render", function()
model.material.map.needsUpdate = true;
);
canvas2.on('mouse:down',function(event)
if(canvas2.getActiveObject())
alert(event.target);
)
scene.add(model);
model.rotation.x = 1.5;
model.position.y=310;
model.position.x=-300;
model.position.z=-100;
model.scale.set(1000,1000,1000);
);
);
function resizeRendererToDisplaySize(renderer)
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize)
renderer.setSize(width, height, false);
return needResize;
function render()
if (resizeRendererToDisplaySize(renderer))
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
renderer.render(scene, camera);
requestAnimationFrame(render);
function animate()
requestAnimationFrame(animate);
cloudParticles.forEach(p =>
p.rotation.z -= 0.001;
);
root.rotation.z -= 0.01;
renderer.render(scene, camera);
model.material.needsUpdate = true;
animate();
灯光/相机:
let cloudParticles = [];
let root;
let model;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1,
1000 );
camera.position.z = 2;
camera.rotation.x = 1.16;
camera.rotation.y = -0.12;
camera.rotation.z = 0;
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer(canvas);
scene.fog = new THREE.FogExp2(0x11111f, 0.002);
renderer.setClearColor(scene.fog.color);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild( renderer.domElement );
let directionalLight = new THREE.DirectionalLight(0xff8c19);
directionalLight.position.set(0,0,1);
scene.add(directionalLight);
let orangeLight = new THREE.PointLight(0xcc6600,50,450,1.7);
orangeLight.position.set(200,300,100);
scene.add(orangeLight);
let redLight = new THREE.PointLight(0xd8547e,50,450,1.7);
redLight.position.set(100,300,100);
scene.add(redLight);
let blueLight = new THREE.PointLight(0x3677ac,50,450,1.7);
blueLight.position.set(300,300,200);
scene.add(blueLight);
let directionalLight2 = new THREE.DirectionalLight(0xffffff);
directionalLight2.position.set(-110,-110,-120);
scene.add(directionalLight2);
html:
<div class="cnvscon">
<canvas id="cnvs" ></canvas></div>
<canvas id="c"></canvas>
这是结果的 img (网格是黑色的): result gltfviewer
【问题讨论】:
【参考方案1】:child.material.map = new TextureLoader().load( new THREE.MeshStandardMaterial( 地图:canvasTexture ));
恐怕这段代码不正确。将canvasTexture
分配给相应的map
属性就足够了。含义:
child.material.map = canvasTexture;
【讨论】:
感谢您的回复,我刚刚更换了它,但仍然无法正常工作,这是错误所在:console.log(model.material); //无法读取未定义的属性'material' canvas2.on("after:render", function() model.material.map.needsUpdate = true; //无法读取未定义的属性'map' ); 在遍历 glTF 资源时,必须检查当前对象是否真的有材质。THREE.Group
或 THREE.Bone
的实例没有这样的属性。
我想我正在使用这行代码:if (child.material && child.material.name === 'Pattern2D_13095')
在搅拌机中,我需要更改纹理的集合的名称是“Pattern2D_13095”,如果我控制台日志 child.material 我做获取材料清单
所以我设法通过改变模型来解决这个问题,纹理确实发生了变化,但颜色是黑色的,并且没有光线折射,尝试改变金属度,但仍然没有改变这是我得到的错误: Failed to execute 'texImage2D' on 'WebGL2RenderingContext': Overload resolution failed.
以上是关于使用fabric js canvas作为threejs 3d模型纹理的主要内容,如果未能解决你的问题,请参考以下文章
在fabric.js中将Canvas下载为PNG,给出网络错误
Html5 Canvas + fabric.js 的独立堆肥
Three.js/WebGL 和 2D Canvas -- 将 getImageData() 数组传递给 Three.DataTexture()