unity3d 发光的线条_unity3d 外发光 - CSDN
  • 1、新建一个无光照着色器(Unlit Shader),重命名为“Unlit_wire” 2、修改其代码如下 Shader "PACKT/unlit_wireframe1" { Properties ... //线框着色器所需要的三个属性 ..., Color) = (0,0,0,0) //模型...

    1、新建一个无光照着色器(Unlit Shader),重命名为“Unlit_wire”

    2、修改其代码如下

    Shader "PACKT/unlit_wireframe1" {
    
    	Properties
    	{
    		//线框着色器所需要的三个属性
    		_Color("Color", Color) = (0,0,0,0) //模型的颜色
    		_EdgeColor("Edge Color", Color) = (0,1,0,1) //线框的颜色
    		_Width("Width", float) = 0.1 //线框的粗细
    	}
    	SubShader
    	{
    		//指定着色器以透明方式渲染
    		Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" }
    		LOD 100
            
            //第一遍绘制背面
    		Pass
    		{
    			//指定混合模式
    			//混合模式,即产生新颜色的方式,可用下面公式来表达
    			//新颜色 = 源颜色 * 源因数 + 目的颜色 * 目的因数
    			//SrcAlpha和OneMinusSrcAlpha的含义为使用源颜色中的alpha通道值作为源因数,用1减去alpha通道值作为目的因数
    			Blend SrcAlpha OneMinusSrcAlpha
    			//渲染模型背面
    			Cull Front
    			//AlphaTest令着色器只渲染Alpha通道大于一定值的像素,而将小于该值的像素直接丢弃
    			AlphaTest Greater 0.5 
    
    			CGPROGRAM
    			#pragma vertex vert  //顶点处理器函数vert
    			#pragma fragment frag  //片元处理器函数frag
    
    			uniform float4 _Color;
    			uniform float4 _EdgeColor;
    			uniform float _Width;
    
    			//定义了顶点处理器的输入数据
    			struct appdata
    			{
    				float4 vertex : POSITION; //顶点坐标
    				float4 texcoord1 : TEXCOORD0; //贴图的纹理坐标
    				float4 color : COLOR; //顶点颜色
    			};
    
    			//定义了由顶点处理器向片元处理器传送的数据
    			struct v2f
    			{
    				float4 pos : POSITION;
    				float4 texcoord1 : TEXCOORD0;
    				float4 color : COLOR;
    			};
    
    			//顶点处理器代码
    			//为模型的顶点计算正确的投影坐标,并且把顶点所对应的纹理坐标和颜色一起打包传送给片元处理器代码
    			v2f vert(appdata v)
    			{
    				v2f o;
    				o.pos = UnityObjectToClipPos(v.vertex);
    				o.texcoord1 = v.texcoord1;
    				o.color = v.color;
    				return o;
    			}
    
    			//片元处理器代码
                //最终为模型在画面中覆盖的像素计算颜色值
    			fixed4 frag(v2f i) : COLOR
    			{
    				fixed4 answer;
    
    				float lx = step(_Width, i.texcoord1.x);
    				float ly = step(_Width, i.texcoord1.y);
    				float hx = step(i.texcoord1.x, 1.0 - _Width);
    				float hy = step(i.texcoord1.y, 1.0 - _Width);
    
    				answer = lerp(_EdgeColor, _Color, lx*ly*hx*hy);
    
    				return answer;
    			}
    			ENDCG
    		}
    
    
            //第二遍绘制正面
    		Pass
    			{
    				Blend SrcAlpha OneMinusSrcAlpha
    				Cull Back
    				AlphaTest Greater 0.5
    
    				CGPROGRAM
                    #pragma vertex vert
                    #pragma fragment frag
    
    				uniform float4 _Color;
    			    uniform float4 _EdgeColor;
    			    uniform float _Width;
    
    			    struct appdata
    			    {
    				    float4 vertex : POSITION; 
    				    float4 texcoord1 : TEXCOORD0; 
    				    float4 color : COLOR; 
    			    };
    
    			    struct v2f
    			    {
    				    float4 pos : POSITION;
    				    float4 texcoord1 : TEXCOORD0;
    				    float4 color : COLOR;
    			    };
    
    			    v2f vert(appdata v)
    			    {
    				    v2f o;
    				    o.pos = UnityObjectToClipPos(v.vertex);
    				    o.texcoord1 = v.texcoord1;
    				    o.color = v.color;
    				    return o;
    			    }
    
    			    fixed4 frag(v2f i) : COLOR
    			    {
    				    fixed4 answer;
    
    			        float lx = step(_Width, i.texcoord1.x);
    			        float ly = step(_Width, i.texcoord1.y);
    			        float hx = step(i.texcoord1.x, 1.0 - _Width);
    			        float hy = step(i.texcoord1.y, 1.0 - _Width);
    
    			        answer = lerp(_EdgeColor, _Color, lx*ly*hx*hy);
    
    			        return answer;
    			    }
    				ENDCG
    			}
    	}
    	Fallback "Vertex Colored", 1
    }
    

    PS:对于透明渲染方式来说,必须先绘制距离摄像机较远的表面,后绘制较近的表面才能获得正确的透明结果。由于物体的背面一定比正面远,所以第一遍渲染必须先绘制背面。

    PS Again:此着色器更加接近底层的硬件着色器,若想更加深入了解硬件着色器可查找“可编程图形管线”的相关知识。

     

    展开全文
  • 可以实现边缘发光 注意设置好shader的等同于物体自身比例参数
  • unity发光描边shader

    2019-05-27 18:03:35
    Shader "Custom/Edge" { Properties { _MainTex("Texture", 2D) = "white" {} _OffsetUV("OffsetUV", Range(0, 0.005)) = 0 _EdgeColor("EdgeColor", Color) = (1, 0, 0, 1) _AlphaTreshold("Treshold", ...
    Shader "Custom/Edge"
    {
    Properties
    {
    _MainTex("Texture", 2D) = "white" {}
    _OffsetUV("OffsetUV", Range(0, 0.005)) = 0
    _EdgeColor("EdgeColor", Color) = (1, 0, 0, 1)
    _AlphaTreshold("Treshold", Range(0, 1)) = 0.5
    _EdgeWidth("EdgeWidth",Range(0,0.03)) = 0.003
    _EdgeColorPower("EdgeColorPower",Range(0,1))=1
    _EdgeStep("EdgeStep",Range(0,0.005)) = 0.001
    }
    SubShader
    {
    Tags{ "Queue" = "Transparent" }
    Blend SrcAlpha OneMinusSrcAlpha

    Pass
    {
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #include "UnityCG.cginc"

    struct appdata
    {
    float4 vertex : POSITION;
    fixed2 uv : TEXCOORD0;
    };

    struct v2f
    {
    float4 vertex : SV_POSITION;
    fixed2 uv[5] : TEXCOORD0;
    };

    sampler2D _MainTex;
    float4 _MainTex_ST;
    fixed _OffsetUV;
    fixed4 _EdgeColor;
    fixed _AlphaTreshold;
    fixed _EdgeWidth;
    fixed _EdgeColorPower;
    fixed _EdgeStep;

    struct CheckData
    {
    fixed alpha;
    bool isCanDraw;
    };

    v2f vert(appdata v)
    {
    v2f o;
    o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    o.uv[0] = v.uv;
    o.uv[1] = v.uv + fixed2(0, _OffsetUV); //up  
    o.uv[2] = v.uv + fixed2(-_OffsetUV, 0); //left  
    o.uv[3] = v.uv + fixed2(0, -_OffsetUV); //bottom  
    o.uv[4] = v.uv + fixed2(_OffsetUV, 0); //right 

    return o;
    }


    fixed check(fixed2 uv)
    {
    fixed alpha = 0;
    fixed step = _EdgeStep;
    fixed curStep = step;
    fixed4 fColor = tex2D(_MainTex, uv);
    fixed2 curUv = uv;
    if (fColor.a <= 0)
    {
    [unroll(20)] for (; curStep <= _EdgeWidth;)
    {
    curUv = uv + fixed2(0, curStep);
    fColor = tex2D(_MainTex, curUv);
    if (fColor.a <= 0)
    {
    curUv = uv + fixed2(-curStep, 0);
    fColor = tex2D(_MainTex, curUv);
    }
    else
    {
    break;
    }
    if (fColor.a <= 0)
    {
    curUv = uv + fixed2(0, -curStep);
    fColor = tex2D(_MainTex, curUv);
    }
    else
    {
    break;
    }
    if (fColor.a <= 0)
    {
    curUv = uv + fixed2(curStep, 0);
    fColor = tex2D(_MainTex, curUv);
    }
    else
    {
    break;
    }
    curStep += step;
    }
    }


    if (fColor.a > 0)
    {
    fixed dis = distance(uv, curUv);
    alpha = _EdgeColor.a*(1-dis/ _EdgeWidth);
    }
    return alpha;
    }

    fixed4 frag(v2f i) : SV_Target
    {
    fixed4 original = tex2D(_MainTex, i.uv[0]);
    fixed alpha = original.a;
    fixed p1 = tex2D(_MainTex, i.uv[1]).a;
    fixed p2 = tex2D(_MainTex, i.uv[2]).a;
    fixed p3 = tex2D(_MainTex, i.uv[3]).a;
    fixed p4 = tex2D(_MainTex, i.uv[4]).a;

    alpha = p1 + p2 + p3 + p4 + alpha;
    alpha /= 5;
    if (alpha <= _AlphaTreshold)
    {
    original.rgb = _EdgeColor.rgb+ _EdgeColorPower;
    original.a = check(i.uv[0]);
    }

    return original;
    }
    ENDCG
    }
    }
    }

    展开全文
  • 放到工程文件夹里面,让物体(gameObject)的材质(material)添加这个shader,就行。
  • Unity3d不久之前正式发布了Unity3d 2017.1, 这个版本的发布也宣告了Unity3d正式告别了5.x时代,并且开始已年份直接命名,开启了新的纪元。那么Unity3d 2017相较上一版本到底有哪些改进呢?这介绍这些改进之前先放出...

    Unity3d不久之前正式发布了Unity3d 2017.1, 这个版本的发布也宣告了Unity3d正式告别了5.x时代,并且开始已年份直接命名,开启了新的纪元。那么Unity3d 2017相较上一版本到底有哪些改进呢?

    这介绍这些改进之前先放出下载地址:Unity 2017.1
    有趣的是通过Unity产品蓝图我们可以发现Unity 2017.2 beta已经提供下载测试并且Unity 2017.3也已经在制作中了。
    这里写图片描述
    Unity 2017.2 beta下载地址:Unity 2017.2 beta

    以下关于Unity2017.1的介绍内容来自Unity官方中文社区,原帖地址:[官方] Unity 2017.1正式版发布

    Unity 2017.1中包含大量新功能与改进。主要内容如下:

    • 艺术家和设计师们:全新的叙事和游戏视频创作工具
      Unity 2017.1为艺术家和设计师们提供了全新的工具,使用Timeline,Cinemachine和Post-processing工具,可以创造令人惊叹的影视内容,合成精美相机镜头,描绘更好的视觉故事。
      Timeline是一款强大的可视化新工具,可用于创建影视内容,例如过场动画、预告片、游戏试玩视频等等。
      Cinemachine是一个高级相机系统,您可以像电影导演一样,在Unity中合成镜头,无需编写任何代码,引领您进入程序化摄影时代。
      Post-processing可以很方便地为场景应用各种逼真滤镜,使用电影工业级技术、控件和颜色空间格式来创造高质量视觉效果,让画面更生动、更逼真,助您描绘更好的视觉故事。
    • 效率:协作、实时操作分析、工具
      我们发布了Unity Teams,它由一系列简化创作者协作流程的功能和解决方案组成,包含Collaborate多人协作(现已发布)和Cloud Build云构建。
      实时操作分析系统引入了新的、更简单的方法,帮助您理解用户,并在不需要重新部署的情况下,对游戏做出动态的反应和调整。
      最重要的是,Unity 2017.1对编辑器进行了大量更新,包括对FBX导入、动画工作流程、2D功能、Asset Bundle工作流和Visual Studio集成的改进。
    • 图形与平台:全面改进
      Unity 2017.1对粒子系统和Progressive Lightmapper进行了大量改进,提供了更多选择来实现您的艺术愿景并控制性能。不同平台可采用不同的渲染品质,例如iOS平台上的Deferred Rendering,和PC上的NVIDIA VRWorks。
      这些都只是Unity 2017.1的亮点概念,下面将介绍完整丰富的细节内容!

    Unity 2017.1新看点

    艺术家叙事工具: Timeline和Cinemachine介绍

    设计师、艺术家或动画师们可以使用新的集成叙事工具,自己制作影视内容和游戏视频,而不用依赖程序员。这意味着开发效率更高,而节约沟通与排队成本。

    Timeline是一款强大的可视化新工具,可用于创建影视内容(例如短片Adam)。通过编排游戏对象、动画、声音和场景,来创建过场动画、游戏视频等等。有了Timeline,您可以专注于叙事和电影艺术创作,而非编码。

    Timeline基于轨道的序列工具,使用“拖放”操作来编排动画、声音、事件、视频等元素,以更快地创建漂亮的过场动画和程序化内容。Timeline有许多功能,例如动画、音频、自动关键帧,以及可以锁定或静音特定轨道的多轨道界面。Timeline可通过Playable API进行扩展,支持创建自定义轨道,来驱动游戏中的任意系统。您可以制作一个Timeline剪辑来表示几乎所有内容——并且可以重复播放、缩放和混合这些剪辑,所有这些都可在Timeline中实现。
    这里写图片描述

    Cinemachine 是多年游戏和电影摄像机的构建经验凝聚而成的结晶。现在,它将业界领先的摄像操作置于所有人手中,引领了程序化摄影的时代。

    这是一套智能摄像机,可以动态的根据场景组成和交互,在最佳时间拍摄最佳镜头。使您摆脱无尽的手工动画、摄像机编程以及修订的过程。

    Cinemachine可以在Asset Store资源商店中下载,现在就添加到您的项目中。

    从第一人称射击游戏到第三人称动作冒险,您可以用Cinemachine彻底改变游戏内摄像机。很容易地:

    • 像电影导演那样,使用高级摄像机工具及真实的摄像机设置,来控制视频序列。
    • 合成镜头,把重点放在艺术方向上,而非实现细节。给Cinemachine智能摄像机一个简单的指示,比如跟随人物的头部,如果动画发生变化,镜头会自动更新并继续正常工作。
      这里写图片描述

      在Unity 2017.1中,我们为Cinemachine增加了很多新功能,比如:

    • 多个目标对象:以多个对象为目标,并设置它们的权重。它基于任意数量的对象创建一个逻辑组,根据其成员的位置来定位自己。在跟踪一组对象时,可以将其用作LookAt和Follow方法的目标。对2D场景也非常适用。
    • 动态取景多个对象:该功能将基于对象的位置自动取景一组目标。如果对象散开,Cinemachine将根据您创建的一套规则调整FOV或推拉(或两者同时进行)
    • 全新开放API:轻松定制Cinemachine配置,获得项目需要的摄像机行为。
    • 推拉轨道:创造出像电影一样的推拉镜头,让摄像机在游戏世界里平滑移动。适合于电影序列,或当您希望摄像机沿着一组轨道跟踪拍摄对象时。
    • 安全镜头:安全镜头会根据镜头优先级与质量,动态选择最佳的摄像机。有东西进了取景框,破坏了镜头?没问题,Cinemachine会切换到下一个最佳摄像机。尤其适用于回放或任何一个可变场景的电影序列。

    Timeline和Cinemachine结合使用,您可以将叙事带入更高的层次。使用后处理栈来进一步创建特效,烘托场景氛围和戏剧效果。
    这里写图片描述

    改进Post-processing栈(测试)

    Post-processing将全屏滤镜和特效应用于摄像机的图像缓冲区,然后再将其显示在屏幕上。您可以使用图像后处理特效来模拟物理摄像机和电影效果。

    最新版的Post-processing栈测试版可以在此下载。最终版预计将于今年夏季发布。(注意:上一个稳定版本可以在Asset Store资源商店中下载)

    改进后的后处理栈将一组完整的图像效果整合到单个后期处理流程中,并带有一系列高质量的摄像机效果:

    • Screen-space anti-aliasing
    • Auto Exposure
    • Motion Blur
    • Bokeh Depth of Field
    • Bloom
    • Color Grading
    • Chromatic Aberration
    • Film Grain
    • Vignette

    您可以将多个特效组合到单个Pass中,使用基于Asset的预设配置系统管理特效也非常轻松。

    颜色分级效果是一种支持Academy Color Encoding System (ACES)的全HDR颜色管线,低端平台可以使用LDR管线。该栈有两个屏幕空间的光照特效,即环境光遮蔽和屏幕空间反射。

    这个新版本还提供了一个基于体积的混合特性,您可以在场景中定义区域(任何类型的网格),并在玩家进入区域时设置特定的氛围/外观。Unity会自动在体积之间进行混合,以实现流畅的外观转换。
    这里写图片描述

    Unity Collaborate多人协作已正式发布!现为Unity Teams一员

    Unity Collaborate多人协作已结束测试,与Cloud Build云构建一起成为Unity Teams的一部分,仅用一个解决方案一套功能,即可帮助您更快速地进行团队协作。Unity Teams将可免费使用至2017年10月。

    点击了解有关Unity Teams的更多内容。

    对于Collaborate多人协作,我们在Unity 2017.1中发布的首个发布版本优先处理了Beta用户提供的反馈。除了性能改进、稳定性和Bug修复之外,我们还增加了一组新功能:选择性推送、更佳的Asset浏览器集成和一个新的“In Progress”功能,用以标志团队成员在某个场景或预制件上有未发布的本地更改。
    这里写图片描述

    以下是我们为Collaborate多人协作添加的一些新功能:

    • In Progress标志
      为场景和预制件添加了In Progress标志,以指示团队中其他人已对某个场景或预制件做出了一些未发布的本地更改。这个特性有助于协作者协调对场景和预制件的更改。
      这里写图片描述
      这里写图片描述

    • 右键单击选择发布
      我们添加了右键单击操作,现在您可以在项目浏览器中直接发布、恢复、查看差异,解决文件冲突。这是一个主要的用户痛点源头,我们希望使Collaborate的行为与其他项目浏览器的行为更加一致。请注意,这种UX允许您选择性地发布已更改的Asset。之前的版本中,您必须发布所有更改。
      这里写图片描述

    • 浏览体验更佳
      在项目浏览器的“收藏”中添加了新的过滤器,包括“所有修改”、“所有被排除”和“所有冲突”,这样用户就可以看到他们所有修改过的文件、所有正在修改的文件、带有冲突的文件和忽略的文件。特别要留意的是“All in Progress(一切都在进行中)”,这让您可以实时看到Collaborate团队中的其他人正在处理哪些Asset(稍后将详细介绍)。
      这里写图片描述

    • 实时操作分析
      Unity 2017.1可以通过数据驱动的实时操作,随时获得丰富的分析数据。深入了解您的用户与您作品的互动情况,并实时做出相应的调整,迎合他们的习惯,无需重新部署新版本。在Unity 2017中,您可以更好地为用户提供更佳的游戏体验。
      通过Standard Events (目前是Beta版)可以进行更高效的洞察,它提供了一组精心设计的预定义事件,可揭示与您游戏相关的重要信息。使用新的Analytics Event Tracker,无需代码即可实现这些功能。
      这里写图片描述
      使用Remote Settings特性,可以即时更改游戏,无需重新部署,该特性已添加到Unity Analytics分析服务中。
      这里写图片描述

    • 2D改进
      在Unity 5.6中,我们为2D游戏开发者对工具和工作流程进行了重大改进。Unity 2017.1中引入了2D Sprite Atlas,这是一种新的Asset,将取代Sprite Packer。随着它的出现,新改进的工作流程可以在运行时更好地控制精灵的打包和使用。图集是Unity中2D工作流程的重要组成部分,而精灵图集不仅提供了更简单的图集创建和管理方式,还有相应的脚本API,可获得更多的控制和用途。
      这里写图片描述
      Sprite Masks用于在世界空间中隐藏或显示精灵或精灵组的一部分。精灵遮罩仅对拥有Sprite Renderer组件或粒子系统的对象生效。
      这里写图片描述
      在Unity 2017.1中,我们还为精灵编辑器添加了精灵物理形状。可以为精灵设置自定义的默认形状,以使用PolygonCollider2D生成碰撞器形状。

    • 动画改进
      我们对Animation窗口进行了全面修改,改进了关键帧的工作流程,使动画制作更方便和熟练,并支持与Animator状态机进行交互。Performance Recording是一个实验性功能。
      新的关键帧工作流程支持明确指定何时将哪帧变为关键帧,并在重新评估/预览动画时,将所有未修改且未关键帧化的属性值都丢弃。我们已经改变了在Animation窗口中编辑剪辑的默认行为(新的默认预览模式)、视觉反馈和全局关键帧操作热键。这些变化的目的是在Animation窗口之外为关键帧操作提供一个流畅的工作流程,同时预览动画剪辑无需处于自动关键帧或录制模式下。
      现在在编辑器中可以对状态机行为进行调试。
      我们还引入了GameObjectRecorder,这是一个新的实验性编辑器特性,它允许您记录GameObject和它子对象上的任何属性。这样就可以轻松地创建动画,将被记录的所有内容保存到一个动画剪辑中。欢迎访问论坛进行反馈。
      这里写图片描述

    • Playables已正式发布
      Playables API通过使用树状结构的PlayableGraph组织和评估数据来源,提供一种创建工具、特效或其他游戏机制的方法。PlayableGraph允许您混合和修改多个数据源,合成为单一输出后播放。
      Playables API支持动画、音频和脚本。Playables API还提供了通过脚本来与动画系统和音频系统进行交互的能力。
      Playable API是一个通用API,它最终将用于视频和其他系统。查看文档了解更多细节。

    • Ambisonic音频
      在Unity 2017.1中,我们增加了对环绕立体声音频剪辑的支持,这是全方位环绕音频技术,它(除了水平面外)还覆盖了听众上方和下方的声源。
      Ambisonics以多声道格式储存。它不是将每个通道都映射到一个特定的扬声器,而是以一种更通用的方式来表示声场。然后,根据聆听者的方向(即XR中用户的头部旋转),旋转声场。声场也可以被解码成一种与扬声器设置相匹配的格式。Ambisonics通常与360度视频结合使用,也可以用作音频天空盒,表现遥远的环境声音。
      我们还添加了Ambisonic解码器插件,而且现在也可以使用正开发中的API,在新的叙事工具Timeline中使用音频剪辑了。

    • 编辑器改进
      我们在UnityEditor.IMGUI.Controls中添加了一个新的ArcHandle类,它可以在场景视图中交互式地编辑弧线。还加入了名为SearchField的新IMGUI控件,它带有普通和工具栏用户界面风格,但也可以自行定制。
      这里写图片描述
      现在还支持使用JetBrains Rider作为外部脚本编辑器。
      其他改进还包括对所有播放器循环阶段添加分析器标签,改进Package Export加载状态,以及记录已连接玩家的日志信息,这些都将出现在编辑器控制台中,使调试更加轻松。

    • 改进了对Visual Studio的支持,包括Mac OS
      Unity安装程序现在可以选择在Windows上安装Visual Studio Community 2017(而非Visual Studio Community 2015)。安装速度显著提高也更轻量。
      Mac用户也别难过,现在可以使用Visual Studio了!微软发布了Mac版的Visual Studio和Tools for Unity。Visual Studio for Mac还提供了许多很酷的功能:一键调试,Unity消息的IntelliSense(完整Unity特定库代码),着色器代码高亮显示等等(点此查看详情)。

    • 场景与Asset Bundle改进
      我们对游戏中的场景和Asset Bundle进行了一些改进。更改底层架构使场景和Asset Bundle加载速度更快,从而使玩家体验更加流畅。我们还创建了一个工具,Asset Bundle浏览器——以帮助创建和优化Asset Bundle。

    • Asset Bundle浏览器
      Asset Bundle浏览器的Beta版与Unity 2017.1一同发布。该工具允许您在Unity项目中查看和编辑Asset Bundle的配置。它的目的是替换当前选择Asset的工作流,并在检视窗口中手动设置Asset Bundle的工作流程。现在您可以集中查看所有的Asset Bundle配置。通过使用上下文菜单和拖放功能,配置、修改和分析相关资源包。
      该工具将标记可能值得关注的警告,并提示将中断资源包创建的错误。从上层查看包集合,您可以更有效地组织Asset Bundle。在更低层查看单个Asset Bundle,您可以看到由于显式包含或依赖项的关系,哪些内容将会放入包中。
      更多细节请查阅文档
      这里写图片描述
      Asset Bundle浏览器可以从Asset Store资源商店下载。

    • 脚本运行时升级(实验性):畅享 C# 6和.NET 4.6
      在Unity 2017.1中,我们引入了实验性版本的脚本运行时内核,该内核已升级到Mono/.NET 4.6运行时。它包含了许多修复、性能改进,可以使用C# 6。我们相信它会提高游戏的整体性能。
      可以在Player Settings中启用.NET 4.6:
      这里写图片描述
      注意,更改该设置会在重启编辑器后生效,因为它会影响编辑器和播放器。对应的脚本API是PlayerSettings.scriptingRuntimeVersion属性。
      IL2CPP完全支持新的.NET 4.6 API,因此您仍可使用C#编写脚本,同时享有原生C++的性能优势。如果您发现任何问题,请访问论坛进行反馈。

    • 模型导入器改进
      从像Maya这样流行的数字内容创作(DCC)工具导入Asset的过程是首批重要的改进对象,这使得DCC工作流程变得更加轻松。最终提高了艺术家和设计师的生产力,减少了程序员的麻烦。
      现在Unity导入从Maya导出的FBX文件已支持Segment Scale Compensation,而且FBX SDK已升级至2016.1.2。
      在导入FBX文件时,我们还添加了计算加权法线的选项,如按面积、角度或二者皆有,以及硬边缘的固定法线生成。现在,可以从FBX文件中导入灯光和摄像机,Unity会自动在需要时为对象添加和配置摄像机和/或灯光组件。
      Unity现在可以使用“Import Visibility”属性从FBX文件中读取可见性属性。值和动画曲线将启用或禁用MeshRenderer组件:
      这里写图片描述

    • Progressive Lightmapper改进
      Unity 2017.1增加了Progressive Lightmapper中对烘焙LOD的支持。在烘焙LOD时,Enlighten和Progressive Lightmapper之间的主要区别在于,使用Progressive Lightmapper不必在LOD周围放置光照探针来获得反射光。在完全烘焙分辨率下,间接光照将为LOD提供更优质的烘焙光照贴图,您也可以避免为它们设置光照探针的繁琐过程。(Unity 5.6中也有此功能。)
      我们还在Progressive Lightmapper中增加了对双面材质的支持,通过添加新的材质设置,使光线与背面接触。启用后,在进行全局光照计算时几何体的两面都被包括在内。当从其他对象观察时,背面不会被认定为无效。背面渲染既不受该设置的控制,也不会在光照贴图中显示。背面使用与正面相同的自发光和漫反射设置反射光线。(该功能也可在Unity 5.6中使用)
      这里写图片描述

    • 实时阴影改进
      我们优化了在稳定模式下,级联定向光源阴影投射器的选择。这意味着生成阴影贴图时会产生更少的Draw Call。这增益是与场景和配置相关的。例如,在四个级联光的情况下,可以看到Draw Call数量显著下降。根据太阳/摄像机的方向,场景中可以减少50%的阴影投射器。下面是维京村庄的一个例子:
      下面的场景在Unity 5.6中有5718个阴影投射器。
      这里写图片描述
      在Unity 2017.1中,相同的场景,只有4807个阴影投射器。
      这里写图片描述
      Unity 2017.1还实现了实时阴影的Percentage Closer Filtering (PCF)。每个像素的深度值都是从当前像素周围的阴影贴图中取样,并所有的采样值进行比较。这使得光和影之间的线条更加平滑。您可以在下图中看到对比:
      这里写图片描述
      除了实时阴影改进,Shadowmask和Distance Shadowmask光照模式现在已成为Quality Setting中的参数,可以在运行时进行修改而无需任何成本。例如,可以在室内使用Shadowmask (实现柔和的阴影),并在相同关卡中的户外场景切换至distance Shadowmask。它也可以作为一个质量设置项。
      我们还添加了Custom Render纹理作为渲染纹理的扩展,可以很方便地用着色器来更新纹理。这有助于实现各种复杂的模拟,比如焦散光、雨滴涟漪模拟,墙面液体喷溅等等。它还提供了一个脚本和着色器框架,以便进行更复杂的配置,比如局部或多阶段更新,不同的更新频率等等。
      这里写图片描述
      有了新添加的LineUtility类和LineRenderer.Simplify函数,现在可以优化线条,用LineUtility创建由简单形状组成的简化版本。
      使用Metal/OpenGL ES3实现iOS上的Deferred Rendering
      我们为A8芯片和以后的iOS设备启用了一个使用Metal和OpenGL ES 3.0的延迟渲染路径。当使用延迟着色时,能够影响GameObject的灯光数量是没有限制的。所有的灯光都是按像素计算的,这意味着它们都能与法线贴图进行正确的交互等等。此外,所有的灯光都可以有剪影和阴影。

    • 粒子系统改进
      我们引入了精灵集成,粒子碰撞力(可以推动碰撞器),大量形状方面的改进,包括一个新的形状类型,噪音模块增加了新选项,以及其他一些较小的特性和增强。因为增加了新的控制和约束,例如速度与对齐,使得在2D中使用粒子更加轻松。可以使用粒子来获得比以往更多的特效和动画效果,包括光线的线条和尾迹。
      通过Texture Sheet Animation模块,我们在粒子系统中增加了对精灵使用的支持。这使粒子系统能更好地进行了图集处理和批处理,同时也在粒子系统中增加了大量与精灵相关的特性,例如不同大小的动画帧,以及每帧的轴心点。
      这里写图片描述
      这里写图片描述
      噪音模块提供了新的选项,可以更好地将噪音应用于粒子效果中。这个功能在Unity 5.5中第一次实现,噪音是被应用到粒子的位置属性。在2017.1中,我们可以将噪音应用到更多的地方:
      -位置
      -旋转
      -大小
      -使用Custom Vertex Streams的着色器(非常适合制作UV失真效果!)
      这里写图片描述
      在粒子系统形状模块的碰撞模式中,我们引入了一个新的甜甜圈粒子发射形状和编辑模式。模块内的Transform可以为粒子发射的形状应用自定义位置、旋转和缩放。
      其他的改进还包括将粒子与速度方向对齐的能力,以及允许在局部空间系统使用Emit over Distance。边缘粒子发射现在更加灵活,可以选择用来产生粒子的边缘厚度。
      粒子现在也可以使用碰撞模块对碰撞器进行施力。
      这里写图片描述

    • Windows Store现在改名为Universal Windows Platform
      Unity现在支持Windows商店的Universal Windows Platform(UWP)应用模式,支持为Xbox One、Windows 10、Windows Phone 10和HoloLens进行构建。
      请注意,对Windows混合现实PC设备的支持将在今年晚些时候发布。
      这里写图片描述
      我们增加了对UWP的多显示支持,现在Unity播放器二进制文件已做数字签名,增加了额外的一层安全性,可以防止对Unity运行时二进制文件进行篡改。
      最后,我们取消了对Windows 8.1和Windows Phone 8.1应用的支持,Unity 5.6是最后一个支持这两个平台的版本。

    • 索尼PS4的视频播放器
      我们在Unity 5.6中引入了一个全新的视频播放器,在Unity 2017.1中正式加入了对索尼PS4的支持,从而完成了对跨平台的支持。PS4的视频播放器使用索尼的AvPlayer库来加速h.264流的解码。解码h.264流(PS4的推荐格式)时,CPU开销非常低。可以同时对最多8个并发h.264流进行解码。它还支持对webm容器中的VP8格式流进行软件解码(更高的CPU开销)。最后,它支持多种视频渲染模式(直接渲染到摄像机的近/远平面,作为材质覆盖,或渲染纹理),音频流可以直接输出或发送到音频源进行混合。

    • 底层原生插件渲染扩展
      我们已经扩展了底层渲染插件API,并提供了一些很酷的新特性:
      -现在可以将用户数据发送到回调函数。
      -我们已经扩展了插件将接收回调的可能事件列表。
      -我们在着色器编译器进程中添加了钩子,可以在发送到编译器之前对着色器打补丁。支持创建自定义关键字所控制的自定义变体。
      -要想了解这些扩展的威力,请查看NVIDIA的VRWorks包,它是实现这一切的基石。

    • VR: NVIDIA VRWorks
      现在,在Unity 2017.1中,NVIDIA VRWorks通过以下特性,为虚拟现实提供了一种全新高度的视觉保真度、性能和响应能力:
      -Multi-Res Shading是一种用于VR的创新性渲染技术,它可以使图像的每一部分都能渲染在一个与镜头矫正图像像素密度相匹配的分辨率上。
      -Lens Matched Shading使用NVIDIA基于Pascal的GPU的新Simultaneous Multi-Projection架构,为像素着色提供潜在的性能改进。
      -Single Pass Stereo使用NVIDIA基于Pascal的GPU的新Simultaneous Multi-Projection架构,仅对几何体进行一次绘制,即可在双眼视图同时投射相同几何体。
      -VR SLI为虚拟现实应用程序提供更高的性能,其中两个GPU可以被指派给特定眼睛,极大地加速立体渲染。
      这里写图片描述
      为了更好地利用这些改进,应该在PC上使用GeForce 9系列或更高的GPU来进行回放。可以访问Asset Store资源商店下载NVIDIA VRWorks for Unity

    • 发布说明
      与往常一样,请查阅发布说明,以了解新特性、改进和修复的完整列表。

    以上内容来源Unity官方中文社区,原帖地址:http://forum.china.unity3d.com/thread-25171-1-1.html
    本文仅做转载和整理。

    by:蒋志杰

    展开全文
  • Unity3d轻量渲染管线(LWRP)民间文档

    万次阅读 2019-02-23 17:31:12
    近日在学习Unity3d的SRP,由于官方未正式发布,故几乎没有文档支持,考虑到官方一贯的风格,即使正式发布了,估计Shader部分也不会有详尽的文档。所以,干脆自己在研究学习源码之余,写了一份文档,既加深自己的理解...

    近日在学习Unity3d的SRP,由于官方未正式发布,故几乎没有文档支持,考虑到官方一贯的风格,即使正式发布了,估计Shader部分也不会有详尽的文档。所以,干脆自己在研究学习源码之余,写了一份文档,既加深自己的理解,也方便后继的学习者。目前只完成了轻量管线部分的文档,先发布初版,欢迎指正。后续还有Core库、高清管线和ShaderGraph的文档正在编写中。

    Runtime

    LightweightPipelineAsset.cs

    管线描述文件,继承自RenderPipelineAsset,是渲染管线的主入口,通过在GraphicsSettings中指定Scriptable Render Pipeline Settings接入引擎主体渲染框架。

    s_SearchPathProject = "Assets"

    定义了工程默认搜索路径,会优先从这个目录搜寻管线内建资源清单。

    s_SearchPathPackage = "Packages/com.unity.render-pipelines.lightweight"

    定义了Package默认搜索路径,如果工程路径中没有找到,会从这里搜寻管线内建资源清单。

    CreateLightweightPipeline

    创建管线描述文件自身。

    CreateLightweightPipelineResources

    创建管线内建资源清单文件。

    CreateLightweightPipelineEditorResources

    创建编辑器用管线内建资源清单文件。

    CreateLightweightPipelineAsset

    管线资源文件改名功能。

    InternalCreatePipeline

    内部用创建轻量管线。

    GetMaterial

    获取材质。

    GetDefaultMaterial

    获得默认的材质。

    GetDefaultParticleMaterial

    获得默认的粒子材质。

    GetDefaultLineMaterial

    获得默认的线条材质。

    GetDefaultTerrainMaterial

    获得默认的地形材质。

    GetDefaultUIMaterial

    获得默认的界面材质。

    GetDefaultUIOverdrawMaterial

    获得默认的界面过绘制材质。

    GetDefaultUIETC1SupportedMaterial

    获得默认的界面ETC1兼容材质。

    GetDefault2DMaterial

    获得默认的2D材质。

    GetDefaultShader

    获得默认的Shader

    LightweightPipelineEditorResources.cs

    编辑器用管线内建资源清单文件

    DefaultMaterial

    默认材质

    DefaultParticleMaterial

    默认粒子材质

    DefaultTerrainMaterial

    默认地形材质

    LightweightPipelineResources.cs

    管线内建资源清单文件

    BlitShader

    全屏拷贝用Shader

    CopyDepthShader

    拷贝深度用Shader

    ScreenSpaceShadowShader

    屏幕空间阴影Shader

    SamplingShader

    采样Shader

    以下以Pass结尾的均为渲染步骤

    架构上极度类似我们RenderStep的设计,用一个List对这些步骤进行一定自由度的排列组合,在执行每个相机的渲染时,依次调用该列表中所有渲染步骤的Execute接口。

    BeginXRRenderingPass.cs

    开始XX现实多眼睛渲染。

    CopyColorPass.cs

    色彩拷贝渲染过程。在渲染过非透明物体以及非透明物体的屏幕后处理效果之后,把当前的颜色缓存保存到额外的一个RT中,“_CameraOpaqueTexture”。这里拷贝出的颜色缓冲的值根据配置可能执行不同程度的降采样或者多重采样。目的可能是为了方便后处理的某些方法进行优化。

    CopyDepthPass.cs

    深度拷贝渲染过程。在渲染过非透明物体以及非透明物体的屏幕后处理效果之后,透明物体之前,把当前的深度缓存保存到额外的一个RT中,“_CameraDepthTexture”。不同于DepthOnlyPass.cs只进行一次采样,这里会根据MSAA渲染设置,进行多重采样。

    CreateLightweightRenderTexturesPass.cs

    创建轻量渲染纹理。根据渲染配置是否需要额外的颜色缓冲或者深度缓冲,决定是否创建新的渲染纹理。

    DepthOnlyPass.cs

    仅渲染深度。深度信息提前处理,把深度信息填入单独的RT中,shader引用名称为“_CameraDepthTexture”。后面渲染非透明物体时的深度信息填入”_CameraDepthAttachment”或者最终的相机的深度缓存中。这里对深度缓冲不进行MSAA,只执行一次标准的采样。调用物体Shader里的LightMode:“DepthOnly”进行渲染。

    这里指定的排序标记是SortFlags.CommonOpaque,这将告诉Unity按照从近到远的顺序来排序这些可见的渲染物体(Renderers),从而起到减少重复绘制(OverDraw)的作用。在默认的最简渲染流程下,这个Pass是不执行的,而当诸如全屏后处理等特性被启用时,这个Pass会被加入渲染流程中,导致DrawCall倍增。

    DirectionalShadowsPass.cs

    渲染方向光产生的级联阴影,仅支持一个主光源产生阴影,其它光源根本不会被处理。点光源和区域光源不会产生任何阴影。生成平行光的阴影贴图,把shadowmap保存到“_DirectionalShadowmapTexture”里。调用物体Shader里的LightMode:“ShadowCaster”进行渲染。

    DrawSkyboxPass.cs

    绘制天空盒。轻量管线中天空盒并不像通常认为的在所有物体之前渲染,而是在非透明物体之后才渲染,目的应该是为了可以使用提前的深度测试降低overdraw。

    EndXRRenderingPass.cs

    结束XX现实多眼睛渲染。

    FinalBlitPass.cs

    使用Blit shader执行一次渲染纹理拷贝。在渲染流程的最后如果没有开启透明物体的后处理并且当前的颜色缓冲对象不是管线最终的颜色缓冲区,则执行拷贝把当前颜色缓冲复制到管线最终输出的颜色缓冲区。

    ForwardLitPass.cs

    空文件,没有代码。

    LightweightForwardPass.cs

    轻量的前向渲染,重定义了出错情况下的显示用shader,但是依然是用的内建shader。

    RenderObjectsWithError,如果检测到Shader使用了Unity旧有内置管线中的LightMode,包括Always、ForwardBase、PrepassBase、Vertex、VertexMRGBM、VertexLM都会用默认的ErrorMaterial(紫色)进行显示,表示这些内置管线用的LightMode在轻量管线中是不支持的,不可以使用。如果指定了轻量管线专用的LightMode,但Shader编译错误,也会用默认的ErrorMaterial(紫色)进行显示。

    errorSettings.SetShaderPassName(i, m_LegacyShaderPassNames[i]);//标识当前渲染使用的LightMode的名称。

    errorSettings.SetOverrideMaterial(m_ErrorMaterial, 0);//标识使用改材质的第一个pass覆盖掉当前渲染设置指定的pass。

    如果Pass指定了不能识别的LightMode,则该物体不会被渲染,也没有错误信息,遇到有模型没渲出来,可能就是LightMode指定错了。

    如果Pass未指定LightMode,Unity会自动将其设置为SRPDefaultUnlit,由于CSharp脚本中注册了SRPDefaultUnlit这种LightMode,所以这个Pass也会被渲染出来。如果手动注释掉对SRPDefaultUnlit注册的代码,那么这个Pass就不会被渲染。

    LocalShadowsPass.cs

    渲染聚光灯产生的阴影,光源类型仅支持聚光灯,光源数量未有限制。点光源和区域光源不会产生任何阴影。

    非烘焙(Realtime/Mixed)聚光灯光源数目目前限制为4个。这里的设置不合理,既然是处理阴影,应该是设置可以投射阴影的聚光灯光源数目不超过某个限制,而不是直接限制所有光源数目。推测应该是写错了,实际应该用产生阴影的灯光数量进行断言。调用物体shader里的LightMode:”ShadowCaster”进行渲染。

    实测,8个聚光灯,其中4个产生阴影,4个不产生阴影,修改Assert后能够正常工作。

    对第152行进行如上图所示的修改,工作正常。从代码逻辑的角度看,这个写法也是不合理的,在执行0~ localLightsCount的循环过程中,去断言循环次数上限不大于4,怎么看都是不正确的逻辑。

    OpaquePostProcessPass.cs

    不透明的后处理,由于渲染步骤的关系,此时仅不透明物体被渲染完毕,故此时所做的后处理仅对不透明物体有效。

    RenderOpaqueForwardPass.cs

    前向渲染不透明物体,继承自LightweightForwardPass,如果没有在这个Pass中正确执行渲染操作,就不会显示任何不透明物体。

    这里指定的排序标记是SortFlags.CommonOpaque,这将告诉Unity按照从近到远的顺序来排序这些可见的渲染物体(Renderers),从而起到减少重复绘制(OverDraw)的作用。

    RenderTransparentForwardPass.cs

    前向渲染半透明物体,继承自LightweightForwardPass,如果没有在这个Pass中正确执行渲染操作,就不会显示任何半透明物体。

    这里指定的排序标记是SortFlags.CommonTransparent,这将告诉Unity按照从远到近(画家算法)的顺序来排序这些可见的渲染物体(Renderers),从而正确混合半透明物体和其后的物体的颜色。

    SceneViewDepthCopyPass.cs

    编辑器模式下Scene视图的深度拷贝。

    ScreenSpaceShadowResolvePass.cs

    屏幕空间的阴影处理。

    ScriptableRenderPass.cs

    所有渲染步骤的基类,定义了Execute接口,提供了基础的设置功能和设置渲染纹理的功能。为派生类提供了注册使用的渲染通道的功能RegisterShaderPassName,用来指定使用shader里的哪个pass进行渲染。

    SetupForwardRenderingPass.cs

    设置前向渲染的基本摄像机参数,后续Shader用到的各种变换矩阵等一些通用参数。

    SetupLightweightConstanstPass.cs(这个Constanst不是我拼错的,源码里就是这样)

    设置灯光相关的基本参数,后续Shader中将会用到的一些通用参数。

    TransparentPostProcessPass.cs

    透明的后处理,此时渲染纹理中已经包含了渲染完的不透明物体及后处理,再加上透明物体。

    默认的执行顺序(在不同情况下生效的步骤不一样):

    1. DirectionalShadowPass(方向光主光源)
    2. LocalShadowsPass(视域内所有的聚光灯)
    3. SetupForwardRenderingPass
    4. DepthOnlyPass
    5. ScreenSpaceShadowResolvePass
    6. CreateLightweightRenderTexturesPass
    7. SetupLightweightConstanstPass
    8. RenderOpaqueForwardPass
    9. DrawSkyboxPass
    10. RenderTransparentForwardPass
    11. FinalBlitPass
    12. SceneViewDepthCopyPass

    DefaultRendererSetup.cs

    默认渲染器的初始化设置,包含了所有渲染步骤的初始化(即便是暂时没有用到的)。实现了Setup接口。

    Init:创建渲染步骤,初始化渲染纹理。

    Setup:调用了Init,初始化渲染器和渲染步骤。

    IRendererSetup.cs

    渲染器初始化的基接口,定义了Setup接口。

    Setup:接口。

    LightweightAdditionalCameraData.cs

    轻量管线用额外摄像机数据。

    renderShadows:是否启用阴影。

    requiresDepthTexture:是否启用深度纹理,会影响到是否激活DepthOnlyPass和CopyDepthPass。

    requiresColorTexture:是否启用色彩纹理,会影响到是否激活CopyColorPass。

    version:版本号,没有地方用到。

    LightweightConstantBuffer.cs

    空文件,没有任何代码。

    LightweightForwardRenderer.cs

    轻量的前向渲染器,受到LightweightPipeline管理和调用,负责管理激活的渲染步骤并执行这些步骤,以及提供了一些渲染器层面的参数设置和获取。

    这里预创建了两个过滤设置,RenderQueueRange.opaque和RenderQueueRange.transparent,分别用于不透明物体(0~2500)和半透明物体(2501~5000)的过滤。这将告知Unity在渲染的时候,只会渲染渲染队列编号(RenderQueue)在范围内的物体,从而实现只渲染不透明物体和只渲染半透明物体。

    在两者之间可以渲染天空盒,减少对天空盒被遮挡部分的着色,减少重复绘制(OverDraw)。

    Dispose:销毁逐对象光照索引和材质。

    CreateRTDesc:创建渲染纹理描述信息

    Execute:执行激活的渲染步骤,然后销毁这些渲染步骤。

    GetMaterial:通过枚举获取材质实例。

    Clear:清空激活的渲染步骤列表。

    EnqueuePass:在末尾增加一个渲染步骤。

    RequiresIntermediateColorTexture:判断是否需要额外渲染纹理用于渲染,或者直接渲染到摄像机的目标纹理。

    CanCopyDepth:判断是否可以拷贝深度(在开启全屏抗锯齿等情况下是不能拷贝深度的)。

    DisposePasses:销毁渲染步骤。

    SetupPerObjectLightIndices:设置逐对象的光源索引,把平行光从索引中剔除,因为进行了全局处理。

    GetCameraClearFlag:基于摄像机的清除标志重新计算清除标志掩码,仅对深度和颜色有效,不清除stencil。

    GetRendererConfiguration:获取渲染器的功能开关设置掩码,包含逐对象反射探针、逐对象光照贴图、逐对象光照探针、以及针对非平行光源处理光照索引。

    LightweightPipeline.cs

    轻量渲染管线,继承自RenderPipeline, 由LightweightPipelineAsset创建和调用,本文件仅包含该类部分代码。

    Dispose:销毁渲染器。

    Render:遍历所有摄像机,逐相机进行渲染。

    SetSupportedRenderingFeatures:设置支持的渲染特性,禁用反射探针旋转功能、指定默认烘焙模式为Subtractive、烘焙模式仅支持Subtractive、烘焙光源仅支持Baked和Mixed类型、烘焙的方向模式有向、无向两种都支持、禁用光照探针代理体积、禁用速度矢量(所以运动模糊用不了)、启用阴影接收、启用反射探针。

    InitializeCameraData:基于管线指定的相关参数(深度、粒子、不透明纹理及降采样等)初始化相机数据,并设置相机额外数据。

    InitializeRenderingData:初始化渲染数据,设置相机并调用光源和阴影的初始化,根据管线参数设置是否启用动态合批。

    InitializeShadowData:根据管线参数覆写阴影相关的参数。

    InitializeLightData:根据管线参数覆写光源相关的数据。

    GetMainLight:从可见光源列表中获得主光源(最亮的平行光)。

    SetupPerFrameShaderConstants:设置逐帧的Shader常量(相机无关的全局参数)。

    SetupPerCameraShaderConstants:设置逐相机的Shader常量(相机有关的参数)。

    LightweightPipelineCore.cs

    LightweightPipeline类的另一部分代码,共同向下维护渲染器和向上提供接口。

    fullscreenMesh:全屏大小的网格。

    GetPipelineCapabilities:获取静态的PipelineCapabilities枚举值,用于ShaderPreprocessor中对Shader的裁剪。

    SetPipelineCapabilities:根据管线参数设置Shader变体的开/关。

    DrawFullScreen:对全屏网格执行绘制。

    GetLightCookieMatrix:获取世界坐标系到主光源的本地坐标系的变换矩阵,用于传递给Shader的_WorldToLight变量。

    CopyTexture:执行渲染纹理的拷贝(blit)。

    IsSupportedShadowType:判断光源类型是否为平行光或聚光灯,仅此两种光源支持阴影。

    IsSupportedCookieType:判断光源类型是否为平行光或聚光灯,仅此两种光源支持信息记录(Cookie)。

    IsStereoEnabled:判断是否为XR模式下启用双眼的Scene视图。

    RenderPostProcess:渲染后处理效果。

    LightweightShaderUtils.cs

    提供Shader相关的杂项功能。

    m_ShaderPaths:管线预制的Shader名称列表。

    GetShaderPath:根据枚举获取管线预制的Shader名称。

    LightweightShadowUtils.cs

    提供阴影相关的杂项功能。

    ExtractDirectionalLightMatrix:计算主光源的视口矩阵和透视矩阵,用于处理它产生的阴影。

    ExtractSpotLightMatrix:计算聚光灯的视口矩阵和透视矩阵,用于处理它产生的阴影。

    RenderShadowSlice:基于给定的视口、透视矩阵渲染阴影切片(级联阴影产生的多级切片)。

    GetMaxTileResolutionInAtlas:计算阴影贴图的分辨率。

    ApplySliceTransform:计算级联阴影的切片变换矩阵。

    SetupShadowCasterConstants:设置产生阴影的光源的Shader参数(_ShadowBias和_LightDirection)。

    GetShadowTransform:基于视口、透视矩阵,计算阴影变换矩阵。

    MaterialHandles.cs

    就一个枚举。

    Error:Shader编译出错时默认使用的粉紫色Shader。

    DepthCopy:深度拷贝用Shader。

    Sampling:采样Shader。

    Blit:渲染纹理拷贝Shader。

    ScrenSpaceShadow:屏幕空间阴影Shader。(Scren不是我拼错的,源码里就这样)

    Count:枚举总数。

    RenderTargetHandle.cs

    一个句柄及相关运算符重载。

    Init:基于Shader属性的名字生成ID。

    Identifier:基于ID创建识别对象。

    Equals:判定ID是否相等。

    GetHashCode:返回ID。

    ==:判定ID是否相等。

    !=:判定ID是否不等。

    RenderTargetHandles.cs

    空文件,没有任何代码。

    SampleCount.cs

    就一个枚举。

    One = 1:单次采样。

    Two = 2:双重采样。

    Four = 4:四重采样。

    SceneViewDrawMode.cs

    重定义Scene视图支持的绘制模式。

    RejectDrawMode:在Scene视图中屏蔽掉那些不支持的绘制模式(TexturedWire、ShadowCascades、RenderPaths、AlphaChannel、Overdraw、Mipmaps、SpriteMask、DeferredDiffuse、DeferredSpecular、DeferredSmoothness、DeferredNormal、ValidateAlbedo、ValidateMetalSpecular、ShadowMasks、LightOverlap)

    SetupDrawMode:启用管线重定义绘制模式。

    ResetDrawMode:禁用管线重定义绘制模式。

    Editor

    lightweightPBRExtraPasses.template

    ShaderGraph用轻量PBR的模板文件,定义了ShadowCaster、DepthOnly、Meta这几个Pass。(和非ShaderGraph用的Standard还是有较大区别的)

    lightweightPBRForwardPass.template

    ShaderGraph用轻量PBR的模板文件,定义了LightweightForward这个Pass。(和非ShaderGraph用的Standard还是有较大区别的)

    LightWeightPBRSubShader.cs

    继承自IPBRSubShader,负责生成ShaderGraph的PBRMasterNode的源码。

    m_ForwardPassMetallic:定义基于金属度的PBR参数列表:Albedo、Normal、Emission、Metallic、Smoothness、Occlusion、Alpha、AlphaThreshold。

    m_ForwardPassSpecular:定义基于高光度的PBR参数列表:Albedo、Normal、Emission、Specular、Smoothness、Occlusion、Alpha、AlphaThreshold。

    GetSubshader:根据IMasterNode中设置的参数,替换掉模板文件中的可替换部分代码,生成最终使用的SubShader源码字符串。

    IsPipelineCompatible:检查当前设置的管线资源文件是否为轻量管线资源。

    GetTemplatePath:从LightweightIncludePaths中指定的包路径中寻找LWRP/Editor/ShaderGraph目录中的指定模板文件,传入参数指定了模板文件的名字。

    GetShaderPassFromTemplate:根据提供的参数替换主Pass模板中的可替换部分代码,生成主Pass源码。

    GetExtraPassesFromTemplate:根据提供的参数替换额外Pass模板中的可替换部分代码,生成额外Pass源码。

    lightweightSubshaderFastBlinn.template

    ShaderGraph用FastBlinn这个SubShader的模板文件,定义了LightweightForward、ShadowCaster、DepthOnly、Meta这几个Pass(轻量管线支持的所有pass)。

    lightweightUnlitExtraPasses.template

    ShaderGraph用无光照Shader模板文件,定义了ShadowCaster、DepthOnly这几个Pass。

    lightweightUnlitPass.template

    ShaderGraph用无光照Shader模板文件,定义了LightweightForward这个Pass。

    LightWeightUnlitSubShader.cs

    继承自IUnlitSubShader,负责生成ShaderGraph的UnlitMasterNode的源码。

    m_UnlitPass: 定义参数列表:Color、Alpha、AlphaThreshold。

    GetSubshader: 根据IMasterNode中设置的参数,替换掉模板文件中的可替换部分代码,生成最终使用的SubShader源码字符串。

    IsPipelineCompatible: 检查当前设置的管线资源文件是否为轻量管线资源。

    GetTemplatePath:从指定的包路径中寻找LWRP/Editor/ShaderGraph目录中的指定模板文件,传入参数指定了模板文件的名字。(同一个包同一个目录下的两个类的相同用途、名称的函数(LightWeightPBRSubShader和LightWeightUnlitSubShader),实现居然还不一样。。。Unity的开发团队在管理上还是不够严谨。)

    GetShaderPassFromTemplate:根据提供的参数替换主Pass模板中的可替换部分代码,生成主Pass源码。

    GetExtraPassesFromTemplate:根据提供的参数替换额外Pass模板中的可替换部分代码,生成额外Pass源码。

    LightweightShaderGUI.cs

    继承自ShaderGUI,抽象基类。

    MaterialChanged:材质发生变更,纯虚函数,需要实现。

    FindProperties:获取需要用到的材质属性实例。本类仅处理_Surface、_Blend、_Cull、_AlphaClip、_Cutoff这几个属性。

    ShaderPropertiesGUI:材质属性的界面显示。本类仅显示_Surface、_Blend、_Cull、_AlphaClip、_Cutoff这几个属性。

    OnGUI:界面显示,分别调用FindProperties,MaterialChanged(仅首次),ShaderPropertiesGUI。

    SetupMaterialBlendMode:设置材质的混合模式,根据_AlphaClip的值去指定_ALPHATEST_ON关键字是否启用,根据_Surface和_Blend的值去指定RenderType、_SrcBlend、_DstBlend、_ZWrite、renderQueue等属性以及_ALPHAPREMULTIPLY_ON关键字是否启用,并决定是否启用ShadowCaster这个Pass。

    DoPopup:呼出一个下拉框风格的界面(子函数封装)。

    DoMaterialRenderingOptions:显示材质面板最下方的RenderingOptions:

    LightweightStandardGUI.cs

    继承自LightweightShaderGUI,标准PBR Shader的设置界面逻辑。

    FindProperties:获取需要用到的材质属性实例。本类仅处理_WorkflowMode、_Color、_MainTex、_Glossiness、_GlossMapScale、_SmoothnessTextureChannel、_Metallic、_SpecColor、_MetallicGlossMap、_SpecGlossMap、_SpecularHighlights、_GlossyReflections、_BumpScale、_BumpMap、_OcclusionStrength、_OcclusionMap、_EmissionColor、_EmissionMap这几个属性。

    MaterialChanged:材质发生变更,原材质keywords置空,调用SetupMaterialBlendMode(基类中)和SetMaterialKeywords。

    ShaderPropertiesGUI:材质属性的界面显示。本类仅显示_WorkflowMode然后调用基类、以及_Color、_MainTex、_Glossiness、_GlossMapScale、_SmoothnessTextureChannel、_Metallic、_SpecColor、_MetallicGlossMap、_SpecGlossMap、_SpecularHighlights、_GlossyReflections、_BumpScale、_BumpMap、_OcclusionStrength、_OcclusionMap、_EmissionColor、_EmissionMap这几个属性。

    AssignNewShaderToMaterial:更换Shader时的处理,如果新的Shader包含能够识别的属性,则把值传递过去。能够识别的属性有_Emission、_AlphaClip 、_Surface、_Blend、_WorkflowMode、_SpecGlossMap、_MetallicGlossMap等。

    DoAlbedoArea:显示Albedo界面。

    DoNormalArea:显示Normal界面。

    DoEmissionArea:显示Emission界面。

    DoMetallicSpecularArea:显示Metallic或者Specular界面,取决于选择的Workflow Mode。

    GetSmoothnessMapChannel根据材质中_SmoothnessTextureChannel参数的值,返回AlbedoAlpha或者SpecularMetallicAlpha。

    SetMaterialKeywords:根据界面操作后的值,设置_SPECULAR_SETUP、_METALLICSPECGLOSSMAP、_SPECGLOSSMAP、_METALLICGLOSSMAP、_NORMALMAP、_SPECULARHIGHLIGHTS_OFF、_GLOSSYREFLECTIONS_OFF、_OCCLUSIONMAP、_PARALLAXMAP、_DETAIL_MULX2、_EMISSION、_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A等关键字是否开启。

    LightweightStandardParticlesShaderGUI.cs

    继承自ShaderGUI,标准粒子Shader的设置界面逻辑。

    FindProperties:获取需要用到的材质属性实例。本类仅处理_Mode、_ColorMode、_FlipbookMode、_Cull、_MainTex、_Color、_Cutoff、_MetallicGlossMap、_Metallic、_Glossiness、_BumpScale、_BumpMap、_EmissionEnabled、_EmissionColor、_EmissionMap、_SoftParticlesEnabled、_CameraFadingEnabled、_SoftParticlesNearFadeDistance、_SoftParticlesFarFadeDistance、_CameraNearFadeDistance、_CameraFarFadeDistance这几个属性。

    OnGUI:为正确显示属性动画,通过FindProperties逐事件获取属性实例,通过调用ShaderPropertiesGUI完成Shader界面的绘制,并在首次启用时通过调用MaterialChanged和CacheRenderersUsingThisMaterial完成初始化操作。

    ShaderPropertiesGUI:通过调用模块化的绘制函数,绘制本Shader所有的界面元素,由于enlighten(相比progressive更亮一些,无论亮部还是暗部)的缘故,在非翻书模式下还要把albedo纹理的缩放和偏移值赋给emission纹理。

    AssignNewShaderToMaterial:更换Shader时的处理,如果新的Shader包含能够识别的属性,则把值传递过去。能够识别的属性有Unlit、_Emission等,针对Shader名称包含Legacy Shaders/、/Transparent/Cutout/、/Transparent/的情况也进行了处理。

    ColorModePopup:选择色彩模式的下拉框。

    FlipbookModePopup:选择翻书模式的下拉框,从源码上看,Blend模式仅仅是定义了_REQUIRE_UV2这个关键字,并且给Mesh指定了UV2和AnimBlend,用两套UV对同一纹理采样后混合。但是没有找到实际应用和把关键字关联起来的地方,可能是因为这个功能还未开发完毕。另外,这个功能的使用似乎需要在制作Mesh的时候提供符合要求的UV数据才行,但是并不知道这些数据是怎么做的,以及这个功能对于美术到底有何用途,顾名思义,似乎是用来制作翻书的效果,但这是粒子系统的功能么?

    TwoSidedPopup:双面与否的勾选,勾上则为CullMode.Off,不勾用CullMode.Back。

    FadingPopup:淡入参数设置,勾选后弹出近、远距离的输入框。

    由近及远,出现淡入效果,越近的地方越虚,越远的地方越实。Fade因子由小变大。

    DoAlbedoArea:显示反照率界面。

    DoEmissionArea:显示自发光界面。

    DoSpecularMetallicArea:显示金属度和光滑度界面。

    DoNormalMapArea:显示法线贴图界面。

    DoVertexStreamsArea:显示顶点流信息并填充实质顶点流信息列表。

    SetupMaterialWithBlendMode:根据选定的混合模式,设置材质的相关属性和关键字。

     

    RenderType

    SOD

    Z

    Alpha

    Render

    Queue

    Test

    Blend

    Premultiply

    Modulate

    Opaque

    1+0

    1

    0

    0

    0

    0

    -1

    Cutout

    TransparentCutout

    1+0

    1

    1

    0

    0

    0

    2450

    Fade

    Transparent

    A+(1-A)

    0

    0

    1

    0

    0

    3000

    Transparent

    Transparent

    1+(1-A)

    0

    0

    0

    1

    0

    3000

    Additive

    Transparent

    A+1

    0

    0

    1

    0

    0

    3000

    Subtractive

    Transparent

    -A+1

    0

    0

    1

    0

    0

    3000

    Modulate

    Transparent

    D+(1-A)

    0

    0

    0

    0

    1

    3000

    SetupMaterialWithColorMode:根据选定的色彩模式,设置材质的关键字。

     

    ColorOverlay

    ColorColor

    ColorAddSubDiff

    Vector4(CASD)

    Multiply

    0

    0

    0

    /

    Additive

    0

    0

    1

    /

    Subtractive

    0

    0

    1

    /

    Overlay

    0

    0

    1

    -1,1,0,0

    Color

    0

    0

    1

    1,0,0,0

    Difference

    0

    0

    1

    -1,0,0,0

    SetMaterialKeywords:设置其它的一些材质参数和关键字,包括_NORMALMAP、_METALLICGLOSSMAP、_EMISSION、_REQUIRE_UV2、_FADING_ON、_SoftParticlesNearFadeDistance、_SoftParticlesFarFadeDistance、_CameraNearFadeDistance、_CameraFarFadeDistance、_SoftParticleFadeParams、_CameraFadeParams、Always,这里是根据材质面板上实际贴图是否存在及默认参数是否变更来决定材质中关键字特性宏的开关,以起到Shader变体的自动生成和裁剪的作用。具体怎样打AB包能够实现正确生成最少变体及不丢失Shader,还有待进一步研究确认。

    MaterialChanged:材质发生变更,原材质keywords置空,调用SetupMaterialBlendMode(基类中)、SetupMaterialWithColorMode和SetMaterialKeywords。

    CacheRenderersUsingThisMaterial:缓存当前内存中所有使用了本材质的Renderer实例。首次生效时执行,以加速后续的遍历。

    SetKeyword:对材质开、关关键字特性的便利方法。

    LightweightStandardSimpleLightingGUI.cs

    继承自LightweightShaderGUI,简单光照Shader的设置界面逻辑

    FindProperties获取需要用到的材质属性实例。本类仅处理_MainTex、_Color、_SpecSource、_GlossinessSource、_SpecGlossMap、_SpecColor、_Shininess、_BumpMap、_EmissionMap、_EmissionColor这几个属性。

    ShaderPropertiesGUI:通过调用模块化的绘制函数,绘制本Shader所有的界面元素,由于enlighten(相比progressive更亮一些,无论亮部还是暗部)的缘故,还要把albedo纹理的缩放和偏移值赋给emission纹理。

    MaterialChanged:材质发生变更,原材质keywords置空,调用SetupMaterialBlendMode(基类中)和SetMaterialKeywords。

    SetMaterialKeywords这个函数是从MaterialChanged调过来的,但是重复执行了一样的代码,应该是写错了。

    并且全局也只有这么一处调用:

    通过调用UpdateMaterialSpecularSource设置其它的一些材质参数和关键字,包括_SPECGLOSSMAP、_SPECULAR_COLOR、_GLOSSINESS_FROM_BASE_ALPHA以及_NORMALMAP、_EMISSION关键字,这里是根据材质面板上实际贴图是否存在及默认参数是否变更来决定材质中关键字特性宏的开关,以起到Shader变体的自动生成和裁剪的作用。具体怎样打AB包能够实现正确生成最少变体及不丢失Shader,还有待进一步研究确认。

    UpdateMaterialSpecularSource:根据面板的参数设置_SPECGLOSSMAP、_SPECULAR_COLOR、_GLOSSINESS_FROM_BASE_ALPHA关键字特性的开、关。

    AssignNewShaderToMaterial:更换Shader时的处理,如果新的Shader包含能够识别的属性,则把值传递过去。能够识别的属性有_Shininess、Transp 、Cutout、Spec、_Surface、_Blend、_SpecSource、_GlossinessSource、Self-Illumin等。

    RequiresAlpha:判断这个Shader设置了_AlphaClip非0或者_Surface被指定为trasparent类型。

    DoSurfaceArea:显示Surface属性第一行界面信息。

    DoSpecular:显示高光界面区域。

    注意,如果上面勾选了Alpha Clip或者选定了Transparent类型的Surface,会导致下面的GlossinessSource置灰,无法选择。本函数负责绘制Specular勾选框及其下面的几行界面,如果未勾选Specular,则下面几行也不绘制。

    DoEmissionArea:显示Emission界面区域。

    ConvertFromLegacy:对Shader名称包含Transp 、Cutout、Spec,或包含_Surface、_Blend、_SpecSource、_GlossinessSource、Self-Illumin等属性的,将相应属性拷贝到新的材质中。

    LightweightUnlitGUI.cs

    FindProperties:获取需要用到的材质属性实例。本类仅处理_MainTex、_Color、_SampleGI、_BumpMap这几个属性。

    ShaderPropertiesGUI:绘制本Shader所有的界面元素。勾选Sample GI会额外提供Normal Map设置,别的也没啥花头了。

    MaterialChanged:材质发生变更,原材质keywords置空,调用SetupMaterialBlendMode(基类中)和SetMaterialKeywords。

    SetMaterialKeywords设置其它的一些材质参数和关键字,包括_SAMPLE_GI、_NORMAL_MAP关键字,这里是根据材质面板上实际贴图是否存在及默认参数是否变更来决定材质中关键字特性宏的开关,以起到Shader变体的自动生成和裁剪的作用。具体怎样打AB包能够实现正确生成最少变体及不丢失Shader,还有待进一步研究确认。

    LightweightCameraEditor.cs

    管线特化的摄像机Inspector面板。

    SetAnimationTarget:设置AnimBool的便捷方法,当值发生变化的时候进行界面重绘。

    UpdateAnimationValues:对ClearFlag、Ortho、TargetEye三个动画值监控其变化。

    OnEnable:缓存管线资产,调用Settings类的同名方法,更新UpdateAnimationValues为true。

    OnDisable:移除对ClearFlag、Ortho、TargetEye三个动画值的监控,缓存的管线资产置空。

    OnInspectorGUI:相机参数的界面绘制,调用了DrawRenderingPath、DrawHDR、DrawTargetTexture、DrawMSAA这几个方法。

    DrawRenderingPath:绘制渲染路径界面,但是不给设置。

    DrawHDR:绘制HDR界面,但是轻量管线默认是禁用HDR的,可以手动开启。

    DrawTargetTexture:绘制渲染纹理界面,如果渲染纹理要求的多重采样抗锯齿倍率高于轻量管线设置的允许倍率,会出现Fix now按钮,点击会用渲染纹理要求的倍率覆盖管线的设置值。

    DrawMSAA:绘制多重采样抗锯齿界面,如果管线设置中关闭了抗锯齿支持,会出现Fix now按钮,点击后把管线的抗锯齿倍率值设置为4倍。

    LightweightLightEditor.cs

    管线特化的灯光Inspector面板。

    OnEnable:调用Settings类的同名方法,调用UpdateShowOptions,传入true。

    OnInspectorGUI:调用Settings类的Update方法,调用UpdateShowOptions,传入false。调用Settings类的DrawLightType,在两种光源类型间切换时,变化的参数播放滚动的效果。

    SetOptions:设置AnimBool的便捷方法,当值发生变化的时候进行界面重绘。

    UpdateShowOptions:对Spot、Point、Dir、Area、Shadow、Runtime、ShadowAngle、ShadowRadius、LightBounceIntensity九个动画值监控其变化(不同的光源类型用到不同的值)。

    DrawSpotAngle:绘制聚光灯的角度参数。

    DrawCookie:绘制Cookie,调用的地方被注释掉了,Tim写着在v1版本中禁用cookie以节省shader组合。

    DrawCookieSize:绘制Cookie的Size,调用的地方被注释掉了,Tim写着在v1版本中禁用cookie以节省shader组合。

    ShadowsGUI:绘制阴影参数,不同的光源类型,阴影参数也不一样。

    LightweightMaterialUpgrader.cs

    调用Core库中的MaterialUpgrader,完成材质转换。

    UpgradeProjectMaterials:将管线自定义的转换类传入MaterialUpgrader类的UpgradeProjectFolder方法对整个工程进行转换。

    UpgradeSelectedMaterials:将管线自定义的转换类传入MaterialUpgrader类的UpgradeSelection方法对选中的资源进行转换。

    GetUpgraders:创建管线要用到的所有转换类的实例,供Core库转换时进行回调。

    SupportedUpgradeParams:定义了轻量管线支持的参数类型。

     

    Upgrade

    SurfaceType

    Upgrade

    BlendMode

    Alpha

    Clip

    Specular

    Source

    Glossiness

    Source

    diffuseOpaque

    Opaque

    Alpha

    false

    NoSpecular

    BaseAlpha

    specularOpaque

    Opaque

    Alpha

    false

    SpecularTextureAndColor

    BaseAlpha

    diffuseAlpha

    Transparent

    Alpha

    false

    NoSpecular

    SpecularAlpha

    specularAlpha

    Transparent

    Alpha

    false

    SpecularTextureAndColor

    SpecularAlpha

    diffuseAlphaCutout

    Opaque

    Alpha

    false

    NoSpecular

    BaseAlpha

    specularAlphaCutout

    Opaque

    Alpha

    true

    NoSpecular

    SpecularAlpha

    diffuseCubemap

    Opaque

    Alpha

    true

    SpecularTextureAndColor

    SpecularAlpha

    specularCubemap

    Opaque

    Alpha

    false

    NoSpecular

    BaseAlpha

    diffuseCubemapAlpha

    Opaque

    Alpha

    false

    SpecularTextureAndColor

    BaseAlpha

    specularCubemapAlpha

    Transparent

    Alpha

    false

    NoSpecular

    BaseAlpha

    StandardUpgrader:标准PBR材质的转换类,用于将BuiltIn的材质转换成轻量管线的格式,除了重命名材质的Shader外,主要是处理_WorkflowMode参数和_OCCLUSIONMAP、_METALLICSPECGLOSSMAP、_SPECULAR_SETUP这三个关键字。

    StandardSimpleLightingUpgrader:简单光照材质的转换类,用于将BuiltIn的材质转换成轻量管线的格式,除了重命名材质的Shader外,主要是处理_Surface、_Blend、_AlphaClip、_SpecSource、_GlossinessSource、_EmissionColor这六个参数和_NORMALMAP、_EMISSION、_SPECGLOSSMAP、_SPECULAR_COLOR、_GLOSSINESS_FROM_BASE_ALPHA这五个关键字以及把_Illum纹理重命名为_EmissionMap。

    TerrainUpgrader:重命名地形材质的Shader。

    ParticleUpgrader :重命名粒子材质的Shader。

    LightweightPipelineAssetEditor.cs

    管线资产文件的Inspector面板。

    OnInspectorGUI:绘制Inspector面板的界面,调用DrawCapabilitiesSettings和DrawGeneralSettings,并绘制XR区面板。

    OnEnable:缓存属性值,添加SoftParticle和OpaqueTextureScale值变化的重绘回调。

    OnDisable:移除SoftParticle和OpaqueTextureScale值变化的重绘回调。

    UpdateAnimationValues:更新SoftParticle和OpaqueTextureScale的当前值。

    DrawGeneralSettings:绘制基础区面板。

    DrawCapabilitiesSettings:绘制容量区面板。

    LightweghtShaderIncludePaths.cs

    GetPaths:获取查找管线资源的根目录,默认是指向通过PackageManager下载的包在电脑上默认保存的地方,如果把包拷贝到Assets目录下使用,需要修改这个路径指向Assets目录下的管线包根目录。

    ShaderPreprocessor.cs

    StripUnusedShader:裁剪掉名字包含Debug、HDRenderPipeline字样的Shader,如果管线禁用了方向阴影(DirectionalShadows),那么也裁剪掉名字包含ScreenSpaceShadows的Shader。

    StripUnusedPass:裁剪掉类型为Meta的Pass,因为是烘焙时用的,如果管线禁用了阴影(方向阴影和局部阴影,详见DirectionalShadowPass和LocalShadowPass),那么也裁剪掉类型为ShadowCaster的Pass。

    StripUnusedVariant:裁剪掉和管线设置不相容(在管线设置中禁用)的变体,包括额外光源(AdditionalLights)、顶点光(VertexLights)、方形阴影(DirectionalShadows)、局部阴影(LocalShadows)、软阴影(SoftShadows)。

    StripInvalidVariants:裁剪掉非法的变体,包括启用级联阴影但是禁用方向阴影、启用软阴影但是禁用方向阴影和局部阴影、启用顶点光但是禁用额外光源、启用方向光照贴图但是禁用光照贴图这几种情况,另外,轻量管线不支持动态光照贴图。

    StripUnused:通过调用StripUnusedShader、StripUnusedPass、StripUnusedVariant、StripInvalidVariants进行Shader裁剪。

    LogVariants:把轻量管线的变体打印出来(调试用),默认关闭,需要开启LOG_VARIANTS宏才可以使用。

    OnProcessShader:Shader编译过程中的回调,通过调用StripUnused进行Shader裁剪。

    UpgradeCommon.cs

    UpgradeSurfaceType:表面类型枚举,Opaque、Transparent。

    UpgradeBlendMode:混合模式枚举,Alpha、Premultiply、Additive、Multiply。

    SpecularSource:高光来源枚举,SpecularTextureAndColor、NoSpecular。

    GlossinessSource:光泽度来源枚举,BaseAlpha、SpecularAlpha。

    ReflectionSource:反射来源枚举,NoReflection、Cubemap、ReflectionProbe。

    UpgradeParams:包含上述枚举的结构体。

    Shader

    InputSurfaceGrass.hlsl

    FastSinCos:使用泰勒级数一次性计算4个0-1区间值的正弦和余弦近似值,正弦取前4项,余弦取前5项。

    TerrainWaveGrass:在顶点层计算草被吹动的动画效果,并根据波动融合顶点色和GrassTint颜色。这里可能是实现三个效果:

    1. 草的物理波动,顶点位移,这里实现的顶点位移,不同位置的草的位移有细微的不同的表现,不会有所有草很规律的波动问题。
    2. 草的颜色波动,波浪颜色(波浪起伏有明暗变化)和草顶点色融合。
    3. 草的alpha值由近及远变为0,和距离的平方成正比,非线性。

    TerrainBillboardGrass:计算草顶点的位置,超出距离的草不做偏移处理。

    InputSurfaceTerrain.hlsl

    定义了地形使用的4组纹理(单次渲染最多使用4组纹理)及其所需的变量,并引用了其它库文件。这里有四组表面纹理和法线的贴图、采样器、纹理缩放和偏移参数;一组控制贴图的对应参数。对应四组表面贴图的平滑度和反光度参数;一组高光贴图和它的采样器,没有纹理缩放和偏移参数。这里定义的高光贴图实际并没有找到使用的地方,可能是作者复制黏贴的时候忘删了。

    InputSurfaceTerrainBase.hlsl

    SampleMetallicSpecGloss:从金属度纹理采样高光光泽度信息,但使用反照率的alpha。但是后续InitializeStandardLitSurfaceData中的调用却又完全不是这么回事,莫名其妙。从当前的逻辑看,这个函数完全没有存在价值,反而混淆了逻辑,导致更不容易理解。

    InitializeStandardLitSurfaceData:填充SurfaceData结构,从主纹理采样反照率(rgb)和光滑度(a)信息,调用SampleMetallicSpecGloss获取高光光泽度和alpha(但是这实际上完全是混淆,其实就是直接从金属度纹理获取金属度),然后从凹凸纹理获取切空间法线。透明度和遮蔽设置为1,高光设置为0。

    LightweightPassDepthOnlyGrass.hlsl

    仅计算草的深度信息,所以只处理了坐标和颜色(透明度裁剪)。

    DepthOnlyVertex:根据草的波动计算顶点色,草的顶点色中Alpha通道用于控制波动强度,不参与其他计算,在一个距离范围之内离摄像机越远Alpha趋近0,用作后续的透明裁剪,根据顶点坐标进行裁剪。

    DepthOnlyFragment:根据顶点色中的透明度(a),执行裁剪,用于输出深度。根据做过波浪计算之后的顶点颜色的透明度(根据设置不同有可能又乘过了贴图的透明度)进行裁剪,裁剪的部分不会写深度缓存。

    LightweightPassLitGrass.hlsl

    InitializeInputData:计算世界空间的法线,计算世界空间的视向量,填充阴影坐标和雾效顶点光信息,计算预烘焙的全局光照信息,输出片元信息的结构体。

    InitializeVertData:填充GrassVertexOutput结构体,计算世界空间的顶点坐标,用32填充闪耀度,基于世界空间坐标计算裁剪,计算世界空间的视向量,根据是否启用法线贴图计算所需的法线、切线和副法线信息,根据宏开关的设置来决定是从法线贴图还是从球谐函数采样全局光照信息,计算顶点光和雾的信息,计算阴影坐标。

    WavingGrassVert:计算草顶点信息,处理INSTANCE信息,处理STEREO,计算顶点颜色,调用InitializeVertData填充其它数据。

    WavingGrassBillboardVert:计算公告板样式草顶点信息,处理INSTANCE信息,处理STEREO,计算顶点颜色,调用InitializeVertData填充其它数据。

    LitPassFragmentGrass:处理INSTANCE信息,采样主纹理并与顶点色进行乘法计算,处理透明度裁剪,反光度填充为0.1,计算闪耀度,调用InitializeInputData处理输入的插值后片元数据,基于BlinnPhong计算光照,计算雾。

    LightweightPassLitTerrain.hlsl

    InitializeInputData:计算世界空间的法线,计算世界空间的视向量,填充阴影坐标和雾效顶点光信息,计算预烘焙的全局光照信息,输出片元信息的结构体。

    SplatmapMix:基于地形图示执行反照率和法线的混合。

    (地形图示用R、G、B、A四个通道分别表示四组纹理的分布)

    (针对多组纹理混合的情境,R、G、B、A通道均可有值,表征其混合权重)

    SplatmapFinalColor:在最后计算雾效。

     

    (不计算雾效的地形)         (计算了红色雾的地形)

    SplatmapVert:执行地形的顶点计算,计算世界空间顶点坐标,并计算裁剪坐标,变换地形图示的UV,计算光照贴图的UV,根据宏定义计算法线,计算雾效顶点光信息,计算阴影坐标。

    SpatmapFragment(这个Spat是源码中就存在的拼写错误):基于地形图示的片元计算,调用了SplatmapMix

    、InitializeInputData和SplatmapFinalColor,各材质的反照率、金属度和光滑度被根据权重融合并用于计算PBR。

    Core.hlsl

    OUTPUT_NORMAL:如果启用了_NORMALMAP,则调用OutputTangentToWorld把切线空间的纹理采样得到的法线转换成世界空间的法线;如未启用,则调用TransformObjectToWorldNormal把模型空间的法线转换成世界空间法线。这里OUTPUT_NORMAL是在顶点着色器中调用,把法线从模型空间转换到世界空间,区别是,如果材质中添加了凹凸贴图就会启用_NROMALMAP,这时在片元着色器里需要当前顶点的切线空间的转换矩阵来进行法线贴图的采样,因此在顶点着色器阶段需要输出世界空间下的(切线、副切线、法线)来构成切线空间的三个正交轴,从而获取切线空间到世界空间的转换矩阵。否则只需要输出顶点法线即可,用来减少插值寄存器的使用。

    UNITY_Z_0_FAR_FROM_CLIPSPACE:根据各种平台特性和底层关键字定义,把深度转换为从近切面到远切面线性增大的值,出于性能考虑,对于负值的情况未做处理,因为距离比较近。这会导致OPENGL下靠近相机近裁剪面特别近的物体的深度信息会被修复为0,可能会有一些问题。主要和UNITY_REVERSED_Z、UNITY_UV_STARTS_AT_TOP关键字的定义有关,也和API版本(SHADER_API_OPENGL、SHADER_API_GLES、SHADER_API_GLES3)有关,关键字在Core库中定义,如下表所示。

     

    D3D11

    GL

    GLES

    GLES2

    GLES3

    Metal

    PSSL

    Switch

    Vulkan

    XBoxOne

    UNITY_UV_STARTS_AT_TOP

    1

    0

    /

    0

    0

    1

    1

    1

    1

    1

    UNITY_REVERSED_Z

    1

    0

    /

    0

    0

    1

    1

    1

    1

    1

    可以看出,两个关键字的定义是完全同步的。

    SCREENSPACE_TEXTURE:为兼容XR而做的定义。

    SCREENSPACE_TEXTURE_FLOAT:为兼容XR而做的定义。

    SCREENSPACE_TEXTURE_HALF:为兼容XR而做的定义。

     

    SCREENSPACE_TEXTURE

    SCREENSPACE_TEXTURE_FLOAT

    SCREENSPACE_TEXTURE_HALF

    UNITY_STEREO_INSTANCING_ENABLED

    UNITY_STEREO_MULTIVIEW_ENABLED

    TEXTURE2D_ARRAY

    TEXTURE2D_ARRAY_FLOAT

    TEXTURE2D_ARRAY_HALF

    其它情况

    TEXTURE2D

    TEXTURE2D_FLOAT

    TEXTURE2D_HALF

    GetScaledScreenParams:返回_ScaledScreenParams(float4,在Input.hlsl中定义)。

    AlphaDiscard:如果定义了_ALPHATEST_ON,则调用clip函数进行裁剪,小于cutoff – offset的alpha值会被裁剪。

    UnpackNormal:如果定义了UNITY_NO_DXT5nm,调用UnpackNormalRGBNoScale,把压缩为0~1值域的法线还原到-1~1值域;否则,调用UnpackNormalmapRGorAG,针对DXT5nm和BC5格式将存于xy通道的法线信息转换到wy通道统一处理后放回xy通道,同样把压缩为0~1值域的法线还原到-1~1值域,然后基于xy计算z的值。这里传入了常量1执行乘法,注释里写着编译器会把它优化掉的,那么为什么还要传呢?

    UnpackNormalScale:与UnpackNormal功能完全相同,额外提供了Scale参数供缩放法线值至-scale~scale值域。

    OutputTangentToWorld:通过调用TransformObjectToWorldNormal(额外处理了非统一缩放的情况,x、y、z方向的缩放率不同)和TransformObjectToWorldDir把法线和切线变换到世界空间,并计算出世界空间下的副法线,基于unity_WorldTransformParams.w和vertexTangent.w来判断副法线是否需要取反。

    FragmentNormalWS:在片元中使用,如果定义了SHADER_HINT_NICE_QUALITY,则对法线执行逐片元归一化,否则就什么都不做,以换取更好的性能,四点不共面的情况下会存在一些可忍受的错误,插值不正确,显示上可能会有一些小错误。由于法线在从顶点阶段传入片元阶段经过了插值计算,所以片元阶段获取的结果可能不是归一化过的法线,需要再次归一化,这里在使用低质量的配置的情况下不进行归一化处理,对某些计算会增大误差,但是节省了计算单元处理器的开销。尤其对相对在世界空间下的体积只有较少的三角面模型在光照处理时会误差增大。

    FragmentViewDirWS:在片元中使用,如果定义了SHADER_HINT_NICE_QUALITY,则对视向量执行安全的(额外处理了0向量的情况以免出错)逐片元归一化,否则就什么都不做,以换取更好的性能,但是由于物体表面未必处处可导,插值不正确,显示上可能会有一些小错误。

    VertexViewDirWS:在顶点中使用,如果没有定义SHADER_HINT_NICE_QUALITY,则对视向量执行安全的(额外处理了0向量的情况以免出错)逐顶点归一化,因为片元中不会进行归一化,否则就什么都不做,因为在片元中会对其进行逐像素归一化,没有必要重复做。

    TangentToWorldNormal:把切线空间的法线值,基于给定的切空间坐标轴变换为世界空间法线值,并调用FragmentNormalWS进行归一化处理。

    ComputeScreenPos:计算屏幕空间坐标,说是后续版本的SRP库中有个功能相同的函数,到时候这个函数就不用了,目前主要用于计算阴影。

    ComputeFogFactor:调用UNITY_Z_0_FAR_FROM_CLIPSPACE获取从近切面到远切面的距离,

    ApplyFogColor:如果FOG_LINEAR、FOG_EXP、FOG_EXP2都没有定义,就什么都不做,就是不启用雾。分别针对三种不同的雾计算不同的雾度因子,并以此因子为系数在原始颜色和雾颜色之间插值。

     

    雾度因子

    LINEAR

    雾强度 * 深度

    EXP

    e(-雾强度 * 深度)

    EXP2

    e(-雾强度 * 深度)2

    ApplyFog:调用ApplyFogColor,并传入unity_FogColor(在InputBuiltin.hlsl中定义,real4类型,仍为cpp层默认传入,CSharp层未开源这部分代码;real4宏在Core库中定义,移动平台下使用half4,否则为float4)。

    TransformStereoScreenSpaceTex:XR时计算左右眼偏移,并根据叠加因子w对zw通道进行缩放。

    UnityStereoTransformScreenSpaceTex:调用TransformStereoScreenSpaceTex,叠加因子w传入1。

    CoreFunctions.hlsl

    齐次裁剪空间(Homogeneous Clip Space),这省略了逐顶点的3次除法运算(x/w, y/w, z/w),提升了性能。下文(函数名)中HClip就是指齐次裁剪空间(Homogeneous Clip)。注释中存在拼写错误,齐次空间应为homogeneous space,而Unity的源码中漏了一个e,写的是homogenous space,这是内置管线就有的历史遗留问题了。在轻量管线中,w分量恒为1。至于为什么要有这个w分量,就要去调查OpenGL最早时候的设计目的了。齐次空间W分量的意义,是处理向量(方向、法线等,w=0)和矢量(顶点w=1)时可以使用统一的4x4变换矩阵。Unity的内部的实现,没有遵照这一方式,在处理方向时都把4x4矩阵做了裁剪成为3x3矩阵忽略了W分量,或者把W分量用来存储其他数据来节省插值寄存器的使用。

    GetCameraPositionWS:返回_WorldSpaceCameraPos(在InputBuiltin.hlsl中定义,主要对XR情况下进行重定义,其它情况下就是在SetupForwardRenderingPass.cs中通过context.SetupCameraProperties接口传入的摄像机的世界坐标)。

    GetWorldToViewMatrix:返回UNITY_MATRIX_V(在Input.hlsl中定义为unity_MatrixV,后者在InputBuiltin.hlsl中定义,主要对XR情况下进行重定义,其它情况下就是cpp层传入的世界空间到观察空间的转换矩阵,这部分代码未在CSharp层开源)。

    GetObjectToWorldMatrix:返回UNITY_MATRIX_M(在Input.hlsl中定义为unity_ObjectToWorld,后者在InputBuiltin.hlsl中定义,就是cpp层传入的模型空间到世界空间的转换矩阵,这部分代码未在CSharp层开源)。

    GetWorldToObjectMatrix:返回UNITY_MATRIX_I_M(在Input.hlsl中定义为unity_WorldToObject,后者在InputBuiltin.hlsl中定义,就是cpp层传入的世界空间到模型空间的转换矩阵,这部分代码未在CSharp层开源)。

    GetWorldToHClipMatrix:返回UNITY_MATRIX_VP(在Input.hlsl中定义为unity_MatrixVP,后者在InputBuiltin.hlsl中定义,主要对XR情况下进行重定义,其它情况下就是cpp层传入的世界空间到裁剪空间的转换矩阵,这部分代码未在CSharp层开源)。

    在冯乐乐的《Unity Shader入门精要》一书的4.8章节有罗列部分内置矩阵的数学意义,轻量管线中的完整矩阵定义如下表所示。

    变量名

    描述

    UNITY_MATRIX_M

    即unity_ObjectToWorld,当前的模型矩阵,用于将顶点/方向矢量从模型空间变换到世界空间

    UNITY_MATRIX_I_M

    即unity_WorldToObject ,UNITY_MATRIX_M的逆矩阵,用于将顶点/方向矢量从世界空间变换到模型空间

    UNITY_MATRIX_V

    当前的观察矩阵,用于将顶点/方向矢量从世界空间变换到观察空间

    UNITY_MATRIX_I_V

    UNITY_MATRIX_V的逆矩阵,用于将顶点/方向矢量从观察空间变换到世界空间

    UNITY_MATRIX_P

    当前的投影矩阵,用户将顶点/方向矢量从观察空间变换到齐次裁剪空间

    UNITY_MATRIX_I_P

    没有实现,不可使用

    UNITY_MATRIX_VP

    当前的观察投影矩阵,用于将顶点/方向矢量从世界空间变换到齐次裁剪空间

    UNITY_MATRIX_I_VP

    没有实现,不可使用

    UNITY_MATRIX_MV

    当前的模型观察矩阵,用于将顶点/方向矢量从模型空间变换到观察空间

    UNITY_MATRIX_T_MV

    UNITY_MATRIX_MV的转置矩阵

    UNITY_MATRIX_IT_MV

    UNITY_MATRIX_MV的逆转置矩阵,用于将法线从模型空间变换到观察空间,也可用于得到UNITY_MATRIX_MV的逆矩阵

    UNITY_MATRIX_MVP

    当前的模型观察投影矩阵,用于将顶点/方向矢量从模型空间变换到齐次裁剪空间

    unity_ObjectToWorld

    当前的模型矩阵,用于将顶点/方向矢量从模型空间变换到世界空间

    unity_WorldToObject

    unity_ObjectToWorld的逆矩阵,用于将顶点/方向矢量从世界空间变换到模型空间

    GetOddNegativeScale:返回unity_WorldTransformParams的w通道(1或-1),表示法线贴图是否需要取反,比如MAX和MAYA的法线贴图就是反的。

    TransformWorldToView:通过左乘UNITY_MATRIX_V矩阵,把顶点从世界空间变换到观察空间。

    TransformObjectToWorld:通过左乘UNITY_MATRIX_M矩阵,把顶点从模型空间变换到世界空间。

    TransformWorldToObject:通过左乘UNITY_MATRIX_I_M矩阵,把顶点从世界空间变换到模型空间。

    TransformObjectToWorldDir:通过左乘UNITY_MATRIX_M矩阵,把方向矢量从模型空间变换到世界空间,做了一次归一化以支持统一缩放。

    TransformWorldToObjectDir:通过左乘UNITY_MATRIX_I_M矩阵,把方向矢量从世界空间变换到模型空间,做了一次归一化以支持统一缩放

    TransformObjectToWorldNormal:如果定义了UNITY_ASSUME_UNIFORM_SCALING,则通过调用TransformObjectToWorldDir进行简单转换(模型空间到世界空间),因为假定模型为统一缩放;否则,需要处理非统一缩放的情况,通过右乘UNITY_MATRIX_I_M矩阵并归一化实现。这里使用右乘的数学意义是,非统一缩放的情况下,直接左乘变换矩阵法线方向会被改动,所以需要使用的是变换矩阵中缩放矩阵的逆矩阵,进行左乘。又有左乘矩阵和右乘矩阵的转置矩阵是等价的,而旋转矩阵是正交矩阵,其逆矩阵等价于转置矩阵。所以这里使用变换

    矩阵的逆矩阵右乘法线,来抵消非统一缩放产生的影响。详见冯乐乐的《Unity Shader入门精要》一书4.7章。

    TransformObjectToHClip:由于Unity对UNITY_MATRIX_MVP的定义是UNITY_MATRIX_VP和UNITY_MATRIX_M相乘,而不是从cpp层直接传入一个MVP的矩阵,因此,使用UNITY_MATRIX_MVP意味着逐顶点的两个4x4矩阵乘法运算(64次乘法、48次加法),所以,这里使用UNITY_MATRIX_M左乘模型空间的顶点坐标,再用UNITY_MATRIX_VP左乘变换后的世界空间的顶点坐标,以减少运算次数(16次乘法、12次加法)。最终把顶点坐标从模型空间变换到齐次裁剪空间。在内置管线中,存在UNITY_USE_PREMULTIPLIED_MATRICES定义的情况下,会从cpp层直接传入MVP矩阵,而轻量管线中没有这个功能。

    TransformWorldToHClip:比TransformObjectToHClip少了一步,直接从世界空间变换到齐次裁剪空间。

    CreateWorldToTangent:通过提供的法线、切线和翻转标记生成一个世界空间到切线空间的变换矩阵的便捷函数。

    TransformTangentToWorld:通过右乘世界空间到切线空间的变换矩阵完成逆变换,把切线空间的方向矢量变换到世界空间。同样这里因为世界空间到切线空间的变换矩阵是正交矩阵,其逆矩阵等于其转置矩阵,所以这里右乘世界空间到切线空间的逆矩阵,等价于左乘切线空间到世界空间的矩阵。而切线空间到世界空间的变换矩阵需要额外计算所以这里使用了右乘。只要不涉及模型空间的变换,都不会有缩放矩阵,而不规则缩放矩阵不是正交矩阵,只要没有缩放矩阵,其他系统矩阵是正交矩阵。详见冯乐乐的《Unity Shader入门精要》一书4.7章。

    TransformWorldToTangent:通过左乘世界空间到切线空间的变换矩阵完成变换,把世界空间的方向矢量变换到切线空间。

    TransformTangentToObject:通过右乘世界空间到切线空间的变换矩阵完成逆变换,得到世界空间的方向矢量,再左乘世界空间到模型空间的变换矩阵,把切线空间的方向矢量变换到模型空间。

    TransformObjectToTangent:通过调用TransformObjectToWorldDir把方向矢量从模型空间变换到世界空间,再左乘世界空间到切线空间的变换矩阵,把模型空间的方向矢量变换到切线空间。

    DepthCopy.hlsl

    VertexInput:VS的输入数据,包含模型空间坐标、纹理坐标UV0和instanceID(如果启用Instance的话)。

    VertexOutput:VS的输出数据,包含齐次裁剪空间的坐标位置、纹理坐标UV0、instanceID(如果启用Instance的话)、以及XR相关的双眼数据。

    vert:顶点着色主入口,设置instanceID(如果启用Instance的话),初始化双眼数据(如果启用XR的话),把模型空间的坐标变换到裁剪空间。

    DEPTH_TEXTURE_MS:定义多重采样的深度纹理或者纹理阵列(XR模式)。

    DEPTH_TEXTURE:定义全精度(32位)深度纹理或者纹理阵列(XR模式)。

    LOAD:根据平台(GLES2不支持,直接返回全0)对多重采样纹理或纹理阵列(XR模式)执行从给定UV采样的操作。

    SAMPLE:每个平台都是对深度纹理的 r通道执行采样。

    MSAA_SAMPLES:设定2次或4次采样多重采样。

    _CameraDepthAttachment:根据是否开启深度纹理多重采样定义摄像机的深度纹理和采样器。

    sampler_CameraDepthAttachment:根据是否开启深度纹理多重采样定义摄像机的深度纹理和采样器。

    DEPTH_DEFAULT_VALUE:根据UNITY_REVERSED_Z宏定义深度的默认值为0或者1。

    DEPTH_OP:根据UNITY_REVERSED_Z宏定义深度操作函数用max还是min。

    SampleDepth:根据是否启用深度多重采样对深度纹理执行循环多重采样或者简单采样,在GLES2上不展开循环,其它平台上均标记为展开循环。

    如果UNITY_REVERSED_Z打开,深度默认值为1,循环多重采样时取最小值。

    如果UNITY_REVERSED_Z未定义,深度默认值为0,循环多重采样时取最大值。

    这里多重采样的在两种深度信息的形况下,无论是取最大值还是最小值,都是取出当前位置最靠近相机的一个深度值。

    frag:片元着色主入口,设置instanceID(如果启用Instance的话),调用SampleDepth获取深度值并返回。

    Input.hlsl

    定义了InputData和前面已经提到过的那些个变换矩阵。

    InputData中包含了世界空间坐标、世界空间法线、世界空间视线、阴影坐标、雾坐标、顶点光照、烘焙光照这些信息。

    在这里定义了最多支持的额外光照数目为16个,加上主光源应该为17个。不包括烘焙光源。

    InputBuiltin.hlsl

    定义了绝大部分引擎cpp层会自动进行赋值的渲染用数据(变量),包括了时间、投影参数、屏幕参数、深度参数、正交相机参数、视锥体的六个面的信息 、相机坐标、光源信息、球谐系数、探针遮蔽、XR信息、环境色、间接光环境色、雾颜色、环境贴图、光照贴图、阴影遮罩、主光源Cookie、变换矩阵等等。

    OptimizeProjectionMatrix:优化投影矩阵,把某些恒为0的位赋0来减少计算。

    一些参数的意义,可以查看这里的代码注释。

    这里的相机的投影矩阵永远保存的是场景中相机的投影矩阵,在阴影计算阶段,不能用这里的参数获取光源位置的投影矩阵。

    InputSurfaceCommon.hlsl

    SurfaceData:定义了表面数据,必须和轻量管线ShaderGraph的MasterNode相匹配。其中包含了反照率、高光、金属度、光滑度、切线空间法线、自发光、遮蔽率、透明度。

    Alpha:根据是否叠加反照率的透明度计算透明度,并在启用AlphaTest的情况下执行透明阈值裁剪。

    SampleAlbedoAlpha:调用SAMPLE_TEXTURE2D宏(GLES2调用tex2D,其它平台调用Texture2D的Sample函数,因为版本原因改名了)采样反照率贴图。

    SampleNormal:调用SAMPLE_TEXTURE2D宏采样法线贴图,然后调用UnpackNormal或UnpackNormalScale(根据是否定义了BUMP_SCALE_NOT_SUPPORTED)把值域转换到-1~1。如果禁用法线贴图则直接返回(0,0,1)。

    SampleEmission:如果启用自发光(_EMISSION), 调用SAMPLE_TEXTURE2D宏采样自发光贴图,并乘上自发光色。否则直接返回0。

    InputSurfacePBR.hlsl

    SAMPLE_METALLICSPECULAR:对于金属度模式和高光模式分别采样金属度纹理和高光纹理,以实现同一套代码兼容两种模式。

    SampleMetallicSpecGloss:调用SAMPLE_METALLICSPECULAR采样金属度或高光纹理,返回高光光泽度;如果未提供该纹理,则通过颜色值进行计算,同样返回高光光泽度。

    SampleOcclusion:调用SAMPLE_TEXTURE2D宏采样遮蔽纹理(G通道),若非GLES环境,基于遮蔽强度参数进行插值;如果未提供遮蔽纹理,直接返回1。

    InitializeStandardLitSurfaceData:基于传入的uv值,采样计算反照率(并进行Alpha裁切)、金属度、高光、切线空间法线、遮蔽、自发光信息,返回SurfaceData结构体。

    InputSurfaceSimple.hlsl

    SampleSpecularGloss:根据是否启用光泽纹理(_SPECGLOSSMAP),从光泽纹理采样光泽色或者直接使用传入的高光色,如果启用基础透明度(_GLOSSINESS_FROM_BASE_ALPHA),则把传入的alpha用作a通道。这个接口用于简单光照模式。

    InputSurfaceUnlit.hlsl

    仅仅定义了一些变量,没有额外提供函数。

    Lighting.hlsl

    DECLARE_LIGHTMAP_OR_SH:如果定义了LIGHTMAP_ON,则为float2的UV值,通常为UV2;否则,为half3的值,用于存放顶点的球谐函数值。

    OUTPUT_LIGHTMAP_UV:如果定义了LIGHTMAP_ON,则为一段计算UV缩放和偏移的表达式;否则为空行。

    OUTPUT_SH:如果定义了LIGHTMAP_ON,则为空行;否则为调用SampleSHVertex函数的表达式。

    SAMPLE_GI:如果定义了LIGHTMAP_ON,则为调用SampleLightmap函数的表达式;否则为调用SampleSHPixel函数的表达式。

    kDieletricSpec:入射角下的标准介质反射率系数为4%。(详询BRDF双向反射分布函数的论文)。

    LightInput:光输入常数结构体,用于在获取灯光参数时,保存根据灯光下标(从unity_4LightIndices0的4个通道依次获取)从CSharp层传入的光源数据(位置、颜色、距离衰减、聚光方向、聚光衰减)索引到的数据进行传参。

    Light:着色数据结构体,用于存放获取到的灯光的数据(在所有灯光数组中的下标、相对当前片元的朝向、衰减、subtractive模式的衰减、颜色)进行传参。

    BRDFData:BRDF数据结构体,用于PBR计算模块间进行参数打包传递。

    CookieAttenuation:计算cookie衰减,cookie功能在轻量管线中已被禁用,说是产生了过多的变体。

    DistanceAttenuation:计算距离衰减,并做平滑处理。主光源是不产生衰减的。只有平行光能成为主光源,即使没有主光源,其它类型的光源也不会充当主光源(详见SetupLightweightConstanstPass.cs的SetupMainLightConstants函数中对_MainLightPosition的设置逻辑)。

    左图为无衰减,中图为衰减后,右图添加平滑处理。

    SpotAttenuation:计算聚光灯的形态衰减。如果光源类型不是聚光灯,这个函数的计算结果恒为1,不起作用(但是计算仍要执行,似乎产生了平白的开销)。对于主光源不会调用这个函数,因此也不存在平白的开销。而一个场景只能有一个实时的平行光,另外一个会自动被设置为烘焙光。

    左图为正常的聚光灯,右图去掉了聚光灯衰减,变成了一个点光源。

    GetLightDirectionAndAttenuation:获取非主光源的方向和衰减,根据传入的灯光数据和片元的世界坐标,获取指向光源的向量并通过调用DistanceAttenuation和SpotAttenuation计算当前片元的衰减值。

    从上图可以看到,平台上所有像素指向中间的光源的向量用RGB颜色表示,刚好与Unity使用的坐标轴的颜色是匹配的,即R(X轴)G(Y轴)B(Z轴),正上方向是G,所以当灯光被拉高时,整个平台变成绿色,如下图所示。

    上图显示了点光源调用DistanceAttenuation得到的衰减系数。

    上图显示了聚光灯调用DistanceAttenuation和SpotAttenuation得到的衰减系数。

    GetMainLightDirectionAndAttenuation:获取主光源的方向和衰减,调用GetLightDirectionAndAttenuation,注释了cookie的处理,所以和非主光源没区别。这个方法不会被调用到。

    GetMainLight:获取主光源的灯光数据(在所有灯光数组中的下标恒为0、方向光的朝向、衰减恒为1、subtractive模式的衰减、颜色)。对于主光源实际上使用的是这个方法。

    GetLight:获取非主光源的灯光数据(在所有灯光数组中的下标、相对当前片元的朝向、衰减、subtractive模式的衰减、颜色)。引擎会自动设置unity_4LightIndices0和unity_4LightIndices1来指定当前片元用到的光源的索引,设置的代码在cpp层,没有开源。

    上图用颜色表示两个Cube分别受到影响的光源的索引值,左边的Cube受到索引为0、1、2、3的光源影响,颜色接近黑色(1+2+3)*0.037=0.222,右边的Cube受到索引为4、5、6、7的光源影响,颜色接近白色(4+5+6+7)*0.037=0.777,而影响范围没有覆盖到这两个Cube的大量实时光源不会影响这两个Cube,影响范围覆盖Cube的光源数量超过管线允许的最大像素级光源数量(轻量管线默认为4)时,会按重要与否和亮度高低排序,仅使用最靠前的光源(这在Unity早年关于光源的文档中有说明)。

    GetPixelLightCount:获取像素级灯光的数量。注意,在编辑器模式下,CullResults类不会随时更新可见光列表信息,会缓存上一次运行的筛选结果,所以如果是变更了实时光,需要运行起来查看。

    ReflectivitySpecular:获取高光3通道的最大值,如果是GLES1,则只取R通道。

    OneMinusReflectivityMetallic:标准介质反射率系数叠加金属度计算。96% - M * 96%,所以金属度越高,返回值越小(最小值为0),金属度越低,返回值越大(最大值为96%)。

    InitializeBRDFData:初始化BRDF(双向反射分布函数)数据。对于基于高光的方式,调用ReflectivitySpecular计算反射率;对于基于金属度的方式,调用OneMinusReflectivityMetallic计算反射率。并计算漫反射、高光、粗糙度等相关信息,存于BRDFData结构体中。这里面存有一些预计算的数据,作用是给到后续执行的计算进行直接调用,节省一些重复计算,例如粗糙度的平方、粗糙度的四倍加二、粗糙度的平方减一。

    EnvironmentBRDF:间接漫反射和BRDF漫反射的乘积加上受粗糙度(1粗糙度+1)减弱的间接高光反射和BRDF高光反射(计算菲涅尔)的乘积。

    DirectBDRF(又拼错):进行BRDF计算。

    BRDF高光 = D * V * F4.0

    其中D = 粗糙度2法线与光视线2 * 粗糙度2 - 1 + 12

    V * F = 1.0光线与光视线2* (粗糙度+0.5)

    注光视线是指入射光矢量和视线矢量相加,夹在两者中间的矢量H。

    参见Siggraph 2015上关于移动平台PBR优化的资料https://community.arm.com/c/e/40

    把计算结果截取到0 – 100的范围内,以防移动平台上使用half会造成数据溢出。

    SampleSH:获取cpp层传入的辐照度环境贴图球谐系数Ar、Ag、Ab、Br、Bg、Bb、C,调用SampleSH9(在Core库中定义)计算L0、L1、L2的结果。从CubeMap映射到SH的原理参见微软皮特派克石罗恩的《愚蠢的球谐函数技巧(Stupid Spherical Harmonics(SH) Tricks》,附录10提供了SampleSH9的完整shader实现以及cpp层计算这7个系数的完整代码实现。

    SampleSHVertex:顶点级的球谐系数,根据EVALUATE_SH_VERTEX和EVALUATE_SH_MIXED宏的定义与否,区分是计算全部L0、L1、L2还是只计算L2,或者全部留给像素级计算。是对SampleSH及其子过程的条件封装。

    SampleSHPixel:像素级的球谐系数,根据EVALUATE_SH_VERTEX和EVALUATE_SH_MIXED宏的定义与否,区分是全都用顶点级计算的结果还是只计算L0、L1,或者全部进行逐像素计算。是对SampleSH及其子过程的条件封装。

    SampleLightmap:调用SampleDirectionalLightmap或SampleSingleLightmap(均在Core库中定义)进行光照贴图的采样。

    GlossyEnvironmentReflection:计算间接高光,首先通过粗糙度算出非线性的MipMap级别,然后从环境六面体贴图(在cpp层指定,未开源,在Light Settings面板中指定)采样相应MipMap级别的预编码辐照度,如果开启了HDR则再从HDR解码辐照度,最后乘上遮蔽系数得到最终结果。如果未开启光滑环境反射功能,则直接用常量颜色代替。

    在Light Settings面板中指定该环境六面体贴图。

    左图直接返回0,右图为正常计算了光滑环境反射,可以看到,在0粗糙度的情况下,两面侧墙明显地反射出了天空球的天际线,而遮蔽纹理可以在既定的粗糙度下按需减弱这种反射。

    SubtractDirectMainLightFromLightmap:基于兰伯特光照模型和光源的衰减程度计算混合型(Mixed即Baked和Realtime共存)光源产生的实时阴影,用烘焙结果减去(Subtractive由此而来)实时阴影的亮度,并通过Light Settings中Realtime Shadow Color设置的颜色提供一个保底亮度(即用户可手动指定阴影的最低暗度,防止阴影过于暗)。要想让这个函数工作,需要把光源设置为Mixed,并且设置好光源的Shadow Type(如果选No Shadows,内存中读取到的Lighting Mode恒为Indirect Only,这个函数不会被调用),Light Settings中设置Lighting Mode为Subtractive。

    Realtime Shadow Color设置为0,阴影较暗。

    Realtime Shadow Color设置为114,阴影较亮。

    GlobalIllumination:调用reflect计算反射向量,计算菲涅尔系数,烘焙的GI乘上遮蔽系数计算间接漫反射,调用GlossyEnvironmentReflection计算环境反射,最后调用EnvironmentBRDF传入这些参数计算静态物体受到的GI间接光照的值。

    菲涅尔系数如上图所示,中间的小人为动态物体,不受本函数影响。

    两侧光滑墙面产生的完全反射。

    通过EnvironmentBRDF混合漫反射和镜面反射后的结果,左侧墙为灰色,右侧墙为红色,底座为绿色。

    MixRealtimeAndBakedGI:调用SubtractDirectMainLightFromLightmap计算混合光照情况下的阴影,然后把光源进一步衰减(和减法模式的烘焙衰减相乘)。

    两面墙壁和底座为静态物体,实时光源和烘焙GI的混合结果如上图所示。左侧墙为灰色,右侧墙为红色,底座为绿色。

    LightingLambert:兰伯特光照模型计算漫反射,法线点积光线。

    LightingSpecular:布林冯光照模型计算镜面反射,法线点积光视线(光线和视线的夹线)。

    LightingPhysicallyBased:6参数,调用DirectBDRF进行BRDF计算,里面反正都是嵌套调用前面的那些方法。

    LightingPhysicallyBased:4参数,调用前面这个6参数的重载。

    VertexLighting:进行逐顶点的光照计算,必须是可线性插值的特性才能在顶点中进行计算,由于顶点的数量通常少于像素的数量(假定每个三角面至少占据3个屏幕像素,否则这模型规格就定得有问题了),这会取得更好的性能。这里主要是逐灯光处理了光色的衰减,并调用LightingLambert计算漫反射。当场景内额外实时光源数目多于4个时,多出的部分光源会进行顶点级别的着色处理。如果没有需要做顶点处理的光源,这里返回黑色。

    LightweightFragmentPBR:PBR片元着色的主入口,作为外部模块调用的API,对于任何想要在PBR之上叠加的效果,可以在这个函数调用之前/后进行处理。类似ShaderGraph的PBRMasterNode结点的使用思路。

    LightweightFragmentBlinnPhong:布林冯光照模型片元着色的主入口,作为外部模块调用的API,对于任何想要在其之上叠加的效果,可以在这个函数调用之前/后进行处理。类似ShaderGraph的PBRMasterNode结点的使用思路。

    LightweightPassDepthOnly.hlsl

    顾名思义,是只进行坐标计算并写入深度用的,需要注意的是,如果存在局部全透明像素,不能写入深度。只有在开启透明度测试的情况下,才会把没通过测试的片元裁剪掉,从而不写入深度。

    VertexInput:VS的输入数据,包含模型空间坐标、纹理坐标UV0和instanceID(如果启用Instance的话)。

    VertexOutput:VS的输出数据,包含纹理坐标UV0、齐次裁剪空间的坐标位置、instanceID(如果启用Instance的话)、以及XR相关的双眼数据。

    DepthOnlyVertex:设置instanceID(如果启用Instance的话),初始化双眼数据(如果启用XR的话),执行纹理坐标的平移、缩放,把模型空间的坐标变换到齐次裁剪空间。

    DepthOnlyFragment:调用SampleAlbedoAlpha获取纹理中的Alpha值,调用Alpha进行全透明像素裁剪(需要开启透明度测试,对小于等于给定裁剪值_Cutoff的像素直接返回,不再执行后续的渲染步骤——不写入深度)。

    LightweightPassLit.hlsl

    LightweightVertexInput:VS的输入数据,包含模型空间、模型空间的法线、模型空间的切线、纹理坐标UV0、光照贴图坐标UV1和instanceID(如果启用Instance的话)。

    LightweightVertexOutput:VS的输出数据,包含纹理坐标UV0、光照贴图(或顶点球谐)坐标UV1、额外光源的世界空间坐标、法线(启用法线贴图时额外提供切线、副法线)、视线、雾强度、顶点光、阴影坐标、裁剪空间的坐标、instanceID(如果启用Instance的话)、以及XR相关的双眼数据。

    InitializeInputData:根据LightweightVertexOutput结构体的输入数据,逐片元将法线、视线转换到世界空间,填充InputData结构体,以供后续使用。

    LitPassVertex:顶点着色主入口,根据LightweightVertexInput结构体的输入数据,逐顶点计算裁剪空间坐标、视线、法线(切线、副法线)、光照纹理坐标、球谐坐标、兰伯特漫反射、雾强度、阴影坐标,输出到LightweightVertexOutput结构体中。

    LitPassFragment:片元着色主入口,调用InitializeStandardLitSurfaceData(在InputSurfacePBR.hlsl中定义)填充SurfaceData结构体,调用InitializeInputData填充InputData结构体,调用LightweghtFragmentPBR计算PBR光照,调用ApplyFog计算雾。

    LightweightPassLitSimple.hlsl

    LightweightVertexInput:顶点着色输入信息,包含模型空间顶点坐标、模型空间法线、模型空间切线、纹理坐标UV0、光照贴图坐标UV1和instanceID(如果启用Instance的话)

    LightweightVertexOutput:顶点着色输出信息,包含纹理坐标UV0、光照贴图(或顶点球谐)坐标UV1、世界空间的坐标、亮度、世界空间法线、视线、世界空间切线(如果启用法线贴图)、世界空间副法线(如果启用法线贴图)、雾系数、顶点光照信息、阴影坐标、齐次裁剪空间坐标、instanceID(如果启用Instance的话)、以及XR相关的双眼数据

    InitializeInputData:基于传入的LightweightVertexOutput结构体,计算世界空间法线、世界空间视线、采样烘焙光照、并填充世界空间坐标、雾系数、顶点光照信息,填充InputData结构体。

    LitPassVertexSimple:用于Standard (Simple Lighting)的顶点着色主入口,根据传入的LightweightVertexInput结构体,设置instanceID(如果启用Instance的话),初始化双眼数据(如果启用XR的话),执行纹理坐标的平移、缩放,把模型空间的坐标变换到齐次裁剪空间,填充世界空间坐标、亮度、视线,根据是否启用法线贴图,输出必要的法线信息,执行光照贴图坐标的平移、缩放,计算球谐光照、雾效、顶点光照、阴影坐标,填充LightweightVertexOutput结构体输出。

    LitPassFragmentSimple:用于Standard (Simple Lighting)的片元着色主入口,根据传入的LightweightVertexOutput结构体,设置instanceID(如果启用Instance的话),采样漫反射颜色和透明度,执行Alpha裁切,从法线贴图采样切线空间的法线,采样自发光颜色,采样高光光泽度,调用InitializeInputData填充InputData结构体,调用LightweightFragmentBlinnPhong根据布林冯光照模型计算光照结果,计算雾效。

    LightweightPassMetaCommon.hlsl

    烘焙专用的Pass,计算光照贴图。

    MetaInput:烘焙用片元数据输入结构体,包括反照率、自发光、高光颜色。

    MetaVertexInput:烘焙用顶点着色输入结构体 ,包含模型空间坐标、模型空间法线、纹理坐标UV0、UV1、UV2,模型空间切线。

    MetaVertexOuput:烘焙用顶点着色输出结构体 ,齐次坐标空间顶点坐标、纹理坐标UV0。

    MetaVertexPosition:根据光照贴图坐标UV1执行纹理缩放、平移,并从世界空间转换到齐次裁剪空间。

    MetaFragment:根据unity_MetaFragmentControl的x、y值是否非0,返回反照率的计算值或自发光色,将unity_OneOverOutputBoost归到0~1,调用PositivePow(在Core中定义)计算反照率颜色的unity_OneOverOutputBoost次方,并截断到0~unity_MaxOutputValue之间。或者直接用自发光色。

    LightweightVertexMeta:调用MetaVertexPosition根据纹理坐标计算齐次裁剪空间坐标,执行纹理坐标的平移、缩放。这个函数十分简单,仅仅用于烘焙时对纯静态物体的空间位置和纹理坐标进行处理,以定位到光照贴图上正确的位置。

    LightweightPassMetaPBR.hlsl

    LightweightFragmentMeta:调用InitializeStandardLitSurfaceData填充SurfaceData结构,调用InitializeBRDFData初始化BRDF(双向反射分布函数)数据,基于计算结果填充MetaInput结构体的反照率、高光颜色、自发光,最后调用MetaFragment计算最终颜色。

    LightweightFragmentMeta的正常计算结果如上左图光照贴图第一行第三格所示,提供了来自其它物体反射的间接光照,如果这个函数直接返回0,如上右图第一行第三格所示,间接光照丢失。在场景中的实际表现如下两图所示:

    这个函数仅对烘焙光照贴图产生影响,运行时不使用。从这段代码看,这只是一个比较简化的计算GI的方式,显然不是基于光线追踪的。

    LightweightPassMetaSimple.hlsl

    LightweightFragmentMetaSimple:从主纹理采样反照率,调用SampleSpecularGloss采样高光、调用SampleEmission采样自发光,最后调用MetaFragment计算最终颜色。

    LightweightPassShadow.hlsl

    VertexInput:阴影计算的顶点着色输入结构体,包含模型空间坐标、模型空间法线、纹理坐标UV0、instanceID(如果启用Instance的话)。

    VertexOutput:阴影计算的顶点着色输出结构体,纹理坐标UV0、齐次裁剪空间坐标。

    GetShadowPositionHClip:计算世界空间坐标、世界空间法线、变换到齐次裁剪空间坐标,利用_ShadowBias的x分量处理平台差异,并填充深度。

    ShadowPassVertex:阴影计算的顶点着色主入口,设置instanceID(如果启用Instance的话),执行纹理坐标的平移、缩放,调用GetShadowPositionHClip计算齐次裁剪空间的坐标,填充到VertexOutput结构体中。

    ShadowPassFragment:阴影计算的片元着色主入口,调用SampleAlbedoAlpha采样反照率中的透明度,并调用Alpha进行透明度裁切。

    片元阶段不输出颜色,只输出深度信息,因为该阶段是阴影投射操作,目的是生成阴影贴图。此时投影矩阵是相机在光源位置把当前深度信息填入阴影贴图。

    GetShadowPositionHClip中参与计算的_ShadowBias来自于灯光信息面板阴影的参数设置,Bias和Normal Bias。Bias是朝着光源的方向偏移阴影,使得光源好像更远离投影体,物理上并不正确,但有助美术进行调整;NormalBias是延物体的法线反方向向内进行偏移。

    Bias的作用是为了解决阴影贴图分辨率满足不了采样时纹素数和片元一 一对应(往往远少于实际片元数量),造成多个片元在阴影贴图的同一个纹素位置采样,而产生的阶梯状现象,如左图所示,尤其当光线方向和阴影接收面的夹角很小时这个现象会尤其明显,需要通过对阴影贴图中存储的深度值做一定的偏移(这里不是对阴影贴图中的深度值做偏移,而是对当前模型的齐次裁剪空间下的深度值做偏移-最用判断该处是否有阴影是完全等价的)来避免该现象,但同时也会导致阴影位置产生错误的偏移,所以Bias值应该在满足需求的情况下尽可能小。

    NormalBias原理和Bias一样,只是会动态根据当前平面法线和光照方向的夹角 调整偏移值。

    建议只使用NormalBias 不使用Bias。

    Particles.hlsl

    SOFT_PARTICLE_NEAR_FADE:_SoftParticleFadeParams的x分量,重定义该名称便于代码阅读,顾名思义,是软粒子的近淡入距离。近淡入距离和远淡出距离如下图所示,在Shader面板上指定。

    SOFT_PARTICLE_INV_FADE_DISTANCE:_SoftParticleFadeParams的y分量,重定义该名称便于代码阅读,顾名思义,是软粒子的远淡出距离和近淡入距离的差的倒数。

    CAMERA_NEAR_FADE:_CameraFadeParams的x分量,重定义该名称便于代码阅读,顾名思义,是相机的近淡入距离。近淡入距离和远淡出距离如下图所示,在Shader面板上指定。

    CAMERA_INV_FADE_DISTANCE:_CameraFadeParams的y分量,重定义该名称便于代码阅读,顾名思义,是相机的远淡出距离和近淡入距离的差的倒数。

    vertColor:根据是否开启UNITY_PARTICLE_INSTANCING_ENABLED宏,定义为vertInstancingColor或者为空。

    vertTexcoord:根据是否开启UNITY_PARTICLE_INSTANCING_ENABLED宏,定义为vertInstancingUVs或者直接使用传入的纹理坐标。并根据是否开启_FLIPBOOK_BLENDING宏,处理纹理坐标的混合。

    vertFading:根据是否为Fading模式或软粒子,对projectedPosition进行计算和赋值的表达式,否则为空。

    fragColorMode:对于6种不同的颜色混合模式,定义了4段不同的颜色计算表达式,仅Unlit用到。

     

    _COLOROVERLAY_ON

    _COLORCOLOR_ON

    _COLORADDSUBDIFF_ON

    计算

    Multiply

     

     

     

    albedo *= i.color;

    Additive

     

     

    albedo.rgb = albedo.rgb + i.color.rgb * _ColorAddSubDiff.x;

    albedo.rgb = lerp(albedo.rgb, abs(albedo.rgb), _ColorAddSubDiff.y);

    albedo.a *= i.color.a;

    Subtractive

     

     

    albedo.rgb = albedo.rgb + i.color.rgb * _ColorAddSubDiff.x;

    albedo.rgb = lerp(albedo.rgb, abs(albedo.rgb), _ColorAddSubDiff.y);

    albedo.a *= i.color.a;

    Overlay

     

     

    albedo.rgb = lerp(1 - 2 * (1 - albedo.rgb) * (1 - i.color.rgb), 2 * albedo.rgb * i.color.rgb, step(albedo.rgb, 0.5));

    albedo.a *= i.color.a;

    Color

     

     

    half3 aHSL = RgbToHsv(albedo.rgb);

    half3 bHSL = RgbToHsv(i.color.rgb);

    half3 rHSL = half3(bHSL.x, bHSL.y, aHSL.z);

    albedo = half4(HsvToRgb(rHSL), albedo.a * i.color.a);

    Difference

     

     

    albedo.rgb = albedo.rgb + i.color.rgb * _ColorAddSubDiff.x;

    albedo.rgb = lerp(albedo.rgb, abs(albedo.rgb), _ColorAddSubDiff.y);

    albedo.a *= i.color.a;

    ALBEDO_MUL:根据是否开启_ALPHAPREMULTIPLY_ON定义为albedo或albedo.a。

    fragSoftParticles:根据是否为Fading模式或软粒子,用软粒子淡入淡出参数计算淡出值并乘以反照率,否则为空。

    fragCameraFading:根据是否为Fading模式,用相机淡入淡出参数计算淡出值并乘以反照率,否则为空。

    appdata_particles:顶点着色输入结构体,包含模型空间顶点坐标、模型空间法线、颜色、纹理坐标UV0及混合UV1(如果是翻书模式)、模型空间切线(若启用法线贴图)。

    VertexOutputLit:顶点着色输出结构体,包含颜色、纹理坐标UV0、法线UV1或UV3、切线UV1和副法线UV2(如果启用法线贴图)、翻书模式混合参数UV4(如果是翻书模式)、透视位置UV5(为Fading模式或软粒子)、世界空间坐标及雾强度UV6、视线及亮度UV7、裁剪空间坐标。

    readTexture:兼容翻书模式的纹理采样方法,返回采样到的颜色。如果是翻书模式的话,在两套UV采样到的颜色间插值(基于UV4中Z通道保存的混合系数)。

    SampleNormalTS:调用readTexture(以兼容翻书模式)采样法线贴图中的切线空间法线值,并重置到-1~1值域。

    SampleEmission:调用readTexture(以兼容翻书模式)采样自发光纹理并乘以自发光颜色。

    SampleAlbedo:调用readTexture(以兼容翻书模式)采样反照率纹理并乘以颜色值,调用fragColorMode处理颜色模式、调用fragSoftParticles处理软粒子、调用fragCameraFading处理相机淡入淡出。

    SampleSpecularGloss:调用readTexture(以兼容翻书模式)采样高光光泽纹理。

    AlphaBlendAndTest:根据透明混合模式调用AlphaDiscard处理半透明混合和透明度裁剪。这个方法在写法上有点奇怪,似乎没有必要定义局部变量result,一并放到return语句就可以了。

     

    _ALPHABLEND_ON

    _ALPHAPREMULTIPLY_ON

    _ALPHAOVERLAY_ON

    返回值

    Opaque

     

     

     

     

    Cutout

     

     

     

    1

    Fade

     

     

    alpha

    Transparent

     

     

    alpha

    Additive

     

     

    alpha

    Subtractive

     

     

    alpha

    Modulate

     

     

     

    1

    AlphaModulate:根据是否定义_ALPHAMODULATE_ON在1和反照率间根据透明度插值或者直接返回反照率。

     

    _ALPHAMODULATE_ON

    返回值

    Opaque

     

    反照率

    Cutout

     

    反照率

    Fade

     

    反照率

    Transparent

     

    反照率

    Additive

     

    反照率

    Subtractive

     

    反照率

    Modulate

    在1和反照率之间根据透明度插值

    InitializeInputData:根据VertexOutputLit结构体的数据,计算世界空间法线、视线、雾强度,阴影坐标、顶点光照、烘焙光照置0,填充到InputData结构体中。

    ParticlesPBR.hlsl

    InitializeSurfaceData:根据传入的VertexOutputLit结构体数据,调用SampleAlbedo采样反照率,根据是否启用金属光泽度纹理调用readTexture(兼容翻书效果)采样该纹理或使用统一参数,调用SampleNormalTS采样法线贴图,调用SampleEmission采样自发光贴图,调用AlphaModulate计算最终的反照率,调用AlphaBlendAndTest计算透明度和执行透明度裁剪,填充整个SurfaceData结构体中的数据。

    Shadows.hlsl

    SHADOWS_SCREEN:对于非GLES环境的级联阴影,启用屏幕阴影模式。

    ShadowSamplingData:阴影数据结构体,包含阴影半像素偏移0(负负)、1(正负)、2(负正)、3(正正)和阴影贴图尺寸(宽度的倒数、高度的倒数、宽度、高度)。

    GetMainLightShadowSamplingData:获取主光源提供的从DirectionShadowsPass.cs传入的上述阴影数据,填充ShadowSamplingData结构体并返回。

    GetLocalLightShadowSamplingData:获取局部光源(聚光灯)提供的从LocalShadowsPass.cs传入的上述阴影数据,填充ShadowSamplingData结构体并返回。

    GetMainLightShadowStrength:返回从DirectionShadowsPass.cs传入的主光源阴影强度。

    GetLocalLightShadowStrenth:返回从LocalShadowsPass.cs传入的第index个局部光源(聚光灯)阴影强度。

    SampleScreenSpaceShadowMap:已兼容XR模式的方式采样屏幕空间的阴影贴图,获取阴影衰减值。

    SampleShadowmap:调用SAMPLE_TEXTURE2D_SHADOW(在Core库中定义,主要是兼容GLES2的情况)采样阴影贴图,如果启用软阴影,则执行9向高斯模糊或简化的4向高斯模糊(移动平台)。

    ComputeCascadeIndex:根据世界坐标计算级联索引,每级的半径从DirectionalShadowsPass.cs传入,是通过CullResults的未开源代码计算出来的。推测是根据配置的级联百分比划定大致区间,但防止物体跨级联区域,所以区间会视物体情况动态微调。

    TransformWorldToShadowCoord:调用ComputeCascadeIndex计算级联索引,左乘对应索引的_WorldToShadow矩阵将世界空间坐标转换到阴影空间。

    ComputeShadowCoord:调用ComputeScreenPos(在Core.hlsl中定义)计算屏幕空间坐标。

    MainLightRealtimeShadowAttenuation:根据是否屏幕空间阴影,分别调用SampleScreenSpaceShadowMap或SampleShadowmap计算主光源的实时阴影衰减。该衰减值用于在Subtract模式下被烘焙光减掉以形成阴影(详见Lighting.hlsl的SubtractDirectMainLightFromLightmap函数)。该衰减值用于实时平行光的阴影生成,直接赋值给平行光的衰减值。平行光没有衰减,但是通过从阴影贴图采样的深度信息,作为衰减值来和无衰减(无阴影)区域形成明暗对比来模拟阴影。

    LocalLightRealtimeShadowAttenuation:调用SampleShadowmap计算局部光源(聚光灯)的实时阴影衰减。该衰减值用于在Subtract模式下被烘焙光减掉以形成阴影(详见Lighting.hlsl的SubtractDirectMainLightFromLightmap函数)。同平行光的计算,只是结果和聚光灯的衰减值相乘,所以在聚光灯的中心和离光源近的地方阴影会非常明显,靠近边缘阴影会淡化。

    LightweightStandardTerrain.shader

    提供了前向、产生阴影、深度计算3个Pass,实现了标准的简化(可调参数较少,但底层实现也是调用标准PBR接口执行的计算)PBR地形渲染。标记为依赖Standard Terrain Add Pass(地形用到的贴图超过4套时,从引用的第5套贴图开始会被使用这个Shader来渲染)和Standard Terrain Base(据说是在不能支持4套贴图的设备上使用这个Shader来渲染,只会用到1套贴图,差不多和Fallback “Diffuse”一样没法看)。

    LightweightStandardTerrainAddPass.shader

    仅提供了前向1个Pass,地形用到的贴图超过4套时,从引用的第5套贴图开始会被使用这个Shader来渲染。

    LightweightStandardTerrainBase.shader

    提供了前向、产生阴影、深度计算、烘焙4个Pass,据说是在不能支持4套贴图的设备上使用这个Shader来渲染,只会用到1套贴图,差不多和Fallback “Diffuse”一样没法看。想来地形在烘焙时也是Fallback到这个Shader的。

    LightweightWavingGrass.shader

    提供了标准着色、深度计算2个Pass,通过InputSurfaceGrass.hlsl、LightweightPassLitGrass.hlsl、LightweightPassDepthOnlyGrass.hlsl三个文件中提供的函数,绘制随风摆动的草地。

    在地形设置中指定风的参数来控制草的波动幅度。

    默认是用下面那个公告板,不清楚这个是在什么地方用到。

    LightweightWavingGrassBillboard.shader

    提供了标准着色、深度计算2个Pass,通过InputSurfaceGrass.hlsl、LightweightPassLitGrass.hlsl、LightweightPassDepthOnlyGrass.hlsl三个文件中提供的函数,绘制随风摆动的草地。

    在地形设置中指定风的参数来控制草的波动幅度。

    和LightweightWavingGrass.shader唯一的区别在于进行顶点计算时,是否按公告板的算法来进行。地形系统默认是使用这个Shader来渲染草。

    LightweightBlit.shader

    顾名思义,进行渲染对象的拷贝,代码简单到令人发指。

    LightweightCopyDepth.shader

    利用DepthCopy.hlsl中的代码机型深度纹理的拷贝,由于多重采样抗锯齿的关系,和上面那个LightweightBlit.shader相比还是略复杂些。

    LightweightSampling.shader

    拷贝过程中进行降采样的Shader,和LightweightBlit.shader基本相同,只是多了一步降采样计算。

    LightweightScreenSpaceShadows.shader

    顾名思义,为屏幕空间阴影。

    VertexInput:顶点着色的输入结构体,包含模型空间顶点坐标、纹理坐标UV0、instanceID(如果启用Instance的话)。

    Interpolators:顶点着色的输出结构体,包含齐次裁剪空间坐标、纹理坐标UV0、以及XR相关的双眼数据

    Vertex:顶点着色主入口,将顶点坐标变换到屏幕空间,基于XR计算双眼纹理坐标。

    Fragment:初始化双眼数据(如果启用XR的话)。片元着色主入口,将相机的坐标变换到视口空间和世界坐标。调用SampleShadowmap计算屏幕空间阴影。

    对屏幕空间阴影,只能计算实时平行光也就是主光源的阴影。屏幕空间阴影的计算要比正常的计算做更多的空间变换,但是可以作为后处理使用,更加灵活,也可以通过降采样来节省开销。推荐使用。

    LightweightStandard.shader

    提供了前向、产生阴影、深度计算、烘焙4个Pass,最常用的PBR Shader。

    LightweightStandardParticles.shader

    提供了前向1个Pass,其它的Pass通过Fallback实现。标准的粒子Shader。

    LightweightStandardParticlesSimpleLighting.shader

    提供了前向1个Pass,其它的Pass通过Fallback实现。简化光照的粒子Shader。

    LightweightStandardParticlesUnlit.shader

    提供了1个默认Pass。无光照计算的粒子Shader。

    LightweightStandardSimpleLighting.shader

    提供了前向、产生阴影、深度计算、烘焙4个Pass,简化光照的标准Shader。

    LightweightStandardUnlit.shader

    提供了前向、产生阴影、深度计算、烘焙4个Pass,无光照的标准Shader。

    展开全文
  • Unity3d 周分享(22期 2019.8.30 )

    千次阅读 2019-09-29 17:29:04
    选自过去1~2周 自己所看到外文内容:https://twitter.com/unity3d 和各种其他博客来源吧 早就有了,抱歉才发! 1、 Unity Transform 性能优化摘要 https://qiita.com/sator_imaging/items/ff5811885f515a0a4998 ...
  • Unity3d 2017

    2019-07-11 11:50:20
    Unity3d引擎的新纪元——Unity3d 2017 来源 http://blog.csdn.net/dark00800/article/details/75209544 Unity3d不久之前正式发布了Unity3d 2017.1, 这个版本的发布也宣告了Unity3d正式告别了5.x时代,并且...
  • 文章目录一、3D模型外描边效果二、如何使用三、shader代码 一、3D模型外描边效果 二、如何使用 将最下面的shader代码保存为SilhouettedDiffuse.shader文件,创建一个material材质球:Outline.mat,将...
  • 今天做法线可视化工具 想先弄个模型的线框显示 网上查...使用引擎版本Unity2019.2 (版本区别不大,支持Geometry Shader就行) 新建一个材质和Shader,然后材质选择该Shader Shader文件: https://download.csdn....
  • 线框Shader的渲染在游戏应用上还是有一定的需求,这次分享一个伪的线框渲染Shader。之所以称之为伪线框,是因为真正的线框应该渲染的是线,这在常规上是使用几何体着色器输出线段图元来实现。但是几何体着色器是...
  • 两个牛叉哄哄的Unity3d Shader编辑器

    千次阅读 2013-07-12 18:55:10
    【AssetStore经验分享】今天遭吓到了。。   ...自己做的插件Xffect Editor Pro ,去年8月放到AssetStore上卖,75美刀一份,断断续续每个月也可以卖10来份。...直到上周那边发个邮件问我需不需要做减价促销,起初我...
  • 效果如下: 话不多说直接上代码,可以更改外轮廓...// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Custom/OutlineShader1" { Properties{ _MainTex("Albedo ...
  • Unity 2017.1正式版发布

    2017-07-27 21:09:06
    Unity 2017.1正式版现已发布,这也标志着Unity 2017产品周期的开始,将全球最受欢迎的游戏引擎变成不断壮大的游戏与实时互动娱乐内容创作平台,专注于帮助各型团队改善工作流程并获得成功。 立即下载使用最新的...
  • Shader smoothstep实现线条渐变色

    千次阅读 2019-03-29 17:41:36
    Shader smoothstep实现线条渐变色效果展示具体实现线条创建创建Shader(LineGradualColor)Shader源码Shader源码分析 效果展示 细节说明(也是下面准备shader实现的三个要点): 线条有三段颜色拼接(代号1 2...
  • Unity 中的 Mesh 及绘制圆环

    千次阅读 2017-05-09 22:48:35
    Mesh 又称网格组件, 是 Unity 中一个重要的概念。什么是 Mesh:简单的说,3D 模型上一个个的网格就是 Mesh 。3D 模型是由多边形拼接而成的, 而多边形是由多个三角形拼接而成。我们将构成这些三角行的点以及边的...
  • Unity3D组件

    2015-07-16 19:50:00
    组件(Component):一切的GameObject(游戏对象)都是用于实现不同功能组件的集合,就是游戏对象实现其用途的功能件。 每个基本几何在创建时默认有4个Component(组件)。 基本组件 1.Mesh:网格,该类型的组件有3项 ...
1 2 3
收藏数 58
精华内容 23
关键字:

unity3d 发光的线条