Before inadvertently saw Ovilia with Threejs did a low POLY, that is, the image of the triangular effect of the plane, feel very stunning, and then took a little time to try.
I did not use the Threejs, so I directly use the canvas 2d drawing API to do, because it feels like this effect is not threejs.
Directly on the demo first: http://whxaxes.github.io/canvas-test/src/Funny-demo/lowpoly/index.html (can also be seen on the mobile side, but because the computational capacity is relatively large, Mobile devices can take more time to calculate than PCs. )
To do this, it is necessary to triangulate the images and to detect the edges of the images. These two, the first used Delaunay triangulation algorithm, the second use of the Sobel edge detection algorithm. It sounds like a big steal. Two algorithms have a corresponding open source component that can be used directly:the Ironwallaby Delaunay component and the Sobel component of the Miguel Mota.
These two algorithms Sobel fortunately a bit, Delaunay is a bit complicated, can be studied later. But for now, these components can be used only to make an effect.
The two most important components are there, and the rest is simple:
First draw the picture onto the canvas:
Canvas.width = (Img.width > 800)? img.height * canvas.width/img.width; 0, 0, canvas.width, canvas.height);
Then get to the canvas's imgdata, and then return the new Imgdata by Sobel calculation
var imgdata = ctx.getimagedata (0, 0, Canvas.width, canvas.height); var newimgdata = Sobel (Imgdata);
If we put the newimgdata on the canvas, we will find that the color image becomes such a grayscale image:
After the picture is processed, the imgdata is traversed, and the coordinate points of the color value greater than 40 (that is, the grayscale is more than RGB (40,40,40)) are recorded. Because we want to randomly select some of the coordinate points at the edge, so the collected coordinates are scrambled, and then added some random coordinates and four corner coordinate values. So that we can get to the coordinate point we need.
varCollectors = [];varindex;//collect edge points with color values greater than 40 for(varx=0;x){ for(vary=0;y) {Index= ~ ~ (y*imgdata.width + x); if(Newimgdata.data[index] > 40) {Collectors.push ([x, y]); } }}//random arrangement of collected pointsCollectors.sort (function(){returnMath.random ()-math.random ()});//add some random points for(vari=0;i<500;i++) {Particles.push ([Math.random () *canvas.width, Math.random () *canvas.height]);}//Add edge pointsparticles = Particles.concat (Collectors.slice (0,~~ (COLLECTORS.LENGTH/50)));//add four vertex coordinatesparticles = Particles.concat ([[0,0], [0,canvas.height], [canvas.width,0], [canvas.width,canvas.height]]);
Once the coordinate point is obtained, it can be computed by the Delaunay component, get the array of triangular coordinates in the order of the sequence, and connect the points in these arrays so that the effect can occur:
Of course, the effect we want is not the line, but the color of all the triangles to fill, that is, to get the three coordinates of the triangle, and then calculate the coordinates of the center point, and then according to the center point coordinates in the imgdata to obtain the corresponding RGB color values, and then fill the Triangle area can be:
//triangular coordinates obtained using Delaunay triangulationvarTriangles =delaunay.triangulate (particles);varX1,x2,x3,y1,y2,y3,cx,cy; for(varI=0;i < Triangles.length; I+=3) {x1= Particles[triangles[i]][0]; X2= Particles[triangles[i+1]][0]; X3= Particles[triangles[i+2]][0]; Y1= Particles[triangles[i]][1]; Y2= Particles[triangles[i+1]][1]; Y3= Particles[triangles[i+2]][1];//Get Triangle Center Point coordinatesCX = ~ ~ ((x1 + x2 + x3)/3); Cy= ~ ~ ((y1 + y2 + y3)/3);//gets the color value of the center point coordinateIndex = (cy*imgdata.width + cx); varColor_r =Imgdata.data[index]; varColor_g = imgdata.data[index+1]; varColor_b = imgdata.data[index+2];//Draw TrianglesCtx.save (); Ctx.beginpath (); Ctx.moveto (x1, y1); Ctx.lineto (x2, y2); Ctx.lineto (x3, y3); Ctx.closepath (); Ctx.fillstyle= "Rgba (" +color_r+ "," +color_g+ "," +color_b+ ", 1)"; Ctx.fill (); Ctx.restore ();}
It is important to note that the obtained center point coordinates must be rounded to get the correct color parameters, if you want to not take the whole, but in the acquisition of RGB index and then take the whole, get the color value is wrong. Because that pixel is not the center pixel we want to get.
The color is also obtained after the simple connection, then the filling operation, the final effect is:
Although there is no designer hand-painted look good, but also a lot of convenience, do to play or very interesting.
Source address, interested can a look at Kazakhstan:
Https://github.com/whxaxes/canvas-test/tree/gh-pages/src/Funny-demo/lowpoly
Using canvas to achieve a picture triangulation (low POLY) effect