Unity3D

Volumetric Clouds Write-up(翻译)

原文地址 The basis of this effect is drawing a vertical stack of quads, each one showing a slice of the cloud. The cloud texture itself is just a world-mapped, top-down animated noise that is piped into opacity. 这种效果的基础是绘制一组垂直堆叠的四边形(简称为:四边形堆栈,vertical stack of quads),每个四边形都显示一片云。 云纹理本身只是一个世界映射的(world-mapped)、自上而下的(top-down)的动画噪声,它通过渲染,管道传输到不透明度中。 To animate the noise, I use the same trick that I use in countless other shaders to create a natural looking motion that appears free of obvious repetition, which is to blend the noise with either a copy of itself with a different UV scale, or a different noise texture, and pan these two noise textures against each other in opposite directions, and then blend them together through multiplication or some other desired blend mode.

Unity纹理压缩格式详解

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com Crunch compression(紧凑压缩) Crunch compression是一种建筑在DXT或ETC压缩之上的压缩格式,提供额外的可变比特率压缩。当Unity加载紧凑压缩的纹理时,它会在CPU上将纹理解压缩为DXT或 ETC,然后将DXT或ETC压缩的纹理数据上传到GPU。 紧凑压缩有助于纹理使用尽可能少的磁盘空间,但对运行时内存使用没有影响。紧凑压缩 纹理可能需要很长时间来压缩,但运行时的解压缩速度相当快。您可以调整紧凑压缩的有损程度,以在文件大小和质量之间取得平衡。 Unity的各种纹理压缩格式信息 参考网页 聊聊 Unity 的 Alpha Is Transparency 有什么用 What does the “alpha is transparency” setting actually do? 光照贴图的中的编码格式

