【Unity】程序创建Mesh(二)MeshRenderer、光照、Probes探针、UV信息、法线信息

文章目录

  • 接上文
  • MeshRenderer(网格渲染器)
    • Materials(材质)
    • Material和Mesh对应
    • Lighting光照
    • Lightmapping
      • 材质中的光照
    • 光源类型
    • 阴影
    • 全局光照
    • Probes(探针)
    • Ray Tracing(光线追踪)
    • Additional Settings
  • UV信息
  • 法线信息
  • 最后


接上文

前面一篇文章【Unity】程序创建Mesh(一)Mesh网格、代码创建模型、顶点信息、三角形信息、MeshFilter、MeshRenderer讲了一部分使用代码创建网格的内容,这一节针对渲染相关的内容再做详解。

MeshRenderer(网格渲染器)

MeshRenderer是Unity中的一个组件,属于UnityEngine命名空间下的一个类,它继承自Renderer类。MeshRenderer的主要作用是渲染由MeshFilter或TextMesh插入的网格。它根据物体的Transform组件的定义位置,从网格过滤器(Mesh Filter)获取几何形状,并在该位置进行渲染。

MeshRenderer还有一些重要的属性,例如Cast Shadows(投射阴影),当这个属性被启用时,如果场景中有创建光照阴影的光源,MeshRenderer将会使对应的Mesh产生阴影。下面简单说明一下MeshRenderer的各项属性。
MeshRenderer设置

Materials(材质)

Materials是MeshRenderer中最重要的属性,它控制了网格的材质表现。通过修改MeshRenderer的Materials属性,我们可以改变物体的外观,如颜色、纹理、光照反应等。

具体来说,MeshRenderer的Materials属性是一个Material数组,这意味着一个MeshRenderer可以拥有多个材质。每个材质可以独立地应用到网格的不同部分,从而实现复杂的视觉效果。例如,一个游戏角色的身体部分可能使用一种材质,而武器或服装则使用另一种材质。

在Unity的编辑器中,你可以通过MeshRenderer组件的Inspector窗口来查看和编辑Materials属性。你可以添加、删除或重新排序材质,还可以为每个材质设置不同的Shader和纹理。

在代码中,你也可以通过脚本来操作MeshRenderer的Materials属性。例如,你可以创建一个新的Material,并将其添加到MeshRenderer的Materials数组中,或者修改现有材质的属性来改变物体的外观。

需要注意的是,当你修改MeshRenderer的Materials属性时,你是在修改该MeshRenderer的本地材质副本。如果你希望多个MeshRenderer共享相同的材质,你应该使用Material的实例化(Instance)而不是复制(Clone)。这样,当你修改共享材质的属性时,所有使用该材质的MeshRenderer都会受到影响。

此外,MeshRenderer的Materials属性与MeshFilter的mesh属性是相辅相成的。MeshFilter定义了物体的形状和结构,而MeshRenderer则通过Materials属性定义了这些形状和结构如何被渲染和表现出来。通过合理使用这两个组件,你可以创建出丰富多样的游戏世界和角色。
Materials材质设置

Material和Mesh对应

在Unity中,当你为MeshRenderer组件分配多个材质时,你需要确保这些材质与你的Mesh的子网格(Submeshes)正确对应。Mesh可以由多个子网格组成,每个子网格可以独立地应用一个材质。

为了将多个材质与Mesh的子网格对应起来,你需要按照以下步骤操作:

  1. 创建子网格:在你的Mesh中,使用SetTriangles方法为不同的部分设置三角形索引,从而创建子网格。每个子网格应包含一组连续的三角形索引。
