Unity 5.x Shaders and Effects Cookbook中文版翻译(第二版)

​ 我打算试着翻译这本技术书,目的又两个,1.希望自己能帮助英文不太好的朋友,2.希望自己也学到这些知识,顺便帮助自己提升英语水平。我英语水平不是很好,接下来如果有什么错误的地方,有看到的朋友还请帮忙纠正。我不会web前端技术,我想试着学学markdown语法,尽量让页面好看些但是最重要的还是内容。 Unity 5.x Shaders and Effects Cookbook中文版(第二版) 目录表 鸣谢 关于作者 www.PacktPub.com 电子书, 优惠, 还有其他 为什么需要订阅? 前言 这本书包含哪些内容 学习的过程中你需要准备的 本书的适合人群 内容结构 始前准备 操作步骤 原理介绍 额外内容 相关补充 本书的一些文体说明 读者反馈 客户支持 示例代码下载 本书一些彩图的下载 勘误表 盗版声明 本书有问题请联系 1.创建你的第一个着色器 介绍 创建一个基本的标准着色器 始前准备 操作步骤 原理介绍 相关补充 如何把Unity 4的旧着色器迁移至Unity 5 始前准备 操作步骤 着色器版本的自动升级 使用标准着色器 迁移用户自定义的着色器 原理介绍 相关补充 给着色器添加属性 始前准备 操作步骤 原理介绍 相关补充 使用表面着色器的属性 操作步骤 原理介绍 额外内容 相关补充 2.表面着色器和纹理贴图 介绍 漫反射的着色处理 始前准备 操作步骤 原理介绍 使用包组 操作步骤 压缩矩阵 相关补充 向着色器添加纹理...

June 26, 2023 · 2 min · 282 words · Link

用数组来实现热度图

用数组来实现热度图 着色器难以掌握的一个典型的原因就是缺少合适的文档。许多开发者在学习着色器的时候被代码搞得一团糟,原因就是他们没有很深的知识来解释眼前到底发生了什么。事实上 Cg/HLSL 中有着大量的臆断,这些臆断又没有被正确的证明过,这就让问题变得更加的突出。Unity3d允许C#脚本使用诸如 SetFloat,SetInt,SetVector 等之类的方法来跟着色器通信。遗憾的是,Unity3D没有类似 SetArray 的方法,也正因如此导致很多开发者们以为 Cg/HLSL 不支持 数组(arrays)。但事实并非如此,这篇文章将会给你展示向着色器传递数组的可能性。需要注意的是GPU为并行计算进行了高度的优化,所以如果在着色器中使用 循环结构(loops) 将会极大的降低它的性能。 在这个知识点中,我们将会实现一个热度图,看起来大概跟下图一样: 始前准备 这个知识点中介绍的效果是从一些设置好的点中创建一个热度图。这个热度图将会覆盖在另外一张图片的上面,就像一张前置图片。下面是必要的步骤: 1.在Unity中使用一张纹理创建一个 quad,这张纹理就是用来创建热度图的那张纹理。在我们的例子中,使用了一张伦敦地图的纹理。 2.创建另外一个 quad,并且把它放在前面创建的那个quad的上面。我们的热度图将会在这个quad上产生。 3.创建一个对应的材质,并且把材质和着色器都应用到第二个quad上。 操作步骤 这个着色器跟我们之前创建的着色器还是有很大不同,当然它也相对较短。因此,下面的步骤中直接提供了着色器完整代码: 1.将下面的的着色器代码整个复制到新创建的着色器中: // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' shader "Custom/Heatmap" { Properties { _HeatTex ("Texture", 2D) = "white" {} } Subshader { Tags {"Queue"="Transparent"} Blend SrcAlpha OneMinusSrcAlpha // Alpha blend Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag struct vertInput { float4 pos : POSITION; }; struct vertOutput { float4 pos : POSITION; fixed3 worldPos : TEXCOORD1; }; vertOutput vert(vertInput input) { vertOutput o; o....

May 4, 2023 · 2 min · 372 words · Link

实现一个毛皮效果的着色器

