三.js中如何使用多张图片组成一个图形

Posted

技术标签:

【中文标题】三.js中如何使用多张图片组成一个图形【英文标题】:How to use a number of pictures to form a graphic in three.js 【发布时间】:2017-04-29 07:48:32 【问题描述】:

我想用 three.js 生成一个由一些图片组成的形状(可能是一些单词):

我想我要做的是得到一些形成形状的点,然后把图片放到这些点上。我已经搜索了一些信息,但我仍然不知道如何获得这些点,因为形状可能不规则。有什么解决办法吗?

【问题讨论】:

【参考方案1】:

在我看来,你有两种方法可以在这里进行:

    你可以使用像Blender这样的建模软件先生成形状和图片,然后导出JSON(参考 thisblender中的threejs json导出器),然后使用JSON加载器加载那个 JSON。 另一种方法是使用threejs 提供的框、圆等(参考docs)创建所需形状的简单几何图形,然后向其添加纹理,如here 所示。

希望这些解决方案之一是您正在寻找的。​​p>

【讨论】:

第一种方式,图片要动态添加,不能用json文件初始化。第二种方式,我的形状是不规则的,无法使用提供的threejs创建。 所以你希望形状是根据用户想要的,动态的对吗?看看这个例子 (stemkoski.github.io/Three.js/Voxel-Painter.html) 你在寻找类似的东西吗?【参考方案2】:

我会使用画布绘制每张照片的 3d 位置。

我在这里用文本创建了一个小提琴:

https://jsfiddle.net/2qu6m4h3/

还有一个形状随机的:

https://jsfiddle.net/d2th9ekb/

它创建了一个画布元素来绘制文本。它询问画布的像素位置。然后将这些位置发送到将立方体放置在 3d 中的函数。您可以放置​​显示每张照片的精灵对象,而不是放置立方体。使用 scale 属性为自己在位置之间留出更多空间。

代码如下:

/*
Start Setup text canvas and tools
*/
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.canvas.width  = 400;
ctx.canvas.height = 200;
function createTextSourceCanvas(text,src) 
    src.font = '50pt Times';
    src.fillStyle = '#00ff00';
    src.fillRect(0, 0, canvas.width, canvas.height);
    src.fillStyle = '#FFFFFF';
    src.textAlign = "center";
    src.textBaseline = "middle";
    src.fillText(text, canvas.width /2, canvas.height /2);

function examineText(src, fi)
    var positiveResults = [];
    var width = src.canvas.width;
  var height = src.canvas.height;
  var imgData = src.getImageData(0, 0,width, height);
    for(var x = 0; x < width; x+=fi)
   for(var y = 0; y < height; y+=fi  )
    var pixel = getPixelXY(imgData, x, y)
    if(pixel[0] == 0 && pixel[1] == 255 && pixel[2] == 0)
        continue;
    
    positiveResults.push([x,y]);
   
  
  return positiveResults;

function getPixel(imgData, index) 
  var i = index*4, d = imgData.data;
  return [d[i],d[i+1],d[i+2],d[i+3]]

function getPixelXY(imgData, x, y) 
  return getPixel(imgData, y*imgData.width+x);

/*
End Setup text canvas and tools
*/

/*
Start Setup Threejs canvas and tools
*/
var scene;
var renderer;
var camera;
var cube;
var controls;
function init3d()
    renderer = new THREE.WebGLRenderer( antialias:true );
  var width = window.innerWidth;
    var height = window.innerHeight;
    renderer.setSize (width, height);
    document.body.appendChild (renderer.domElement);
  scene = new THREE.Scene()
  camera = new THREE.PerspectiveCamera (45, width/height, 1, 10000);
    camera.position.y = 160;
    camera.position.z = 400;
    camera.lookAt (new THREE.Vector3(0,0,0));
  controls = new THREE.OrbitControls (camera, renderer.domElement);
    var gridXZ = new THREE.GridHelper(100, 10);
    scene.add(gridXZ);
    var pointLight = new THREE.PointLight (0xffffff);
    pointLight.position.set (0,300,200);
    scene.add (pointLight);
    window.addEventListener ('resize', onWindowResize, false);

function onWindowResize ()
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize (window.innerWidth, window.innerHeight);

function animate()
    controls.update();
  requestAnimationFrame ( animate );  
    renderer.render (scene, camera);

/*
End Setup Threejs canvas and tools
*/

/*
Start create 3d from text examination
*/
function create3dProjectionText(scene, positions, wExtent, hExtent, scale)
    if(scale == undefined)
        scale = 1;
  
  var group = new THREE.Object3D();

  var cubeGeometry = new THREE.BoxGeometry (2,2,2);
    var cubeMaterial = new THREE.MeshLambertMaterial (color: 0xFFFFFF);

  for(var i in positions)
        cube = new THREE.Mesh (cubeGeometry, cubeMaterial);
      cube.position.set (positions[i][0]*scale - (wExtent*scale/2), positions[i][1]*scale -(hExtent*scale/2), 0);
      group.add (cube);
  
  group.rotateX( -Math.PI  );
  scene.add(group);

/*
End create 3d from text examination
*/
//initialize the 3d space
init3d();
//initialize the text canvas
createTextSourceCanvas("Hello World", ctx);
//
create3dProjectionText(scene, examineText(ctx ,4), ctx.canvas.width, ctx.canvas.height, 1.5);
animate();

【讨论】:

以上是关于三.js中如何使用多张图片组成一个图形的主要内容,如果未能解决你的问题,请参考以下文章

php中上传多张图片,如何解决?

如何在前端用js进行多图片上传

如何使用 Flutter 在 iOS 和 Android 上共享多张图片?

如何在PPT中一个页面上实现多张图片轮播

如何使用 HTTP 将多张图片上传到 Flutter 中的 Rest API?

如何在 Flutter 中使用 Dio 和 multi_image_picker 插件上传多张图片