這篇郭先生來說說BufferGeometry,型別化陣列和粒子系統的使用,並且讓圖片有馬賽克效果(同理可以讓不清晰的圖片清晰化),如圖所示。線上案例點選部落格原文
1. 解析圖片
解析圖片和上一篇一樣
initCanvas() { canvas = document.createElement('canvas'); content = canvas.getContext('2d'); canvas.width = 1600; canvas.height = 1200; img = new Image(); img.crossOrigin = '*'; img.src = "/static/images/base/girl.jpg"; img.onload = () => { content.drawImage(img, 0, 0, canvas.width, canvas.height); imgDate = content.getImageData(0, 0, canvas.width, canvas.height); this.createPotCloud(); //建立點雲 }; }
2. 操作畫素點
createPotCloud() { if (points) { scene.remove(points) } let cw = Math.floor(canvas.width / size); let ch = Math.floor(canvas.height / size); particles = cw * ch; geometry = new THREE.BufferGeometry(); positions = new Float32Array(Math.floor(particles * 3)); positions_af = new Float32Array(Math.floor(particles * 3)); var colors = new Float32Array(Math.floor(particles * 3)); for (var i = 0; i < positions.length; i += 1) { positions[3 * i] = - canvas.width / 2 + (i % cw) * size; positions[3 * i + 1] = canvas.height / 2 + Math.floor((-1 - i) / cw) * size; positions[3 * i + 2] = 0; let selectPos = size * (i % cw) + Math.floor(i / cw) * cw * size * size; colors[3 * i] = imgDate.data[4 * selectPos] / 255.0; colors[3 * i + 1] = imgDate.data[4 * selectPos + 1] / 255.0; colors[3 * i + 2] = imgDate.data[4 * selectPos + 2] / 255.0; } geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3)) geometry.dynamic = true; geometry.attributes.position.needsUpdate = true; var material = new THREE.PointsMaterial({ size: size, vertexColors: THREE.VertexColors }) points = new THREE.Points(geometry, material); points.name = 'points'; scene.add(points); loaded = true; },
可以不用糾結程式碼,核心思想其實我們只需要每隔一定的顏色點取出一個顏色點,然後將這個顏色賦予到geometry的color屬性上,就可以了,也可以每隔兩行、兩列取一個點,但是圖片上面的點是一維的,所以需要一些數學方法,
如圖所示,原理很簡單哦。將不清晰的圖片清晰化,就是需要插入更多的畫素點,插入的畫素點,需要根據已存在的畫素點的顏色進行插值,比如原圖的畫素點1為0xffffff,畫素點2的顏色為0xdddddd,則插在兩個畫素點之間畫素點的顏色為0xeeeeee,以此類推。
轉載請註明地址:郭先生的部落格