Unity Shader入门精要学习笔记:透明效果
透明效果 透明是游戏中经常要用的一种效果,在实时渲染中要实现透明效果,通常会在渲染模型时控制它的透明通道(Alpha Channel)。当开启透明混合后,当一个物体被渲染到屏幕上时,每个片元除了颜色值和深度值外,他还有另外一个属性——透明度。当透明度为1时。表示该像素是完全不透明的,而当其为0时,则表示改像素完全不会显示。 在Unity中,我们通常使用透明度测试(这种方法其实无法得到真正的的半透明效果)和透明度混合实现透明效果。 对于不透明物体,不考虑他们渲染顺序也能得到正确的排序效果,这是由于强大深度缓冲(depth buffer也被称为z-buffer)。 在实时渲染中,深度缓冲是用于解决可见性问题的,核心思想:根据深度缓冲中的值来判断该片元距离摄像机的距离,当渲染一个片元时,需要把它的深度值和已经存在与深度缓冲中的值进行比较(如果开启了深度测试),如果它的值距离摄像机更远,则不需要渲染到屏幕(有物体挡住了它),否则这个片元将会覆盖掉此时颜色缓冲中的像素值,并把它的深度值更新到深度缓冲中(如果开启深度写入)。 但是如果要实现透明效果,当使用透明度混合时,我们关闭了深度写入(Z...
Unity Shader基础篇:浅谈TEXCOORDn
事情的起因 今早起床,发现自己在知乎被邀请回答一个问题:(应该是这阵子逛的图形学区域比较多) TEXCOORD到底是个什么东西 我们来看看官方文档怎么说 TEXCOORD0 is the first UV coordinate, typically float2, float3 or float4. TEXCOORD1, TEXCOORD2 and TEXCOORD3 are the 2nd, 3rd and 4th UV coordinates, respectively. 看上去很简单,TEXCOORD是指纹理坐标,float2, float3, float4类型。n是指第几组纹理坐标。 第几组???能有几组uv??? 身为对美术一无所知的逻辑仔,我是不太明白的,在网上也没有找到好的答案,好在咨询了很多大佬,在此整理一下。 模型中每个顶点保存有uv,可能有一套或者几套,这些uv是指三维模型在2D平面的展开,跟纹理对应上进行插值采样就看到三维里的纹理颜色了 https://kumokyaku.github.io/2019/07/14/UNITY%E7%94%9F%E6%...
Unity Shader入门精要学习笔记:Unity中的基础光照
我们如何看待这个世界的 通常,我们要模拟真实的光照环境来生成一张图像,需要考虑三种物理现象。 首先,光纤从光源中被发射出来 然后,光线与场景中的一些物体相交,一些光线被物体吸收了,而另一些光线被散射到其他方向。 最后,摄像机吸收了一些光,产生了一张图像。 光源 在实时渲染中,我们通常把光源当成一个没有体积的点,用I表示他的方向。用辐照度来量化光。对于平行光,它的辐照度可通过计算在垂直于I的单位面积上单位时间内穿过的能量来得到。 在计算光照模型时,我们需要知道一个物体表面的辐照度,而物体表面往往是和I不垂直的,那么如何计算这样的表面辐照度呢?我们可以使用光源方向I与表面发现n之间的夹角余弦值来得到。默认方向矢量模为1. 吸收和散射 光线由光源发射出来后,就会与一些物体相交。通常相交结果有两个:散射和吸收 散射只改变光线方向,但不改变光线的密度和颜色。而吸收只改变光线的密度和颜色,但是不改变光线方向。 光线在物体表面经过散射后,有两种方向,一种会散射到物体内部,这种现象被称为折射或者透射。另一种会散射到外部,这种现象被称为反射。 为了区分这两种不同的散射方向,我们在光照模型中使...
Unity Shader入门精要学习笔记:让画面动起来
Unity Shader中的时间变量 动画效果往往都是把时间添加到一些变量的计算中,以便在时间变化时,画面也可以随之变化。Unity Shader提供了一系列关于时间的内置变量来允许我们方便地在Shader中访问运行时间。 纹理动画 序列帧动画 要播放帧动画,我们需要计算出每个时刻需要播放的关键帧在纹理中的位置。 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader "Unity Shaders Book/Chapter 11/Image Sequence Animation&quo...
Unity Shader入门精要学习笔记:学习Shader所需的数学基础
前言 由于此章节部分内容博主已经在计算机图形学中学习过,所以会少记录一部分,可以前往图形学:上和图形学:下查看 笛卡尔坐标系 二维笛卡尔坐标系 一个二维笛卡尔坐标系包含两个部分的信息 原点 两条过原点的互相垂直的矢量,即x轴和y轴,这些坐标轴也被称为是该坐标系的基矢量。 OpenGL和DirectX使用了不同的二维笛卡尔坐标系。 三维笛卡尔坐标系 在三维笛卡尔坐标系中,我们需要定义三个坐标轴和一个原点。 这三个坐标轴被称为该坐标系的基矢量。通常情况下,这三个坐标轴之间是互相垂直的,且长度为1,这样的基矢量被称为标准正交基。但这并不是必须的。如果不都为1,就是正交基。 左手坐标系和右手坐标系 两种坐标系无法通过旋转做到重合。 左右手坐标系转换方法是,把其中一个轴反转,并保持其他两个轴不变。 Unity使用的坐标系 Unity使用的是左手坐标系。(模型空间) 在观察空间中,Unity使用的是右手坐标系。以摄像机为原点的坐标系。 点和矢量 点是n维空间中的一个位置,他没有大小,宽度这类概念。 矢量是指n维空间中一种包含了模和方向的有向线段。 单位矢量可以用类似:$\widehat ...
Unity Shader入门精要学习笔记:更复杂的光照
更复杂的光照 Unity的渲染路径 Unity的渲染路径决定了光照是如何应用到Unity Shader中的。 Unity支持多种类型的渲染路径,主要有三种:前向渲染路径(Forward Rendering Path),延迟渲染路径(Deferred Rendering Path),顶点照明渲染路径(Vertex Lit Rendering Path)(在Unity 5.0后被抛弃)。 如果当前显卡不支持所选择的渲染路径,Unity就会自动使用更低一级的渲染路径。 通俗来讲,指定渲染路径是我们和Unity的底层渲染引擎的一次重要沟通。 如果不指定渲染路径,一些光照变量很可能不会被正确赋值。 前向渲染路径 前向渲染路径的原理 每进行一次完整的前向渲染,我们需要渲染该对象的渲染图元,并计算连个缓冲区的信息:颜色缓冲区和深度缓冲区。我们利用深度缓冲来决定一个片元是否可见,如果可见就更新颜色缓冲区的颜色值。 对于每个逐像素光源,我们都需要进行上面一次完整的渲染流程。如果一个物体在多个逐像素光源的影响区内,那么该物体就需要执行多个Pass,每个Pass计算一个逐像素光源的光照结果,然后在帧...
Unity Shader入门精要学习笔记:基于物理的渲染
引言 随着计算机的处理能力越来越强,人们开始考虑使用更加复杂的算法来渲染更加真实的画面。 在二十世纪八十年代左右, 基于物理的渲染技术(Physically Based Shading, PBS) 首次被引入图形学的正统研究中,学者们提出了使用光线追踪的方法来渲染全局光照,由此打开了精确渲染光线传播的大门。 在实时渲染领域, 人们也发现了这种基于物理的光照模型的巨大优势。 在这之前, Lambert光照模型、 Phong 光照模型和 Blinn-Phong 光照模型等经验模型占据了主流。 然而,这种不满足能量守恒的光照模型使得美术人员需要花费大量的时间在参数调节上。 尤其是, 美术人员往往好不容易为一个物体调节好了所有参数,使得它在当前的光照条件下看起来是满意的。然而, 一旦光照环境发生了变化, 这一切都得从头再来。 因此, 近年来游戏从业者开始着手把基于物理的光照模型应用于实时渲染中。 PBS的理论和数学基础 光是什么 在物理学中,光是一种电磁波。首先,光由太阳或其他光源中被发射出来,然后与场景中的对象相交,一些光线被吸收(absorption),而另一些则被散射(scatte...
Unity Shader入门精要学习笔记:屏幕后处理效果
建立一个基本的屏幕后处理脚本系统 屏幕后处理通常是在渲染完整个场景得到屏幕图像后,再对这个图像进行一系列操作,实现各种屏幕特效。例如景深(Depth of Field),运动模糊(Motion Blur)等。 要实现屏幕后处理的基础在于得到渲染后的屏幕图像。 123456/// <summary>/// 抓取屏幕图像/// </summary>/// <param name="src">Unity会把当前渲染的得到的图像存储在第一个参数对应的源渲染纹理中</param>/// <param name="dest">目标渲染纹理</param>MonoBehaviour.OnRenderImage (RenderTexture src, RenderTexture dest) 12345678910111213/// <summary>/// 完成对渲染纹理的处理/// </summary>/// <param name="sour...
Unity Shader入门精要学习笔记:基础纹理
前言 纹理最初的目的就是使用一张图片来控制模型的外观。 在美术人员建模的时候,通常会在建模软件中利用纹理展开技术,把纹理映射坐标存储在每个顶点上。纹理映射坐标定义了该顶点在纹理中对应的2D坐标。 通常这些坐标使用一个二维变量(u,v)来表示,其中u是横向坐标,而v是纵向坐标,因此纹理映射坐标也被称为UV坐标。 但顶点UV坐标的范围通常都被归一化到[0,1]范围内。纹理采样时使用的纹理坐标不一定是在[0,1]范围内。实际上,这种不在[0,1]范围内的纹理坐标又是会非常有用,与之关系紧密的是纹理的平铺模式,它将决定渲染引擎在遇到不在[0,1]范围内的纹理坐标时如何进行纹理采样。 单张纹理 我们通常会使用一张纹理来代替物体的漫反射颜色。 实践 我们使用Blinn-Phong光照模型来计算光照。 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787...
Unity Shader入门精要学习笔记:开始Unity Shader学习之旅
一个最简单的顶点/片元着色器 顶点/片元着色器的基本结构 123456789101112131415161718192021222324252627282930// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'shader "Unity Shader Book/Chapter 5/Simple Shader"{ SubShader { Pass { CGPROGRAM //表示vert函数是顶点着色器代码 #pragma vertex vert //表示fragment函数是片元着色器代码 #pragma fragment frag float4 vert(float4 v : PO...