当前位置:网站首页>Getting Started with Three.JS Programmatic Modeling
Getting Started with Three.JS Programmatic Modeling
2022-08-02 11:00:00 【New brains in vats】
在这个教程中,我们将学习如何在 three.js Make your own custom procedure in geometry,Geometry and how to use the program to create attractive low polygon terrain.
This tutorial requires you to have the following basic skills:
- 基本熟悉three.js应用的结构
- 基础编程知识
- 3dBasic knowledge of the geometry(顶点,uvs,法线等)
- 任何具有 webgl Compatible with web browser machine
- 关于如何运行 javascript 代码的知识(Local or use similarjsfiddle的东西)
If you read my previous tutorial,会看到three.js Provides many different kinds of built-in basic geometry,Plus you can easily take3D 模型导入到three.js And why you need to make your own geometry?好吧,One answer is, of course, for fun!If you ask me this is the only answer to you need.
但是,For a more pragmatic readers,If you want to build every time you run the program unique geometry,Then generate your own geometry is beneficial.或者,If the geometry need to adapt to you don't know some of the constraints of beforehand,And make it not suitable for storage.
1、基本几何体
首先,We are from a basicGeometry实例开始.在上一个教程中,We looked at many different types of geometry,例如SphereGeometry和CylinderGeometry,但出于我们的目的,We need a general emptyGeometry对象.
var geometry = new THREE.Geometry();
var material = new THREE.MeshBasicMaterial();
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
现在,We started making the real geometry.Three.js Need at least two things to useGeometry.首先它需要vertices,如你所知,3D Graphics are drawn through the rasterizer triangle.So we need at least a triangle to draw something(Strictly speaking, this is not true,但就我们的目的而言,This is a fair assumption).我们需要 3D 空间中的 3 个点.其次,我们需要告诉 three.js 如何使用 three.js Connect these points together.Face3需要 3Points and connect them together to draw a triangle.现在让我们来看看.首先,Let's define a simple triangle.
geometry.vertices.push(new THREE.Vector3( 1, -1, 0));
geometry.vertices.push(new THREE.Vector3( 0, 1, 0));
geometry.vertices.push(new THREE.Vector3(-1, -1, 0));
geometry.faces.push(new THREE.Face3(0, 1, 2));
Please note that direct access to the vertex arrays and how easy it is to?这是three.js中Geometry类的好处.如果我们使用 BufferGeometry这将更加复杂.但是BufferGeometry速度稍快,Therefore you face tradeoffs.
Before we go on a few more points.Note that we face is how to take three integer.These are our three vertices of each vertex array index.We define them in the transaction order.Refer to the same vertex in multiple surface and there is nothing wrong with.事实上,This allows us to reuse some vertices and save some space.Let's see how it works.
geometry.vertices.push(new THREE.Vector3( 1, -1, 0));
geometry.vertices.push(new THREE.Vector3(-1, 1, 0));
geometry.vertices.push(new THREE.Vector3(-1, -1, 0));
geometry.vertices.push(new THREE.Vector3( 1, 1, 0));
geometry.faces.push(new THREE.Face3(0, 1, 2));
geometry.faces.push(new THREE.Face3(0, 3, 1));
As seen here,We have now defined two triangle,But only to add a vertex.This is not take too much extra space vertex array under the condition of a good way to define the object.
这是在 three.js Create a custom geometry basic method,We can be extended in any way we want it.Can use any method can design add vertex and.But there are some useful considerations.为了充分利用 three.js 的特性,We hope our geometry with normal、Vertex colors and uv.
2、法线
Normal is our most easy to add the properties of the.Once we have defined a vertex array,就可以通过调用computeVertexNormals或computeFlatNormalsTo calculate the normal for us.Let's take a look at both:
geometry.computeVertexNormals();
geometry.normalsNeedUpdate = true;
Vertex normals computation on the triangular interpolation of each vertex normals.Vertex normals are normally used for high-fidelity model appearance.This is because the interpolation to make normal look like on the triangle has changed,This will allow you to calculate more accurate triangle on the surface of the light.
geometry.computeFaceNormals();
geometry.normalsNeedUpdate = true;
For the face normals,The triangle normals remain unchanged.When calculating the lighting,We will be able to clearly see the triangle itself.When making a specific style when choosing to display the triangle itself,Face normals is very good.
Both are very easy to call.为了说明差异,Let's bend a little bit about the us quadrilateral,Make different direction triangle face,如下所示:
geometry.vertices.push(new THREE.Vector3( 1, -1, 0));
geometry.vertices.push(new THREE.Vector3(-1, 1, 0));
geometry.vertices.push(new THREE.Vector3(-1, -1, -1));
geometry.vertices.push(new THREE.Vector3( 1, 1, -1));
geometry.faces.push(new THREE.Face3(0, 1, 2));
geometry.faces.push(new THREE.Face3(0, 3, 1));
还有一件事.Let's change the material for MeshNormalMaterial,So that we can explain the appearance of normal.
现在我们可以看到,When we use vertex normals,它看起来像这样:
Pay attention to the corner of different colors,And in the middle of the two vertices same color?
Now let's look at the face normals with curved quadrilateral:
Each triangle is prominent and has a different color.
3、UV
Is closely related to the normal uv.将 2D 纹理映射到 3D 对象时使用 Uv.不幸的是,A given vertex array,three.js Not calculate for us uv.因此,When building geometry,We need beside the vertex array to build a uv 数组.
three.js 中的 uv 数组是在Geometry的faceVertexUvsAttribute access.faceVertexUvs是一个 uv 数组的数组.They are length is equal to faces 数组的数组,包含三个 uv,Each vertex of a corresponding surface.Now this sounds very complicated,But in fact it is very simple.We defined vertex normals,And then when we define our face,We will do more step.
geometry.faces.push(new THREE.Face3(0, 1, 2));
var uvs1 = [new THREE.Vector2(1, 0), new THREE.Vector2(0, 1), new THREE.Vector2(0, 0)];
geometry.faceVertexUvs[0].push(uvs1); //remember faceVertexUvs is an array of arrays
geometry.faces.push(new THREE.Face3(0, 3, 1));
var uvs2 = [new THREE.Vector2(1, 0), new THREE.Vector2(1, 1), new THREE.Vector2(0, 1)];
geometry.faceVertexUvs[0].push(uvs2);
这样做可以让我们Geometry纹理化,我们可以轻松地在three.js The application of texture,我们只需将Texture添加到mapMaterial properties of.
var material = new THREE.MeshBasicMaterial({map: texture});
We pass from the disk loading a texture to get a(Although we can also create your own,But this is too advanced for this tutorial).
var texture = new THREE.TextureLoader().load('uv_texture.jpg');
我们得到的是:
4、顶点颜色
Geometry of the final common attribute is vertex color.Sometimes we don't want to use the texture or complicated shaders.Sometimes we want to store a vertex color in advance,Then simply read from our material.幸运的是,three.js Provides us with a simple approach to provide early vertex color.
We can be set by two ways of them.The first is a pass a single colorColor我们的Face3定义,Thus providing a single color for the whole triangle.Or we can pass in an array of colors,So that every vertex has its own color,The color is inserted in the surface.
//Face3 takes three vertex indices, a normal and then a color
//We aren't worried about normals right now so we pass null in instead
geometry.faces.push(new THREE.Face3(0, 1, 2, null, new THREE.Color(0.9, 0.7, 0.75)));
geometry.faces.push(new THREE.Face3(0, 3, 1, null, new THREE.Color(0.6, 0.85, 0.7)));
如你所见,Each triangle has its own color.现在,If we want each vertex has its own color,We just need to create an array of objects contain three colors and introduced into rather than a singleColor.
请注意,Can be used for each face different array,I just choose not to do that.
You can see the color on the vertex blending.If you want to smooth transition in simple object color,This will be especially useful.
5、Low-Poly地形
To take advantage of everything we learned in the above,We will write a little foot originally generated an irregular plane,The plane wasPerlinNoise cancellation,To produce some beautiful Low-Poly In the style of the terrain.
The above made no mention of making yourselfGeometryYou only need to deal with is one of the additional benefit of you absolutely need the amount of data.如果GeometryDon't need to be normal,Please don't waste time to calculate them.If you don't want to add texture,请不要在 uvs 上浪费空间.
We will draw a small piece of Low-Poly In the style of the terrain,因此我们不需要 uvs Or vertex color,We will only use each facet normals and transfer to a single color to the material.
6、Make your own plane
当 three.js Provides such a simple way to make our own plane,This seems to be a waste.But our plane will have a significant different.We are not unified spread our point.通常,Plane defined by the point of the grid,就像在 three.js 中一样.But we will put our point spread a little,So when we make flat terrain,It looks will not be locked in the grid.
首先,Let's take a plan.We will start with a regular grid plane,Then with the progress of our move to a different thing.You've learned how to define a single quadrilateral.Now we will extend it to more things.毕竟,Plane is just a pile of quadrilateral arrangement together.让我们从一段代码开始,Then we separate it.
makeTile = function(size, res) {
geometry = new THREE.Geometry();
for (var i = 0; i <= res; i++) {
for (var j = 0; j <= res; j++) {
var z = j * size;
var x = i * size;
var position = new THREE.Vector3(x, 0, z);
var addFace = (i > 0) && (j > 0);
this.makeQuad(geometry, position, addFace, res + 1);
}
}
geometry.computeFaceNormals();
geometry.normalsNeedUpdate = true;
return geometry;
};
该函数makeTile有两个参数size和res.sizeDefine the build the size of each quadrilateral plane,resDefine the width of the plane.很容易.Then we have a nested loop,We count in the 2 d 0 到res.很简单,You can now see the grid to form.
Magic happens within the loop.我们将变量x和zSet to our vertex positions,We will through the quadrilateral position multiplied by the squarei, j的大小来计算.我们将其保存到Vector3.
但是addFace呢.This is actually a clever trick.你看,We are the first line of the vertices to form a quadrilateral.So in our flat edge,We tell our script do not form a triangle,But once we enter the second line,We can start to combine the vertices to form a quadrilateral and triangular.
然后我们调用makeQuadAnd pass it to us in this loop to calculate all the information.简单的!还有一件事,As soon as we complete cycle,我们告诉three.js Computing normals for us.Then we'll return a new geometry object to used in the main part of the program.太棒了!现在让我们看看makeQuad function.
makeQuad = function(geometry, position, addFace, verts) {
geometry.vertices.push(position);
if (addFace) {
var index1 = geometry.vertices.length - 1;
var index2 = index1 - 1;
var index3 = index1 - verts;
var index4 = index1 - verts - 1;
geometry.faces.push(new THREE.Face3(index2, index3, index1));
geometry.faces.push(new THREE.Face3(index2, index4, index3));
}
};
好的,First of all, we add the vertices to the vertex array.这很容易理解.如果addFace是 False,So we stop.否则,We calculate the surrounding the position of the vertices and form two sides,Just as we did above.Just now we must evaluate index position.这就是它的全部!使用这两个函数,You should eventually get the following results:
7、For the plane to add some noise
为了让事情变得有趣,We will add some noise to the vertex to slightly change the height.If you need to review in javascript The use of noise,请查看此教程.
var position = new THREE.Vector3(x, noise.perlin2(x, z)*size, z);
I will be noise multiplied by the size,So that it well with your plane size scaling.如果你使用 MeshNormalMaterialYour plane now looks like this:
其实有点无聊.You can see it is just a mesh vertices are pushed up and down.Let us through decomposition vertex positions more to make it more interesting.我们将通过调用 Math.random 随机偏移xAnd location to do this.
var z = j * size + (Math.random() - 0.5) * size;
var x = i * size + (Math.random() - 0.5) * size;
现在,If the height of reset to 0,You can see the change of the triangle degree.
If you add height again.
This is to create their own little terrain had to do everything!Try to use different Settings,Especially when trying to make the quadrilateral is very small and the resolution.xThen try to through multiplied by the number of different size slightly mixed noisezTo zoom noise.You should be able to create all of the different types of Low-Poly 地形.对于示例,这里是使用MeshPhongMaterial.
8、结束语
I know there are a lot of things on it.Application geometry is a very deep subject.But now you have started inthree.js To further explore its tools!I hope you have learned to:
- 如何使用 three.js 的GeometryClass to make your own custom geometry,包括:
- 如何定义自己的uvs,
- How to define your own vertex color,
- 以及如何使用 three.js 计算法线
- How to automatically create jitter plane
边栏推荐
猜你喜欢
随机推荐
10份重磅报告 — 展望中国数字经济未来
使用较广泛的安全测试工具有哪些?
[Science of Terminology] For those difficult words about the integrated workbench, read this article to understand in seconds!
LayaBox---TypeScript---Mixins
字节跳动软件测试岗,收到offer后我却拒绝了~给面试的人一些忠告....
阿里CTO程立:阿里巴巴开源的历程、理念和实践
mysql清除binlog日志文件
ssm网页访问数据库数据报错
只问耕耘,不问收获,其实收获却在耕耘中
Oracle根据时间查询
周杰伦新歌发布,爬取《Mojito》MV弹幕,看看粉丝们都说的些啥!
学习笔记-支付宝支付
org.apache.ibatis.binding.BindingException Invalidbound statement (not found)的解决方案和造成原因分析(超详细)
LayaBox---TypeScript---三斜线指令
LayaBox---TypeScript---声明合并
How to technically ensure the quality of LED display?
从测试入门到测试架构师,这10年,他是这样让自己成才的
The 38-year-old daughter is not in love and has no stable job, the old mother is crying
行为型模式-策略模式
Alibaba CTO Cheng Li: Alibaba Open Source History, Concept and Practice