1. 概述

上一篇文章《Unity3D学习笔记1——绘制一个三角形》中介绍了Unity3D的HelloWorld——绘制一个简单的三角形。不过这个三角形太简单了,连材质都没有。那么这里就将三角形扩展为一个矩形的面,并且为这个面贴上纹理。

2. 详论

2.1. 网格(Mesh)

前面说到网格是渲染物体的骨架,因此还是先要把渲染物体的架子搭好。改进一下上一篇文章中的创建Mesh的代码:

Mesh mesh = new Mesh();
mesh.name = name; Vector3[] vertices = new Vector3[4]
{
new Vector3(-5, -5, 0),
new Vector3(-5, 5, 0),
new Vector3(5, -5, 0),
new Vector3(5, 5, 0),
};
mesh.vertices = vertices; Vector2[] uv = new Vector2[4]
{
new Vector2(0, 0),
new Vector2(0, 1),
new Vector2(1, 0),
new Vector2(1, 1),
};
mesh.uv = uv; Vector3[] normals = new Vector3[4]
{
new Vector3(0, 0, -1),
new Vector3(0, 0, -1),
new Vector3(0, 0, -1),
new Vector3(0, 0, -1),
};
mesh.normals = normals;
//mesh.RecalculateNormals(); int[] triangles = new int[6] { 0, 1, 2, 1, 3, 2 };
mesh.triangles = triangles; GameObject newGameObject = new GameObject(name);
MeshFilter mf = newGameObject.AddComponent<MeshFilter>();
mf.sharedMesh = mesh;

2.1.1. 顶点

因为我们要创建一个矩形的面,所以需要创建四个顶点。仍然是像之前创建三角面的顶点一样,赋予顶点的空间位置属性xyz坐标。同时,我们还给Mesh赋予了4个uv坐标,4个法向量normal。uv坐标是用来计算纹理坐标的,也就是当物体贴上纹理之后的纹理坐标位置;法向量是用来参与光照计算的,如果缺少法向量,很多材质的效果不正确。可以通过mesh.RecalculateNormals()让Unity3D自己计算法向量。

位置(position/vertice)、纹理坐标(uv/texCoord)、法向量(normal)是经常用到了三个顶点属性,但是顶点属性也不仅仅只有三个,甚至可以根据需要自定义。

2.1.2. 顶点索引

一个矩形面确定了四个顶点,但是需要划分成两个三角形,每个三角形引用3个顶点索引,也就是6个顶点索引。当然我们也可以使用6个顶点,按照自然顺序来确定顶点索引。但是这样一来,就浪费了空间存储。这也是使用顶点索引的好处,可以节省空间,毕竟Mesh中的很多顶点是共用的。

2.2. 材质(Material)

接下来我们在Unity3D编辑器中创建一个材质,并且在C#脚本中将这个材质给到我们创建的面上。

2.2.1. 创建材质

材质和纹理(图片)在Unity3D中被认为是一种资源,要加载他们需要特定的办法。一种比较简单的办法是使用Resources.Load。

在Assets目录下创建一个名为Resources的文件夹,只有使用这个目录下的资源,使用Resources.Load才能找到。在Resources文件夹下新建一个材质,并把想使用的纹理图片文件移到这个文件夹下:

点击新建的材质,在Inspector视图中,将纹理图片挂载到这个材质上:

Unity3D新建的材质默认为标准,是一种PBR材质,由多种贴图混合而成。我们这里暂时只设置Albedo贴图,也就是基本颜色贴图。实际使用时,右边的颜色拾取也能影响到贴图效果,在有贴图时,可以将其拾取成白色。

2.2.2. 使用材质

在编辑器中把材质创建好之后,在脚本中就可以直接使用创建好的材质了:

MeshRenderer meshRenderer = newGameObject.AddComponent<MeshRenderer>();
Material material = Resources.Load<Material>("MaterialDemo");
meshRenderer.material = material;

2.3. 光照

