《Unity着色器和屏幕特效开发秘笈》—— 2.6 在Unity编辑器中创建程序纹理贴图

简介:

本节书摘来自华章出版社《Unity着色器和屏幕特效开发秘笈》一 书中的第2章,第2.6节,作者:(美)Kenny Lammers,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.6 在Unity编辑器中创建程序纹理贴图

有时你为了创建更多不一样的效果,需要动态创建纹理或者在运行时修改它们的像素值,这种情况通常被称为程序性的纹理效果。不同于你在图像编辑软件中手动制作一些新纹理,你需要在一个二维空间中创建一组像素然后将其应用到一个新的纹理上。再将创建的新纹理传入到着色器中,使它们可以在着色器中进行计算。
这种技术在已有的纹理贴图上进行绘图是非常有用的,我们使用动态创建纹理贴图的方式可以制造一种玩家和游戏环境之间的互动效果。也可以用它来制作一些贴花的效果,或者创建一些可以在着色器函数中使用的程序化形状等。在很多情况下比如你可能想创建一个新纹理并且将它匹配到某些程序模式,另外你也可以将它应用到你的着色器中。
创建动态纹理的过程其实就是对你的纹理进行处理的过程,它肯定需要依赖于一个专门的脚本。但是你需要了解它是如何实现的,换句话说,你应该知道在你的着色器管线中需要哪些技术。让我们来看看如何通过创建一个脚本实现将动态创建的纹理赋给表面着色器。

2.6.1 准备工作

你需要通过执行以下步骤来为本节做些准备:
1.在你的Unity项目中创建一个新的C#脚本,并将其命名为ProceduralTexture。
2.在场景中创建一个空的游戏对象,将其Position(位置)置零,并将Procedural-Texture.cs脚本附加到该物体上。
3.接下来,创建一个新的着色器,一个新的材质,以及一个可以附加着色器和材质的对象。确定你的着色器和材料的命名,使你通过名字可以很容易地找到它们。
4.设置好了这一切,我们就可以创建一段代码实现一个抛物线型的像素值,将其应用至一个纹理并将该纹理赋给着色器。通过本节的学习,你将创建一个如下图所示的纹理贴图:
screenshot

2.6.2 如何操作

1.创建一个变量来控制纹理的高度和宽度,以及一个Texture2D类型的变量来存储我们生成的纹理。我们还需要几个私有变量来存储脚本运行时涉及的一些变量值。
screenshot

2.在脚本的Start()函数中,我们首先需要检查对象,查看该对象的材质属性是否已经赋值。如果材质不为空,我们将调用自定义函数GenerateParabola(),并为我们返回一个Texture2D类型的变量值:
screenshot

3.然后,我们需要声明自定义函数GenerateParabola(),它将实现我们预期的效果:
screenshot

4.最后,我们还要填充自定义函数,实现一个抛物线形纹理的算法。现在先不用关心这些内容的具体意义,我们将在本章的下一节详细地讲解每一行代码。
screenshot
screenshot

2.6.3 实现原理

在脚本开始处,我们先简单地检查场景中的特定对象,看看是否有材质赋给该对象,这样我们才能给它指定一个纹理。如果该对象的材质不为空,我们会将自定义的currentMaterial变量值赋给transform.renderer.sharedMaterial的返回值,该返回值是一个材质类型变量。
然后,进入下一个if()语句,检查当前材质值是否为有效值。如果材质值有效,我们就调用GenerateParabola()函数,该函数将为我们返回一个Texture2D类型的值。
当程序运行到GenerateParabola()函数时,它会先通过Texture2D()构造函数创建一个新的纹理,并且传入我们的widthHeight变量。完成这一步后我们将创建一个空的纹理,这样我们就可以递归widthHeight的平方次为每个像素填充相应的颜色值了。
创建了新的纹理以后,我们计算中心像素的位置,并使用centerPixelPosition变量来存储该值。
接下来,我们进入两个相嵌的For循环遍历刚才新建空纹理的每个像素。如果你不是很熟悉C#的for循环,可以查阅http://msdn.microsoft. com/en-us/library/ch45axte.aspx。
接下来,对于循环内当前像素值的位置Vector2(x,y),我们使用Vector2.Distance()函数计算它与中心像素的距离,该函数将为我们返回一个浮点值。举例来说,如果在循环中的当前像素位置是Vector2(32,32)而且我们创建的是一个512×512的纹理,那么我们得到的距离值等于316.78。也就是说,它与中心点的像素距离为(32,32)。
然后,我们需要将像素距离值重新映射至0到1的范围内,这样它才能作为一个颜色值被我们使用(Unity使用的颜色值范围是从0到1的)。为了实现这种映射我们需要做的就是将距离值除以纹理的宽度或高度值的一半。因此,在这种情况下,我们需要把我们的距离值除以256,也就是512的一半。所以,如果我们有一个大小为316.78的距离值,正如我们在前面的例子中看到的一样,我们会得到一个大小为1.23的颜色值。
现在,我们还需要确保我们得到的任何值都不能高于1.0或低于0.0,因此我们使用Mathf.Clamp()函数,它可以让我们将值限定在你传递的参数范围内。我们给该函数传入0和1两个值,以确保我们得到的是一个归一化的值。
最后,我们用1减去当前值对颜色值进行取反,然后将最后的值传递给一个新的颜色变量的各个通道。如下图所示:
screenshot

