Unity3D学习笔记2——绘制一个带纹理的面

简介: Unity3D学习笔记2——绘制一个带纹理的面

Unity3D学习笔记2——绘制一个带纹理的面

目录

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

标签: 材质 , , 纹理 , Unity3D


相关文章
|
1月前
|
缓存 图形学
Unity3D学习笔记12——渲染纹理
Unity3D学习笔记12——渲染纹理
29 2
|
1月前
|
API C# 图形学
Unity3D学习笔记9——加载纹理
Unity3D学习笔记9——加载纹理
26 2
|
1月前
|
API 图形学 异构计算
Unity3D学习笔记7——GPU实例化(2)
Unity3D学习笔记7——GPU实例化(2)
|
1月前
|
存储 缓存 图形学
Unity3D学习笔记11——后处理
Unity3D学习笔记11——后处理
24 1
|
20天前
|
图形学 开发者
【独家揭秘】Unity游戏开发秘籍:从基础到进阶,掌握材质与纹理的艺术,打造超现实游戏视效的全过程剖析——案例教你如何让每一面墙都会“说话”
【8月更文挑战第31天】Unity 是全球领先的跨平台游戏开发引擎,以其高效性能和丰富的工具集著称,尤其在提升游戏视觉效果方面表现突出。本文通过具体案例分析,介绍如何利用 Unity 中的材质与纹理技术打造逼真且具艺术感的游戏世界。材质定义物体表面属性,如颜色、光滑度等;纹理则用于模拟真实细节。结合使用两者可显著增强场景真实感。以 FPS 游戏为例,通过调整材质参数和编写脚本动态改变属性,可实现自然视觉效果。此外,Unity 还提供了多种高级技术和优化方法供开发者探索。
35 0
|
1月前
|
测试技术 C# 图形学
Unity3D学习笔记10——纹理数组
Unity3D学习笔记10——纹理数组
37 0
|
1月前
|
图形学 异构计算
Unity3D学习笔记8——GPU实例化(3)
Unity3D学习笔记8——GPU实例化(3)
24 0
|
1月前
|
存储 API 图形学
Unity3D学习笔记6——GPU实例化(1)
Unity3D学习笔记6——GPU实例化(1)
27 0
|
1月前
|
API 图形学 索引
Unity3D学习笔记5——创建子Mesh
Unity3D学习笔记5——创建子Mesh
23 0
|
1月前
|
API C# 图形学
Unity3D学习笔记4——创建Mesh高级接口
Unity3D学习笔记4——创建Mesh高级接口
28 0