int[] triangles0 = { /* 三角形索引数组,对应第一个子网格 */ };  
int[] triangles1 = { /* 三角形索引数组,对应第二个子网格 */ };  
// ...更多子网格  mesh.SetTriangles(triangles0, 0); // 设置第一个子网格  
// 设置第二个子网格,注意第二个参数是上一个子网格的三角形数量  
// 第三个参数submeshIndex用于指定子网格的索引。索引从0开始,每个子网格的索引必须唯一。
mesh.SetTriangles(triangles1, triangles0.Length, submeshIndex: 1); 
// ...为更多子网格设置三角形
  1. 分配材质:在你的MeshRenderer组件中,为Materials属性分配一个与你的子网格数量相同的材质数组。
Material[] materials = new Material[mesh.subMeshCount];  
materials[0] = new Material(Shader.Find("SomeShader")); // 为第一个子网格分配材质  
materials[1] = new Material(Shader.Find("AnotherShader")); // 为第二个子网格分配材质  
// ...为更多子网格分配材质  meshRenderer.materials = materials; // 将材质数组分配给MeshRenderer

这里mesh.subMeshCount将返回你的Mesh中子网格的数量,你需要确保分配的材质数组长度与子网格数量相匹配。

  1. 确保索引对应:重要的是要确保你设置的三角形索引与子网格的材质分配正确对应。如果你错误地分配了材质,或者三角形索引与子网格不对应,渲染结果可能会出现问题。
  2. 更新Mesh:在修改了Mesh的结构或材质后,确保调用mesh.RecalculateBounds()来更新Mesh的边界信息,这对于正确的渲染和碰撞检测很重要。
mesh.RecalculateBounds();

通过以上步骤,你可以将多个材质与你创建的Mesh的子网格对应起来,从而实现复杂的材质和渲染效果。这对于创建具有不同材质部分的物体(如角色模型的不同部位使用不同纹理)非常有用。

Lighting光照

MeshRenderer中提供了对于 Lighting(光照)的设置功能,它与场景中的光源(Lights)以及材质(Materials)相互作用,以产生光照效果。
材质定义了物体如何与光源进行交互。材质中的Shader决定了如何计算光照。例如,一个材质可能使用Phong Shading模型来计算光照,而另一个可能使用Lambert Shading。Shader代码决定了光照如何影响物体的颜色、亮度、高光等。

光照的设置内容如下:
光照设置

Lightmapping

如果勾选了 Lighting 中的 Contribute Global Illuminatior 选项,MeshRenderer 中就会出现对于 Lightmapping 的相关设置内容。
Lightmapping
Lightmapping设置内容如下:
Lightmapping设置

材质中的光照

在材质中可以设置多种光照属性,如:

  • Albedo(反照率):物体的基础颜色。
  • Metallic(金属度):物体表面的金属程度,影响高光反射。
  • Smoothness(光滑度):影响高光的大小和强度。
  • Emissive(自发光):物体自身发出的颜色,不受光源影响。

这些属性在Shader中用于计算光照结果。

光源类型

Unity支持多种光源类型,每种类型都有其独特的光照属性:

  • Directional Light(方向光):模拟来自无限远处的光源,如太阳。它有一个方向和一个颜色。
  • Point Light(点光源):从一个点向所有方向发射光线的光源。它有一个位置、颜色和范围。
  • Spot Light(聚光灯):从一个点发射光线,但只在一个圆锥体内照亮物体。它有一个位置、颜色、范围和圆锥体的角度。
  • Area Light(区域光):模拟一个具有面积的光源,可以产生更柔和的阴影。

阴影

阴影是光照系统中的一个重要部分。在Unity中,你可以为光源启用阴影,并选择阴影的类型(如硬阴影或软阴影)。阴影的渲染质量和性能消耗取决于你选择的阴影设置。

MeshRenderer 会根据场景中的光源和物体的材质来计算阴影。如果物体的材质或光源没有启用阴影,那么该物体就不会产生或接收阴影。

全局光照

全局光照(Global Illumination, GI)考虑了场景中所有光源对物体的间接照明影响。在Unity中,你可以使用实时全局光照(Realtime GI)或烘焙全局光照(Baked GI)来模拟这种效果。MeshRenderer 会与这些全局光照系统相互作用,以产生更真实的光照效果。