点击Play,会发现虽然显示了一个带纹理的面,但是面的颜色显得很暗:

这是因为光照的位置不对,材质缺少对光照的影响。那么我们调整默认光照Directional Light的Transform,将其调整到和摄像机的位置一致:

这个时候的光照正好对准了面的正中间:

最终Game视图中的面也按照正常亮度显示了:

3. 代码

全部的C#脚本代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class Main : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
GameObject main = GameObject.Find("/Root");
if (main == null)
{
return;
} GameObject triangleGameObject = GreateQuad();
triangleGameObject.transform.parent = main.transform;
} GameObject GreateQuad()
{
string name = "quad"; Mesh mesh = new Mesh();
mesh.name = name; Vector3[] vertices = new Vector3[4]
{
new Vector3(-5, -5, 0),
new Vector3(-5, 5, 0),
new Vector3(5, -5, 0),
new Vector3(5, 5, 0),
};
mesh.vertices = vertices; Vector2[] uv = new Vector2[4]
{
new Vector2(0, 0),
new Vector2(0, 1),
new Vector2(1, 0),
new Vector2(1, 1),
};
mesh.uv = uv; Vector3[] normals = new Vector3[4]
{
new Vector3(0, 0, -1),
new Vector3(0, 0, -1),
new Vector3(0, 0, -1),
new Vector3(0, 0, -1),
};
mesh.normals = normals;
//mesh.RecalculateNormals(); int[] triangles = new int[6] { 0, 1, 2, 1, 3, 2 };
mesh.triangles = triangles; GameObject newGameObject = new GameObject(name);
MeshFilter mf = newGameObject.AddComponent<MeshFilter>();
mf.sharedMesh = mesh; MeshRenderer meshRenderer = newGameObject.AddComponent<MeshRenderer>();
Material material = Resources.Load<Material>("MaterialDemo");
meshRenderer.material = material; return newGameObject;
} // Update is called once per frame
void Update()
{ }
}

Unity3D学习笔记2——绘制一个带纹理的面的更多相关文章

  1. Unity3D学习笔记1——绘制一个三角形

    目录 1. 绪论 2. 概述 3. 详论 3.1. 准备 3.2. 实现 3.3. 解析 3.3.1. 场景树对象 3.3.2. 绘制方法 4. 结果 1. 绪论 最近想学习一下Unity3d,无奈发 ...

  2. Unity3D学习笔记3——Unity Shader的初步使用

    目录 1. 概述 2. 详论 2.1. 创建材质 2.2. 着色器 2.2.1. 名称 2.2.2. 属性 2.2.3. SubShader 2.2.3.1. 标签(Tags) 2.2.3.2. 渲染 ...

  3. Unity3D学习笔记4——创建Mesh高级接口

    目录 1. 概述 2. 详论 3. 其他 4. 参考 1. 概述 在文章Unity3D学习笔记2--绘制一个带纹理的面中使用代码的方式创建了一个Mesh,不过这套接口在Unity中被称为简单接口.与其 ...

  4. Unity3D学习笔记12——渲染纹理

    目录 1. 概述 2. 详论 3. 问题 1. 概述 在文章<Unity3D学习笔记11--后处理>中论述了后处理是帧缓存(Framebuffer)技术实现之一:而另外一个帧缓存技术实现就 ...

  5. Unity3D学习笔记8——GPU实例化(3)

    目录 1. 概述 2. 详论 2.1. 自动实例化 2.2. MaterialPropertyBlock 3. 参考 1. 概述 在前两篇文章<Unity3D学习笔记6--GPU实例化(1)&g ...

  6. WebGL three.js学习笔记 6种类型的纹理介绍及应用

    WebGL three.js学习笔记 6种类型的纹理介绍及应用 本文所使用到的demo演示: 高光贴图Demo演示 反光效果Demo演示(因为是加载的模型,所以速度会慢) (一)普通纹理 计算机图形学 ...

  7. Unity3D学习笔记6——GPU实例化(1)

    目录 1. 概述 2. 详论 3. 参考 1. 概述 在之前的文章中说到,一种材质对应一次绘制调用的指令.即使是这种情况,两个三维物体使用同一种材质,但它们使用的材质参数不一样,那么最终仍然会造成两次 ...

  8. 【web开发学习笔记】Structs2 Result学习笔记(三)带參数的结果集

    Result学习笔记(三)带參数的结果集 第一部分:代码 //前端 <head> <meta http-equiv="Content-Type" content= ...

  9. unity3d学习笔记(一) 第一人称视角实现和倒计时实现

    unity3d学习笔记(一) 第一人称视角实现和倒计时实现 1. 第一人称视角 (1)让mainCamera和player(视角对象)同步在一起 因为我们的player是生成的,所以不能把mainCa ...

