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. 通过Dapr实现一个简单的基于.net的微服务电商系统(十三)——istio+dapr构建多运行时服务网格之生产环境部署

    之前所有的演示都是在docker for windows上进行部署的,没有真正模拟生产环境,今天我们模拟真实环境在公有云上用linux操作如何实现istio+dapr+电商demo的部署. 目录:一. ...

  2. [bug] httpd服务启动问题

    参考 httpd服务器启动失败 https://www.cnblogs.com/Crazy-Liu/p/11550824.html Apache-httpd服务器启动成功网页却不能访问 https:/ ...

  3. 云计算OpenStack---云计算、大数据、人工智能(14)

    一.互联网行业及云计算 在互联网时代,技术是推动社会发展的驱动,云计算则是一个包罗万象的技术栈集合,通过网络提供IAAS.PAAS.SAAS等资源,涵盖从数据中心底层的硬件设置到最上层客户的应用.给我 ...

  4. SpringBoot 上传文件如何获取项目工程路径

    上传文件时,需要将上传的文件存放于工程路径中,以便前端能够获取文件资源,那如何获取工程路径呢? //获取 SpringBoot 工程中 static 的绝对路径 String serverpath= ...

  5. 3.1 cat:合并文件或查看文件内容

    cat 命令 可以理解为英文单词concatenate的缩写,其功能是连接多个文件并且打印到屏幕输出,或者重定向到指定的文件中.此命令常用来显示单个文件内容,或者将几个文件内容连接起来一起显示,还可以 ...

  6. PID参数

    大家奉上一篇关于PID算法及参数整定的知识! 1.位置表达式 位置式表达式是指任一时刻PID控制器输出的调节量的表达式. PID控制的表达式为 式中的y(t)为时刻t控制器输出的控制量,式中的y(0) ...

  7. jq slideDown后里面的A链接失效(已解决)

    jq slideDown后里面的A链接失效(解决) 用jq 的 slideDown写了一个二级下拉菜单,但是里面的a标签全部失效了,挂的链接右键菜单可以正常打开,但是左键正常点击不行 查阅了很多资料, ...

  8. Python单元测试简介及Django中的单元测试

    Python单元测试简介及Django中的单元测试 单元测试负责对最小的软件设计单元(模块)进行验证,unittest是Python自带的单元测试框架. 单元测试与功能测试都是日常开发中必不可少的部分 ...

  9. 高动态范围(High-Dynamic Range,简称HDR)

    高动态范围(High-Dynamic Range,简称HDR) 一.HDR介绍 高动态范围(High-Dynamic Range,简称HDR),又称宽动态范围技术,是在非常强烈的对比下让摄像机看到影像 ...

  10. YOLOv3和YOLOv4长篇核心综述(上)

    YOLOv3和YOLOv4长篇核心综述(上) 对目标检测算法会经常使用和关注,比如Yolov3.Yolov4算法. 实际项目进行目标检测任务,比如人脸识别.多目标追踪.REID.客流统计等项目.因此目 ...