Probes(探针)

在Unity中,MeshRenderer中的Probes主要指的是光照探针(Light Probes)反射探针(Reflection Probes),它们用于在场景中获取光照和反射信息,以增强渲染的真实感。

  • 光照探针用于在光照计算中获取场景中的光照信息。它们能够捕捉场景中的光照数据,并在运行时为物体提供光照信息。这样,即使物体在场景中移动,也能根据最近的光照探针进行光照计算,实现平滑的光照过渡。光照探针的设置可以在MeshRenderer组件中进行调整,默认情况下,所有游戏对象都会使用光照探针,并在场景中改变位置时在最近的探针之间进行混合。
  • 反射探针则用于在反射计算中获取场景中的反射信息。它们能够捕捉场景中的环境反射数据,使得物体能够呈现出更真实的反射效果。通过反射探针,游戏开发者可以在物体表面模拟出周围环境的倒影和反射,提升游戏画面的质感。

在使用光照探针和反射探针时,开发者需要注意正确设置MeshRenderer组件的相关参数,以确保探针能够正确工作。此外,根据场景的具体需求和性能考虑,开发者还需要合理选择探针的数量和分布,以达到最佳的光照和反射效果。

探针的设置内容如下:
在这里插入图片描述

Ray Tracing(光线追踪)

在使用High Definition Render Pipeline(HDRP)管线时,在MeshRenderer中可以设置光追模式,分别为:

  • Off:关闭;
  • Static:静态光追;
  • Dynamic Transform(默认):动态变换;
  • Dynamic Geometry:动态几何。

关于HDRP的详细内容,可以直接到 Unity 手册中去查看,内容还是比较全面的,这里附上链接:高清渲染管线 (High Definition Render Pipeline)用户手册

Additional Settings

额外属性设置:
在这里插入图片描述

UV信息

// 设置网格的UV坐标(可选,但通常用于纹理映射)
Vector2[] uvs = new Vector2[]
{new Vector2(0, 0),new Vector2(1, 0),new Vector2(1, 1),new Vector2(0, 1)
};
mesh.uv = uvs;

设置Mesh的UV坐标的基本原理主要是为了实现纹理映射,确保纹理能够正确地贴合到三维模型的表面上。UV坐标是一个二维坐标系,其中U代表横向(水平)坐标,V代表纵向(垂直)坐标。在三维建模中,每个顶点都可以被赋予UV坐标,这些坐标用于将纹理映射到多边形表面上。

UV坐标的取值范围通常在0到1之间,包括0和1两个端点。这样无论图像的像素分辨率是多少,UV坐标都可以换算成贴图的像素坐标。通过将纹理图像的每个像素与模型表面的顶点进行对应,我们可以实现纹理的精确映射。

在设置UV坐标时,需要考虑到模型的几何形状和纹理的特点。不同的模型部分可能需要使用不同的UV坐标,以确保纹理能够正确地贴合到模型的各个表面上。同时,还需要注意UV坐标的连续性和平滑性,以避免在纹理映射时出现明显的接缝或拉伸现象。

除了基本的UV坐标设置外,还可以使用一些高级技术来优化纹理映射效果,比如UV展开和UV打包。UV展开是将三维模型的表面展开到二维平面上,以便更好地编辑和调整UV坐标。UV打包则是将多个模型的UV坐标合并到一个纹理图中,以提高纹理的利用效率和渲染性能。

总之,设置Mesh的UV坐标是实现纹理映射的关键步骤之一,需要根据模型的几何形状和纹理特点进行精确的设置和调整。

法线信息

// 设置网格的法线(可选,但通常用于光照计算)
Vector3[] normals = new Vector3[]
{Vector3.up,Vector3.up,Vector3.up,Vector3.up
};
mesh.normals = normals;