随机推荐

  1. 把el-element的日期格式改为CRON

    在日常的开发当中,经常会遇到格式的不匹配造成的困扰. 在日期管理上,el-element也是贴心的准备了相关的日期选择器,但是在取值的时候发现,el-element所给出的值格式可能并不是我们常用的. ...

  2. [刷题] PTA 02-线性结构1 两个有序链表序列的合并

    程序: 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 typedef int ElementType; 5 typedef st ...

  3. 10.21 nmap:网络探测工具和安全/端口扫描器

    nmap命令 是一款开放源代码的网络探测和安全审核工具,是Network Mapper的缩写.其设计目标是快速地扫描大型网络.nmap可以发现网络上有哪些主机,主机提供了什么服务(应用程序名称和版本号 ...

  4. 【无人机航空摄影测量精品教程】目录:摄影测量、Pix4d、EPS、CC、PhotoScan项目化作业流程及注意事项汇总

    目录 1. 专栏简介 2. 专栏地址 3. 专栏目录 1. 专栏简介 该专栏为目前最为热门的无人机航测内外业项目,主要内容包括:无人机航测外业作业流程(像控点布设.航线规划.仿地飞行.航拍)和内业数据 ...

  5. Go语言web开发---Beego基础

    一.框架 框架:可复用的设计组件,它规定了应用的体系结构,明确了整个设计,协作各个组件之间的依赖关系,责任分配,和流程控制.通俗解释框架就是一堆代码的集合,为了提高软件的开发效率和质量,一般都会使用框 ...

  6. 书列荐书 |《至关重要的关系》 【美】里德&#183;霍夫曼

    本书的内容不算多,堪称精辟,有些东西甚至可以作为指导思想.括号内为书列君书评. 经典语录: 每个人都是企业家!(否则你无法最大化努力!) 创业和做人是相通的.我们要有计划,要执着,但是也要有弹性,懂得 ...

  7. CVPR2020论文解读:OCR场景文本识别

    CVPR2020论文解读:OCR场景文本识别 ABCNet:  Real-time Scene Text Spotting with Adaptive Bezier-Curve Network∗ 论文 ...

  8. Dockerfile构建实践

    Dockerfile构建实践 本文介绍了用于构建有效图像的推荐最佳实践和方法. Docker通过从一个Dockerfile文本文件中读取指令来自动构建映像,该文本文件按顺序包含构建给定映像所需的所有命 ...

  9. Mobileye 自动驾驶策略(二)

    Mobileye 自动驾驶策略(二) 与多方都成功进行了合作,其中比较大型的合作包括法雷奥.百度和中国 ITS. 法雷奥是最近的的 Tier 1 合作伙伴,法雷奥和 Mobileye 签署协议,表示未 ...

  10. Lidar激光雷达与Radar雷达

    Lidar激光雷达与Radar雷达 自动驾驶技术正迅速成为汽车工业的驱动力.来自全球的汽车制造商正在与Google等顶级高科技巨头以及其他知名初创公司合作,共同开发下一代自动驾驶汽车.中国也开辟了自动 ...