从半透明模型的描边到URP Multipass Rendering

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 卡通渲染技术中,描边的实现的有多种做法,有基于后处理实现,也有基于非后处理,通过多次绘制模型的方法实现。 通过多次绘制模型的实现,方法无非就是: 绘制模型本体,同时写入深度值。 让模型顶点沿着法线外扩一定的偏移量,即让模型膨胀一些 全用描边的颜色绘制膨胀过的模型,且,在绘制时,使用cull front,即只绘制模型的背向摄像机面。在第1步中因为绘制模型本体时已经写入深度值。在本步骤中只要不改变深度测试函数的方式,那么除了膨胀部分之外,是无法写入像素的,能写入的部分,便形成了边缘。 上述的方式,一般应用于不透明的材质上。如果是半透明的材质的话就有问题,因为在第1步绘制半透明材质时,一般是不写入深度值的。那么第3步在绘制膨胀模型时,模型背部的地方就会被绘制上去。 解决这个问题有很多,可以利用stencil test的方式。也可以在第一步绘制,不绘制任何颜色,只写入深度,然后再绘制模型,最后再绘制描边。后一种方法,如果用Unity内置管线,大约就是这个样子: Shader "Unlit/半透明" { Properties { _Diffuse("Diffuse",Color) = (1,1,1,1) // 漫反射 _MainTex("MainTex",2D) = "white"{} // 2D纹理贴图 _AlphaScale("Alpha Scale",Range(0,1)) = 1 // 控制Alpha参数 } SubShader { Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" } //渲染顺序设置Transparent LOD 100 // 用两个pass通道来处理,防止出现渲染错误,第一个pass通道 // 每个pass通道都会渲染一次 Pass { ZWrite On // 注意这里:写入深度 为了确认渲染顺序 ColorMask 0 // 掩码遮罩代表这个pass通道不写入任何颜色值 } Pass // 第二个pass通道 { Tags{"LightMode" = "ForwardBase"} ZWrite Off // 注意这里:关闭ZWrite(深度写入) Blend SrcAlpha OneMinusSrcAlpha // 源颜色因子 正常透明混合 CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.

彻底弄懂Unity3D的光照模式,光照贴图和光探针(持续更新)

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 1 光源的Light Mode 光源的Light Mode分为Realtime,Baked,Mixed四种。 Realtime类型 本类型的光源,会根据Shadow Distance项指定的值,以及当前摄像机的位置值,去敲定本光源是否给物体投下阴影。在URP中,Shadow Distance值在Universl Render Pipeline Asset中指定。 在旧管线中,如果启用了【Realtime Global Illumination】选项,realtime光源仅贡献实时的直接光照部分。正因为如此,所以由这种光源产生的影子是纯黑的,不会受别的间接光照的影响 在自定义的管线中,实时光源可以对实时的间接光照部分产生贡献。 Baked类型 Unity把Baked类型的光源产生的照明和阴影信息,烘焙到lightmap或者light probe中。 baked类型的光源,只贡献了漫反射部分的光照,不贡献镜面高光部分的光照。 只有标识为static的GameObject才接受baked类型的光源产生的照明和阴影。 Mixed类型 mixed类型,顾名思义,即是整合了realtime和baked两种模式的特点。采用mixed类型的光源,可以在其贡献的直接光照部分,使用realtime的模式实现,间接光照部分,使用baked模式实现。 在场景中,mixed类型的光源的行为,依赖于【Lighting】窗口中的【Lighting Mode】属性设置。不同的设置,会产生不同的视觉保真度,以及产生不同的性能消耗。 在运行时,可以更改mixed类型的光源的属性。但仅对realtime部分的属性生效。 2【Lighting】窗口中的【Lighting Mode】属性 直接光照的实现模式 间接光照的实现模式 阴影的实现模式 适用机型 Baked Indirect real-time baked real-time 中端机型 Shadowmask real-time baked 部分baked,部分real-time 中高端机型 Subtractive baked baked 只对一个平行光渲染real-time阴影 低端机型 Baked Indirect光照模式的一些细节 内置管线,URP,HDRP,都支持本模式 在本模式下,Mixed类型的光源照射到GameObject时,GameObject会收到以下的光影信息如下表: Shadowmask光照模式的一些细节 与baked indirect模式类似,Shadowmask模式也结合了实时直接光照和烘焙间接光照。但两者不同之处在于在于渲染阴影的方式。Shadowmask模式允许Unity在运行时结合baked阴影和real-time阴影,并在远处渲染阴影。它通过使用额外的光照贴图 纹理称为阴影蒙版,并通过将附加信息存储在光探头。 Shadowmask模式提供所有模式下保真度最高的阴影,但性能成本和内存要求最高。 不同渲染管线对Shadowmask模式的支持程度 管线类型 是否支持 内置管线 支持 URP 从10.1版本开始支持 HDRP 支持 Shadowmask模式有两种,一种是Distance Shadowmask,另一种是Shadowmask。在Project Setting界面的Quality选项可以指定,如下图所示:

Unity动态加载光照贴图的坑

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com Unity的光照贴图,如果在运行时动态加载的话,需要对创建出来的game object的lightmap index做一次重新指派, 然后在设置一下LightmapSetting。基本按照Mr.钱康来的这一系列文章那样子设置。如下链接: Unity中光照贴图一二坑及解决办法 Unity中光照贴图一二坑(续) 如果按照老钱的方法去做了,还是有问题的话,那么就要看下 【Project Settings -> Graphics -> Shader Stripping】 菜单下的这个: 就是打包时没把LIGHTMAP_ON相关的shader变体给打进去,因为被strip掉。为了保险,选中Custom,然后所有全部选上,再进行打AB。就能正确加载光照贴图。当然,这样子会导致变体变多变大,所以最好还是仔细分析下,那些勾选上为好。 国内有一个兄弟也是碰到这个问题,在Unity论坛上也有人用这个方案解决了问题 另外,经过实测,只要正确设置好shader stripping之后,无论从AB中装载进来的game object,是不是从static变为非static标签,或者有没有用StaticBatchingUtility.Combine去运行时静态合批,都不影响正确加载lightmap 参考网页 光照贴图接缝探讨 where did “lightmap static” go 打包Assetbundle以及Shader Stripping导致LightMap全部丢失的解决方法 UWA上的《Lightmap丢失》 Shader Variants 打包遇到的问题 Stripping scriptable shader variants Stripping commonly unused shader variants in Unity’s built-in render pipeline Unity帮助文档中和Shader Stripping相关的页面

Unity卡通渲染知识点笔记(持续更新中)

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com 描边 描边有两种方法,一种是用两个pass,第一个pass绘制模型本身,第二个pass则是绘制边缘。这种技术的要点是在第一个pass使用cull back把背面拣选掉,第二个pass使用cull front 把正面拣选掉,这时候就只剩下侧边的边缘线颜色。 在第二个pass中,在绘制时,让模型顶点沿着法线方向向外移动一定的距离。这时候绘制出的一个纯色模型把原来的模型给包住。但如果是在世界空间中移动的话,当镜头拉远时,描边线会变得很细小。所以为了解决这个问题,一般将法线在裁剪空间中或者在NDC空间中做位移: 在裁剪空间中做位移的操作如下: // 这段代码是一段URP代码 Varyings vert(Attributes input) { // scaledScreenParams 是用当前窗口的屏幕宽高像素值乘以渲染缩放系数renderScale的值。renderScale默认为1, float4 scaledScreenParams = GetScaledScreenParams(); float aspect = abs(scaledScreenParams.x / scaledScreenParams.y);//求得X因屏幕比例缩放的倍数 // 下面的计算是在裁剪空间中操作。当然也可以直接将法线转到NDC Varyings output; VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz); VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS); float3 normalCS = TransformWorldToHClipDir(normalInput.normalWS);//法线转换到裁剪空间 float2 extendDis = normalize(normalCS.xy) *(_OutlineWidth*0.01);//根据法线和线宽计算偏移量 extendDis.x /= aspect ;//由于屏幕比例可能不是1:1,所以偏移量会被拉伸显示,根据屏幕比例把x进行修正 output.positionCS = vertexInput.positionCS; // 因为后续会转换成NDC坐标,会除w进行缩放,所以先乘一个w,那么该偏移的距离就不会在NDC下有变换 output.positionCS.xy += extendDis * output.positionCS.w ; // 要预先乘一个做透视除法的值 return output; } 在NDC空间做变换代码如下: // 这是一段基于Unity内建管线的顶点着色器代码 v2f o; UNITY_INITIALIZE_OUTPUT(v2f, o); float4 pos = UnityObjectToClipPos(v.

URP和内建管线的一些编程上的差异

请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com SubShader代码中的Tags 新增加了RenderPipeline关键字 SubShader的Tags段中需添加 "RenderPipeline" = "UniversalPipeline"语句段 光照模式(LightMode)关键字的对应替换 Built-in URP 作用 ForwardBase UniversalForward ForwardAdd 开启关键字_ADDITIONAL_LIGHTS解决 ShadowCaster ShadowCaster MotionVectors 尚未支持 Always 不再支持 PrepassBase 不再支持 PrepassFinal 不再支持 Vertex 不再支持 VertexLMRGBM 不再支持 VertexLM 不再支持 URP新增 DepthOnly URP新增 Meta 用于烘焙光照贴图 URP新增 Universal2D 用于2D的前向渲染 URP新增 UniversalGBuffer Deferred Rendering(延迟渲染)中使用,目前URP不支持延迟渲染,暂时用以兼容HDRP URP新增 UniversalForwardOnly 用于在Deferred Rendering(延迟渲染)中,表示这个Pass使用Forward Rendering(前向渲染) 变体相关的指令 内建管线中,提供了multi_compile_fwdbase来编译所有ForwardBasePass所需要的变体,multi_compile_fwdadd来编译ForwardAddPass所需要的所有变体,类似如下代码: #pragma multi_compile_fwdbase 而在URP中,需要自己判断需要编辑哪些变体,用户又更大的灵活性,类似如下(参考Lit.Shader): #pragma multi_compile _ _MAIN_LIGHT_SHADOWS #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS #pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile _ _SHADOWS_SOFT #pragma multi_compile _ _MIXED_LIGHTING_SUBTRACTIVE 参考网页 从 Builtin 管线升级到 URP