在Unity中使用代码来创建Mesh并指定法线信息时,需要提供一个Vector3数组,数组中每个元素对应一个Mesh顶点(一一对应),用于指定每个顶点的法线方向。如果你的Mesh是由平滑的面组成,你可能还需要计算平滑法线,这通常涉及到对相邻面的法线进行平均。

最后

关于UV和法线相关的更细节的内容,我会在渲染章节再进行细致的学习和记录(详见文档下方的目录),欢迎大家一起学习。


更多内容请查看总目录【Unity】Unity学习笔记目录整理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/747712.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】map和set深度讲解

> 作者简介:დ旧言~,目前大二,现在学习Java,c,c,Python等 > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:熟练掌握map和set容器。 > 毒鸡汤:…

升入理解计算机系统学习笔记

磁盘存储 磁盘是广为应用的保存大量数据的存储设备,存储数据的数量级可以达到几百到几千千兆字节,而基于RAM的存储器只能有几百或几千兆字节。不过,从磁盘上读信息的时间为毫秒级,比从DRAM读慢了10万倍,比从SRAM读慢了…

NodeJs利用腾讯云实现手机发送验证码

本文介绍如何在nodejs实现短信发送,以腾讯云的短信验证为例。 腾讯云中准备工作 首先需要腾讯云的个人或者企业认证的账号,个人会赠送一百条,企业赠送一千条,可以用于测试,地址:腾讯云短信服务。然后需要…

《Ubuntu20.04环境下的ROS进阶学习5》

一、Hector_Mapping构建二维地图 在前面我们已经介绍了如何使用激光雷达来扫描地图,如何用激光雷达来建造地图,本节我们将两者结合起来,通过Hector_Mapping功能包实现SLAM。 二、在仿真环境中进行2D SLAM 1、下载Hector_Mapping sudo apt i…

【论文阅读笔记】Attention Is All You Need

1.论文介绍 Attention Is All You Need 2017年 NIPS transformer 开山之作 回顾一下经典,学不明白了 Paper Code 2. 摘要 显性序列转导模型基于包括编码器和解码器的复杂递归或卷积神经网络。性能最好的模型还通过注意力机制连接编码器和解码器。我们提出了一个新…

【Numpy】练习题100道(26-50题)

#学习笔记# 在学习神经网络的过程中发现对numpy的操作不是非常熟悉,遂找到了Numpy 100题。 Git-hub链接 1.题目列表 26. 下面的脚本输出什么?(★☆☆) print(sum(range(5),-1)) from numpy import * print(sum(range(5),-1)) 27. 考虑一个整数向量…

怎样提升小程序日活?签到抽奖可行吗?

一、 日活运营策略 小程序应该是即用即走的,每个小程序都在用户中有自己的独特定位,可能是生活日常必备(美食、团购、商城),也可能是工作办公必备(文档、打卡、工具)。 如果你想要让自己的小程…

云计算与APP开发,如何利用云端服务提升应用性能?

随着移动应用程序(APP)的普及,如何提升应用性能成为了开发者们关注的重点之一。而云计算技术的发展为APP开发者提供了全新的解决方案。本文将探讨云计算与APP开发的结合,以及我们公司提出的解决方案,帮助开发者利用云端…

KMP 算法介绍

1. KMP 算法介绍 KMP 算法:全称叫做 「Knuth Morris Pratt 算法」,是由它的三位发明者 Donald Knuth、James H. Morris、 Vaughan Pratt 的名字来命名的。KMP 算法是他们三人在 1977 年联合发表的。 KMP 算法思想:对于给定文本串 T 与模式串 …

使用 ZipArchiveInputStream 读取压缩包内文件总数

读取压缩包内文件总数 简介 ZipArchiveInputStream 是 Apache Commons Compress 库中的一个类,用于读取 ZIP 格式的压缩文件。在处理 ZIP 文件时,编码格式是一个重要的问题,因为它决定了如何解释文件中的字符数据。通常情况下,Z…