2.6.4 更多内容

现在你已经看到了如何使用少量的矢量数学生成像素值,你也可以试着生成其他类型的数据并将它们存储到一个纹理当中。下面的代码演示了通过使用世界向量和图像中心到当前像素的向量方向两者的点积来生成其他类型数据。
1.下面就是使用数学公式创建一个环绕纹理中心的环形:
screenshot

2.下面是使用数学公式计算像素方向上的点积,相对世界向量的Vector3.up(Vector3(0, 1, 0) y轴)和Vector3.right(Vector3(1, 0, 0) x轴):
screenshot

3.下面是使用数学公式计算像素方向相对世界方向的角度:
screenshot

生成像素使用不同的向量和角度计算会产生不同的计算结果,我们可以通过下图看出:
screenshot

相关文章
|
26天前
|
数据可视化 前端开发 开发工具
如何在网页中嵌入UE/Unity/WebGL程序,并与网页端通信
LarkXR实时云渲染平台,为UE数字孪生提供的产品化、平台化功能模块,以及必备的二次开发能力。
如何在网页中嵌入UE/Unity/WebGL程序,并与网页端通信
|
4月前
|
图形学 开发者
Unity编辑器脚本(添加/删除)碰撞盒
这段代码提供了两个Unity编辑器工具,用于批量处理模型的碰撞盒。一是“一键添加所有碰撞盒”,通过选择模型的父物体,自动为其子物体添加`MeshCollider`。二是“一键清理所有Collider碰撞盒”,同样选择父物体后,递归删除子物体上的`BoxCollider`组件。两者均通过Unity的菜单项实现便捷操作,方便开发者快速调整场景中的物理属性。
|
10月前
|
存储 安全 数据安全/隐私保护
Django 后端架构开发:富文本编辑器权限管理与 UEditor 、Wiki接入,实现 Markdown 文本编辑器
Django 后端架构开发:富文本编辑器权限管理与 UEditor 、Wiki接入,实现 Markdown 文本编辑器
393 0
|
7月前
|
前端开发
业余时间开发了个海报编辑器
为了满足撰写博客或录制教程视频时对高质量海报的需求,我利用业余时间开发了一款海报编辑器。第一版功能简单,支持固定尺寸、黑底白字的标题。后来经过优化,增加了背景图、模糊效果、文字样式调整等功能,使海报更具吸引力。目前该编辑器已上线,欢迎大家试用并反馈。[访问海报编辑器](https://tool.share888.top/#/poster)
135 6
业余时间开发了个海报编辑器
|
7月前
|
缓存 API 开发工具
有关Unity使用Rider编辑器无法弹出代码提示的有效解决方法
【11月更文挑战第13天】在 Unity 中使用 Rider 编辑器时,若遇到代码提示无法弹出的问题,可以通过检查 Rider 设置(如自动补全选项、Unity 插件安装、索引设置)、Unity 项目设置(如解决方案正确关联、脚本导入设置)以及环境和依赖关系(如 .NET SDK 版本兼容性、Unity 和 Rider 版本兼容性)等方面进行排查和解决。
1153 5
|
8月前
|
运维 Java Linux
【运维基础知识】掌握VI编辑器:提升你的Java开发效率
本文详细介绍了VI编辑器的常用命令,包括模式切换、文本编辑、搜索替换及退出操作,帮助Java开发者提高在Linux环境下的编码效率。掌握这些命令,将使你在开发过程中更加得心应手。
100 2
|
10月前
|
图形学 开发者 存储
超越基础教程:深度拆解Unity地形编辑器的每一个隐藏角落,让你的游戏世界既浩瀚无垠又细节满满——从新手到高手的全面技巧升级秘籍
【8月更文挑战第31天】Unity地形编辑器是游戏开发中的重要工具,可快速创建复杂多变的游戏环境。本文通过比较不同地形编辑技术,详细介绍如何利用其功能构建广阔且精细的游戏世界,并提供具体示例代码,展示从基础地形绘制到植被与纹理添加的全过程。通过学习这些技巧,开发者能显著提升游戏画面质量和玩家体验。
580 3
|
10月前
|
开发者 图形学 开发工具
Unity编辑器神级扩展攻略:从批量操作到定制Inspector界面,手把手教你编写高效开发工具,解锁编辑器隐藏潜能
【8月更文挑战第31天】Unity是一款强大的游戏开发引擎,支持多平台发布与高度可定制的编辑器环境。通过自定义编辑器工具,开发者能显著提升工作效率。本文介绍如何使用C#脚本扩展Unity编辑器功能,包括批量调整游戏对象位置、创建自定义Inspector界面及项目统计窗口等实用工具,并提供具体示例代码。理解并应用这些技巧,可大幅优化开发流程,提高生产力。
803 1
|
10月前
|
算法 vr&ar C#
使用Unity进行虚拟现实开发:深入探索与实践
【8月更文挑战第24天】使用Unity进行虚拟现实开发是一个充满挑战和机遇的过程。通过掌握Unity的VR开发技术,你可以创造出令人惊叹的VR体验,为用户带来前所未有的沉浸感和乐趣。随着技术的不断进步和应用场景的不断拓展,VR开发的未来充满了无限可能。希望本文能为你提供有用的指导和启发!
|
10月前
|
缓存 图形学
Unity3D学习笔记12——渲染纹理
Unity3D学习笔记12——渲染纹理
89 2