实现一个毛皮效果的着色器 材质的外观取决于它的物理结构。着色器试图去模拟它们,但在那样做的过程中,它们都把光的行为方式过度的简化了。因为材质有肉眼可见的复杂结构所以渲染起来尤其的难。比如大多数的纺织布料和动物的毛皮。在这个知识点中将会展示去模拟皮毛和其他材质(比如草)的可能性,而不仅仅是限于那些平坦的的表面模拟。为了完成这些,同样的材质将会被一遍又一遍的进行多次绘制,每一次都会增加它的大小。因此创造了皮毛的假象。 这里着色器所呈现出的效果基于了 Jonathan Czeck 和 Aras Pranckevičius 的工作成果: 始前准备 为了让这个知识点能起效果,你需要准备两样东西。首先是一张皮毛的纹理因为它要呈现外观。其次是另外一张用来表示皮毛分布的纹理,并且它要跟前一张纹理高度匹配。下面的图片展示的是美洲豹的毛皮纹理(左)和它可能的控制遮罩纹理(右): 白像素的控制遮罩将从原始的材质挤压而来,模拟了一张毛皮。那些白像素分布稀疏程度非常的重要,因为它能给我们一种材料是由很多细小的毛发构成的假象。创建一张那样的纹理的简单方式如下: 1.给你的原始纹理设置一个阈值,好让原始纹理失去毛皮厚度的时候截取斑点纹理。 2.添加一个噪音过滤器让图像像素画。噪音的RGB通道一定去掉关联从而获得黑白的结果。 3.为了看起来真实一点,覆盖一个 Perlin 噪音过滤器来给毛皮添加一些变化。 4.最后,再应用一个阈值过滤器让纹理的像素更好的分离。 跟其他着色器开始前一样,你需要创建一个新的 标准着色器(standard shader) 和材质来容纳它们。 操作步骤 对于这个知识点,我们能开始修改我们的 标准着色器(standard shader) 了: 1.在着色器的 属性(Properties) 上添加下面的代码: Properties { _Color ("Main Color", Color) = (1,1,1,1) _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {} _Glossiness ("Smoothness", Range(0,1)) = 0.5 _Metallic ("Metallic", Range(0,1)) = 0.0 _FurLength ("Fur Length", Range (.0002, 1)) = .25 _Cutoff ("Alpha cutoff", Range(0,1)) = 0....

May 3, 2023 · 5 min · 907 words · Link

使用CG包含让着色器模块化

使用CG包含让着色器模块化 都说关于内建的CG包含文件很棒,但是如果我们想构建自己CG包含文件来保存我们自己的光照模型和帮助函数该怎么办呢?我们是能这样做的,事实上,在我们的着色器编写管线中如果要高效的使用自己包含文件,还需要多学一点代码的语法才能来创建自己的包含文件。不用纠结了,让我们来看看如何创建一个新的CG包含文件的过程吧。 始前准备 让我们概览一下在这个知识点中生成这些新的项的过程吧。 1.首先我们创建一个新的名为 MyCgInclude.txt 的文本文件。 2.其次将这个文件的扩展名改为 .cginc,Windows可能会给出一个该文件会不可用的警告消息,但它依然时可以正常工作。 3.将这个新的 .cginc 文件导入到Unity工程中并且让它编译。如果一切顺利,你将会看到Unity会把它编译成一个CG包含文件。 我们现在已经准备好创建我们自定义的CG包含代码了。然后简单的双击这个你创建的CG包含文件在代码编辑器中打开它。 操作步骤 打开我们的CG包含文件按之后,我们就能向其中添加代码了,好让它可以跟我们表面着色器一起工作。下面的代码可以准备好我们的CG包含文件让它可以跟表面着色器一起使用,并且随着我们开发越来越多着色器,还能对它持续的添加所需的代码: 1.开始创建我们的CG包含文件的时候我们来了解一下 预编译指令(preprocessor directive)。它们时类似于 #pragma 和 #include 这样的声明。在这个例子中,我们想定义一个新的代码设置,在这个代码设置中如果我们的着色器在它的预编译指令中包含了这个文件,那么这个代码设置将会执行。在你的CG包含文件的顶部输入下面的代码: #ifndef MY_CG_INCLUDE #define MY_CG_INCLUDE 2.我们总是需要确保对 #ifndef 或者 #ifdef 用 #endif 将前面的这些定义检测闭合[就是我们编程中常说的成对出现,译者注],就好像C#中的 if 声明一样,我们需要用两个括号将它闭合。在 #define 指令后面输入下面的的代码: #endif 3.此时,我们只需要给CG包含文件填充代码了。所以我们通过添加下面的代码来完成我们的CG包含文件: fixed4 _MyColor; inline fixed4 LightingHalfLamber (SurfaceOutput s, fixed3 lightDir, fixed atten) { fixed diff = max(0, dot(s.Normal, lightDir)); diff = (diff + 0.5)*0.5; fixed4 c; c.rgb = s.Albedo * _LightColor0.rgb * ((diff * _MyColor....

May 3, 2023 · 2 min · 218 words · Link

更高级的着色器技术

第十章 更高级的着色器技术 在本章节中,你将会学习下面的这些知识点: 使用Unity内建的 CG包含(CgInclude) 文件功能 使用CG包含让着色器模块化 实现一个毛皮效果的着色器 用数组来实现热度图 介绍 最后这一章涵盖了一些可用于游戏的高级的着色器技术。你需要记住的是很多你在游戏中看到的引人入胜的效果,都来自于对着色器技术反复打磨,力求完美的追求。这本书只是抛砖引玉罢了,教你一些修改和创建着色的知识。所以非常强烈的鼓励你竭尽所能的利用这些知识去实践和实验。制作一款好的游戏并不是一项追求超现实主义的任务;学习着色器不是为了完全模仿现实,因为这是办不到的。相反的,你应该试着把着色器当成一个工具来让你的游戏变得独一无二。有了最后这一章的知识后,你就能够创建自己想要的材质了。 使用Unity内建的CG包含文件功能 编写我们自己的 CG包含文件(CgInclude files) 的第一步就是先去了解Unity都给我们提供了哪些现成的着色器。编写 表面着色器(Surface Shaders) 的时候,其实这隐藏的背后发生了很多的事情,这让编写表面着色器的过程变得非常高效。我们是可以查看这些CG包含文件所包含的代码的,位置就在 Editor | Data | CGIncludes [编辑器的安装位置,译者注]。所有的文件都包含在这个目录下,发挥着跟我们自己的着色器一起将我们的游戏对象渲染到屏幕上的作用。这些文件中,有些负责阴影和光照,有些提供一些有用的功能,还有的负责管理跟平台相关的依赖等。如果没有它们,那么我们的着色器编写体验将会变得更加繁琐。 你可以通过下面的链接查找Unity给我们的提供的相关CG包含文件的信息列表: https://docs.unity3d.com/Manual/SL-BuiltinIncludes.html 让我们开始了解Unity内建的CG包含文件吧,从 UnityCG.cginc 这个文件中使用一些内建的帮助函数。 始前准备 在迫不及待开始编写着色器前,我们需要在场景中设置一些东西。我们需要创建下面的这些东西并且在代码编辑器打开着色器: 1.创建一个新的场景然后在场景中添加一个简单的球体。 2.创建一个新的材质和着色器。 3.将着色器挂载到材质上然后将材质应用到球体上。 4.之后,创建一个 平行光(directional light) 并且将它放到我们的球体的上面。 5.最后,我们将要去打开 UnityCG.cginc 这文件了,它在Unity的 包含文件夹(CgInclude folder) 下面,位置在Unity编辑器的安装位置。这可以让我们分析一些帮助函数的代码,好让我们能更好的理解当我们使用它们的过程中都发生了什么。 6.你应该有了一个简单的场景用来跑着色器了,就像下面的屏幕截图一样: 操作步骤 场景准备好后,我们现在就可以开始对一些包含在 UnityCG.cginc 文件中的内建帮助函数进行实验了。在Unity中双击我们之前为场景创建的着色器,这样在代码编辑器中打开它,然后在着色器中输入下面步骤提供的代码: 1.在着色器的 属性块(Properties block) 中添加下面的代码。我们需要给这个演示的着色器添加一张单独的纹理和一个滑动条: Properties { _MainTex ("Albedo (RGB)", 2D) = "white" {} _DesatValue ("Desaturate", Range(0, 1)) = 0.5 } 2....

May 3, 2023 · 1 min · 156 words · Link

创建一个夜视屏幕效果

创建一个夜视屏幕效果 我们的下一个屏幕效果绝对是一个更受欢迎的效果。在游戏市场中的 使命召唤现代战争(Call of Duty Modern Warfare),光环(Halo) 等第一人称游戏中都出现过。是使用一种独特的青柠色屏幕颜色,让整个图像增亮的效果。 为了获得这种夜视效果,我们需要使用Photoshop来剖析这个效果。它是这么一个简单的过程,在网上找一些相关的图片然后将这些图像组成一个层级,看看你将需要哪种混合模式,或者需要哪一种顺序来组合我们的这些层级。下图展示的是用Photoshop处理后的呈现效果: 让我们把由Photoshop组成的图像分解成不同的组成部分,好让我们可以更好的理解这些我们之后要组合的资源。在下一个知识点中,我们将涵盖这些的处理过程。 始前准备 开始制作我们这个屏幕效果,我们又要将这个效果分解成不同的组成层级。我们可以使用Photoshop创建一个效果图,这样对于创建我们的夜视效果来说,可以对如何构成这个效果提供一些灵感: 绿色着色: 我们屏幕效果的第一层是标志性的绿色,几乎在每一张夜视图像中都能找到。这将给我们的效果带来标志性的夜视的样子,就像下图所示那样: 扫描线: 为了给玩家带来一种新的显示效果,提升效果呈现,我们在着色层的上面添加扫描线。为了这个,我们将用Photoshop创建一个纹理,让用户可以对纹理进行平铺,从而可以让这些扫描线变大或者缩小。 噪音图: 我们的下一层级是一张简单的噪音纹理,我们将会把它平铺在平铺后的着色图像和扫描线的上面,然后将图像打散并且给我们的效果添加更多的细节。这一层简单的强调了 数字读出外观(digital read-out look) :[各位觉得听起来拗口,可以去查一下DRO的概念,我这里贴一个相关的百科] 渐晕纹理: 我们的夜视效果的最后一个层级是渐晕。如果看过使命召唤现代战争中的夜视效果,你就会注意到它使用了一个渐晕来仿造一个从单筒望眼镜看出来的效果。我们将在这个屏幕效果中也做同样的事情: 让我们聚集需要的这些纹理,开始创建我们的屏幕效果。请按照下面的步骤进行: 1.收集一张渐晕纹理,一张噪音纹理和一张扫描线纹理,就跟我们上面看到哪些那样的就行。 2.创建一个名为 NightVisionEffect.cs 的脚本和一个名为 NightVisionEffectShader.shader 的着色器。 3.创建好这些代码文件后,给这些文件添加必要的代码好让屏幕效果系统可以设置好并且正常运行。至于该如何做的操作步骤,可以参考 第八章, 通过Unity渲染纹理实现屏幕效果。 最终,随着我们的屏幕效果系统设置好并且顺利运行,以及收集好所需的纹理后,我们就可以开始创建夜视效果的过程了。 操作步骤 当我们把所有的资源收集好并且让屏幕效果系统流畅的跑起来后,让我们开始给脚本和着色器添加一些必要的代码。我们将首先给 NightVisionEffect.cs 脚本添加代码,双击脚本在代码编辑器中打开这个文件。 1.我们先要给脚本添加一些变量,这样可以让这个效果的用户在 检查器面板(Inspector) 中去调整这些变量。在 NightVisionEffect.cs 脚本中输入下面的代码: #region Variables public Shader nightVisionShader; public float constrast = 2.0f; public float brightness = 1.0f; public Color nightVisionColor = Color.white; public Texture2D vignetteTexture; public Texture2D scanLineTexture; public float scanLineTileAmount = 4....

May 2, 2023 · 3 min · 559 words · Link

游戏和屏幕效果

第九章 游戏和屏幕效果 当我们要创建可信和沉浸的游戏的时候,我们要考虑的不仅仅只有材料。屏幕效果也会改变游戏的整体感觉。这在电影里面非常常见,比如后期制作阶段中的调色。使用 第八章 通过Unity渲染纹理实现屏幕效果 中学到的知识,你也可以在游戏中实现这些技术。在这一章将会呈现两个有趣的效果;当然,你可以适当修改它们以适用于你的需求,也可以创建完全属于你自己屏幕效果。 在这一章,你将会学到下面的这些知识点: 创建一个老电影屏幕效果 创建一个夜视屏幕效果 介绍 如果你正在阅读这本书,你很可能玩过一两个游戏。即时游戏一方面会使玩家进入一个沉浸世界,让人觉得他们好像在现实世界玩游戏一样。现代的游戏利用的屏幕效果越多获得的沉浸感也越多。 通过屏幕效果,我们可以将在某个确切环境中的心境从平静转为惊恐,仅仅只要改变屏幕看起来的样子。想象一下走进了某个关卡中的房间,然后游戏突然接管并且将你带进一个电影时刻。很多现代游戏都会使用不同的屏幕效果来改变不同时刻的一个心境。理解如何创建在游戏中使用的效果是我们学习编写着色器的下一个旅程。 在这一章,我们将了解一些更加常用的游戏中的屏幕效果。你将会学习如何改变游戏的样子,把它从正常的样子改成一个老电影效果的样子,并且我们还会去了解大多数 FPS(first-person shooter第一人称射击) 游戏是如何使他们的夜视效果呈现在屏幕中的。通过这些知识点,我们将了解如何将这些效果跟游戏中的事件关联起来,好让游戏根据当前演出的需要去打开或者关闭这些特效。 创建一个老电影屏幕效果 很多游戏背景设定在不同的时期。有些发生在幻想世界或者科幻世界,更有甚者发生在旧西部,那个时候电影摄像机才刚刚发明并且人们看到的都是一些黑白电影或者棕褐色效果色调的电影。它们看起来格外不同,我们将在Unity中用屏幕效果来复制这种看起来的样子。 获得这种效果需要一些步骤,如果要将整个屏幕变成黑或白或灰,我们需要将这个效果分解成不同的组成部分。如果我们分析一些相关的老电影的镜头,我们就可以开始做这个了。让我们来看看下面这张图片并且分解其中的元素,看看是那些构成了这个老电影的样子: 我们用一些在网上找到的图片构建了这个图片。像这样尝试利用Photoshop来构建图片总是一个很好的主意,它能为你的新的屏幕特效打好一个计划。在这个过程中它不仅能将我们需要用代码编写的元素告诉我们,还提供了一个快捷的方式让我们了解我们的屏幕效果需要使用哪一种混合模式和我们将要构建那些层级。本书这个知识点中我们为Photoshop创建的这些文件的支持网站在http://www.packtpub.com/support[已经失效(译者注)]。它是一个名为 OldFilmEffect_Research_Layout.psd 的文件。 始前准备 我们现在目的明确,让我们看看最终效果的每一层都包含了什么然后为我们的着色器和C#脚本收集一些资源。 复古色调(Sepia tone): 这是一个相对容易获得的效果,我们只需把原始渲染纹理的所有像素颜色变为一个单一的颜色范围。使用原始图像的亮度然后加上一个常量颜色就可以很容易获得。我们的第一层将会看起来跟下面的图片一样: 渐晕效果(Vignette effect): 当一些古老的电影放映机放映老电影的时候,我们经常看到某种软边界[ 我个人觉得翻译的不够准确 ]围绕在老电影的四周。这是因为这种电影放映机使用的球形灯泡发出的光中间部位比周围要亮造成的。这种效果通常叫做渐晕效果并且是我们屏幕效果的第二层。我们可以通过在整个屏幕上覆盖一张纹理来获得这个效果。下面的图片演示了这一层看起来的样子,就是一张纹理: 灰尘和划痕(Dust and scratches): 第三层也是最后一层就是我们的老电影屏幕效果中的灰尘和划痕。这一层将使用两种不同的平铺纹理,一种作为划痕然后另一种作为灰尘。原因就是我们将根据时间以不同的速度对这两种纹理做动画。这将会产生一种效果,就是当电影在播放的时候同时在老电影的每一帧中都会有一些细小的划痕和灰尘。下图演示了它们的纹理看起来效果: 操作步骤 老电影屏幕效果的那些独特层级都很简单,但是将它们组合之后我们就能获得令人震惊的视觉效果。让我们缕一缕该怎么构建我们的脚本和着色器,之后我们就能逐行解析并且学习为什么可以那样写。此时,你应该有个设置好的屏幕效果系统而且能顺利运行,因为我们这个知识点不会涵盖如何设置这个系统。 1.我们将添加脚本代码。我们要输入的第一个代码块将定义我们的变量,这些变量会在 检查器 (Inspector) 上显示,好让这个效果的使用者可以可以用想填的数据修改它们。如我们还想在检查器上显示我们效果用到的那些我们处理好的Photoshop文件,也可以在此添加它们的引用。在脚本中添加下面的代码: #region Variables public Shader oldFilmShader; public float OldFilmEffectAmount = 1.0f; public float contrast = 3.0f; public float distortion = 0.2f; public float cubicDistortion = 0.6f; public float scale = 0....

April 20, 2023 · 5 min · 1010 words · Link

屏幕效果中的覆盖混合模式

屏幕效果中的覆盖混合模式 对于我们最后要讲的知识点,我们将会去了解另一种混合模式,覆盖混合模式。这种模式实际上是利用了一些条件声明,这些条件声明决定了每个通道上的每个像素的最终颜色。所以,在使用这种混合模式的过程中需要编写的代码会更多一些。接下来我们看看该如何实现它。 始前准备 对于最后这个屏幕特效,我们需要像前面两个知识点中那样设置两个脚本(一个C#, 一个shader)。对于这个知识点,我们将使用之前使用的场景,所以我们不必创建新的场景了: 1.分别创建一个名为 Overlay_ImageEffect 的C#脚本和一个名为 Overlay_Effect 的着色器脚本。 2.把上一个知识点中用的C#脚本代码复制到这个新的C#脚本中来。 3.将上一个知识点中使用的着色器代码复制到这个新的着色器代码中来。 4.将 Overlay_ImageEffect C#脚本挂载到主摄像机上(注意把之前的C#脚本先移除),然后在 检查器面板(Inspector) 中将 Overlay_Effect 着色器拖拽到C#脚本组件的着色器变量上。 5.然后分别双击C#脚本和着色器在代码编辑器上打开它们。 操作步骤 开始处理我们的覆盖屏幕效果,我们将需要完成着色器代码而且要运行起来没有错误。接下来我们就可以修改C#脚本用来给着色器发送正确的数据。 1.首先要做的是在着色器的 属性块(Properties block) 中添加需要的属性。我们将使用这一章前面几个知识点中一样的一些属性: Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _BlendTex ("Blend Texture", 2D) = "white" {} _Opacity ("Blend Opacity", Range(0, 1)) = 1 } 2.接下来我们需要在 CGPROGRAM 代码块之内添加与属性对应的变量: CGPROGRAM #pragma vertex vert_img #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" uniform sampler2D _MainTex; uniform sampler2D _BlendTex; fixed _Opacity; 3....

April 18, 2023 · 1 min · 176 words · Link

在屏幕效果中使用基础的类Photoshop混合模式

在屏幕效果中使用基础的类Photoshop混合模式 屏幕效果不仅仅只限于调整游戏中渲染纹理的颜色。我们还可以使用它将渲染纹理和其他的图像结合在一起。这个技术跟Photoshop中创建一个新的图层没有什么不同然后选择一种混合模式将两张图片混合在一起,当然在我们这里就是将一张纹理跟渲染纹理混合。这是一个非常强的技术,因为它提供给了艺术家一个在游戏中模拟混合模式的生产环境,而不不仅仅只是在Photoshop中。 对于这个特定的知识点,我们将会了解一些更加常用的混合模式,比如说 Multiply,Add 和 Overlay。你将会看到在游戏中拥有一个Photoshop中的混合模式的功能是多么的简单。 始前准备 开始前,我们需要准备资源。所以请跟着下面的步骤为我们新的 混合模式屏幕效果( Blend mode screen effect) 设置好我们的屏幕效果系统并且让它顺利运行起来: 1.创建一个新的C#脚本,并且为其命名为 BlendMode_ImageEffect 2.创建一个新的着色器,命名为 BlendMode_Effect 3.我们简单的将我们本章节第一个知识点中的C#脚本中的代码复制到我们这个新的C#脚本中来。这样我们就可以将精力放在混合模式效果实现的数学原理上。 4.同样,将本章节第一个知识点中的着色器代码赋值到我们这个新的着色器代码中来。 5.最后,我们需要一张额外的纹理来表现我们的混合模式效果。在这个知识点,我们将使用一张 粗旧类型纹理(grunge type texture)。它能让测试效果看起来非常明显。 操作步骤 我们第一个要实现的混合模式是Photoshop中的一样的 Multiply 混合模式。让我们先修改我们着色器中的代码。 1.在Unity的项目窗口中双击着色器,在代码编辑器中打开我们的着色器代码。 2.我们需要在属性块中添加一些新的属性好让我们可以有纹理可以混合并且要有一个 不透明度滑动条(a slider for an opacity value)。在你的着色器中输入下面的代码: Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _BlendTex ("Blend Texture", 2D) = "white" {} _Opacity ("Blend Opacity", Range(0, 1)) = 1 } 3.在 CGPROGRAM 代码块中添加与属性对应的变量好让我们可以访问 属性块(Properties block) 中的数据: CGPROGRAM #pragma vertex vert_img #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG....

April 16, 2023 · 2 min · 326 words · Link

在屏幕效果中使用亮度, 饱和度和对比度

在屏幕效果中使用亮度, 饱和度和对比度 现在我们有了自己的屏幕效果系统并且能正常运行,我们就可以去探索在当今的游戏当中更多涉及到像素操作的一些更常用的屏幕效果。 首先,使用屏幕效果来调节游戏整体的最终颜色效果,这肯定可以给艺术家对于游戏最终的样子,有一个全局的控制。比如可以用一些颜色滑动条用来调节游戏最终渲染结果的 R,G,B 颜色强度。又或者是给整个屏幕填充大量的某个颜色这样看起来就像是一种深褐色的胶片效果。 对于这个特殊的知识点,我们将会涵盖一些可以在图像上进行的更加核心的颜色修改操作。它们是 亮度(brightness), 饱和度(saturation) 和 对比度(contrast)。学习如何对这些颜色调整过程进行编码,将给我们学习屏幕的艺术效果一个很好的基础。 始前准备 这里我们需要创建一些新的资源。我们可以利用同样的场景作为我们的测试场景,但是我们需要一个新的脚本和着色器: 1.创建一个新的名为 BSC_ImageEffect 的脚本。 2.创建一个名为 BSC_Effect 的新着色器。 3.现在我们需要简单将前一个知识点中的脚本代码复制到现在这个新的脚本中来。这样的话可以让我们把重点放在亮度,饱和度和对比度的数学原理上。 4.把上一个知识点中的着色器代码复制到我们这个新的着色器中。 5.在场景中创建几个新的游戏对象,然后添加几个不同颜色的漫反射材质球,然后把这些材质球随机的添加给场景中这几个新的游戏对象。这将会给我们一个很好的颜色范围来测试我们的新屏幕效果。 当这些完成之后,你将会有一个类似于下图的游戏场景: uniform sampler2D _MainTex; fixed _BrightnessAmount; fixed _satAmount; fixed _conAmount; - 4.现在我们需要添加一些操作好用来表现我们的亮度,饱和度和对比度效果。在我们的着色器中添加下面的新函数,在 **frag()** 函数上面添加即可。不要担心它现在虽然还没啥用;我们将在下一个知识点中解释所有的代码: ```c# float3 ContrastSaturationBrightness(float3 color, float brt, float sat, float con) { float AvgLumR = 0.5; float AvgLumG = 0.5; float AvgLumB = 0.5; float LuminanceCoeff = float3(0.2125, 0.7154, 0.0721); float3 AvgLumin = float3(AvgLumR, AvgLumG, AvgLumB); float3 brtColor = color * brt; float intensityf = dot(brtColor, LuminanceCoeff); float3 intensity = float3(intensityf, intensityf, intensityf); float3 satColor = lerp(intensity, brtColor, sat); float3 conColor = lerp(AvgLumin, satColor, con); return conColor; } 5....

April 15, 2023 · 2 min · 262 words · Link