代码随想录刷题笔记 Day 52 | 打家劫舍 No.198 | 打家劫舍 II No.213 | 打家劫舍III No.337

文章目录 Day 5201. 打家劫舍&#xff08;No. 198&#xff09;<1> 题目<2> 笔记<3> 代码 02. 打家劫舍 II&#xff08;No. 213&#xff09;<1> 题目<2> 笔记<3> 代码 03.打家劫舍III&#xff08;No. 337&#xff09;<1> 题目<2&g…

工智能的迷惑是技术发展的产物

简述&#xff1a; 随着ChatGPT在全球科技舞台上掀起一股热潮&#xff0c;人工智能再次成为了人们关注的焦点。各大公司纷纷紧跟潮流&#xff0c;推出了自己的AI大模型&#xff0c;如&#xff1a;文心一言、通义千问、讯飞星火、混元助手等等&#xff0c;意图在人工智能领域占据…

Vue多文件学习项目综合案例——购物车,黑马vue教程

一、项目截图 二、主要知识点 vuex的使用json-server的使用json-server --watch index.json三、需要注意的点 json-server 安装成功&#xff0c;查看版本直接报错。安装默认版本埋下的一个坑&#xff0c;和node版本不匹配作者直接安装vuex&#xff0c;默认安装也是版本不匹配…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:Panel)

可滑动面板&#xff0c;提供一种轻量的内容展示窗口&#xff0c;方便在不同尺寸中切换。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含子组件。 说明&#xff1a; 子组件类型&a…

QMI8658芯片I2C驱动开发指南

这个芯片纯国产挺好用的&#xff0c;电路很好设计&#xff0c;我这垃圾焊功&#xff0c;纯手焊&#xff0c;&#xff0c;居然能用。 第一部分 硬件连接 画的很简陋&#xff0c;看看就可以了&#xff0c;这里I2C总线需要接10K上拉没有画出来&#xff0c;这个需要注意一下。 …

树形结构 一篇文章梳理

树形结构是一种非常重要的非线性数据结构&#xff0c;它模拟了具有层次关系的数据模型。在树形结构中&#xff0c; 目录 一、组成元素&#xff1a; 二、树的属性&#xff1a; 深度或高度 度 路径 路径长度 三、树的类型 1 二叉树 2 多叉树 3 完全二叉树 4 满二叉树…

【计算机网络_传输层】UDP和TCP协议

文章目录 1. 重新理解端口号端口号划分netstat指令pidof 2. UDP协议2.1 UDP协议端格式2.2 UDP的特点2.3 UDP的注意事项2.4 基于UDP的应用层协议 3. TCP协议&#xff08;传输控制协议&#xff09;3.1 TCP协议的格式和报头字段3.2 如何解包和分用3.3 理解TCP协议报头3.4 TCP协议的…

day-20 二叉树的层序遍历

思路&#xff1a;利用队列进行广度优先遍历即可 注意点&#xff1a;ArrayList执行remove之后&#xff0c;索引i会立即重排&#xff0c;注意可能越界 code: /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeN…

Xcode调试Qt 源码

在Mac下使用Xcode 开发Qt程序&#xff0c;由于程序断点或者崩溃后&#xff0c;Qt库的堆栈并不能够正确定位到源码的cpp文件&#xff0c;而是显示的是汇编代码&#xff0c;导致不直观的显示。 加载的其他三方库都是同理。 所以找了攻略和研究后&#xff0c;写的这篇文章。 一&a…

SIP调试之SIPP测试工具

SIPP是针对SIP协议的一个性能测试的命令行工具&#xff0c;可以动态显示测试的统计信息&#xff08;如呼叫速率、延时、消息统计等&#xff09;。用户可以通过XML场景配置文件&#xff0c;自定义模拟各种UAC/UAS测试场景的信令交互流程&#xff0c;可以被用来测试IP话机、SIP代…