烘焙分辨率影响烘焙的结果

烘焙是针对静态物体的

烘焙贴图的精度影响物体的效果
在这里插入图片描述

这些物体都是静态的,这些物体使用的材质都是默认的diffuse材质。

第一次设置其分辨率为:
在这里插入图片描述

可以看到明显的明暗分界线。

第二次设置为:
在这里插入图片描述

明显好一点。

第2,如何采样烘焙贴图的数据

下面是初步的shader:My Lighting.cginc

#include "AutoLight.cginc"

struct VertexData
{
	float4 vertex:POSITION;
	float2 uv1:TEXCOORD1;	
};

struct Interpolators 
{
	float4 pos:SV_POSITION;
	float2 lightmapUV:TEXCOORD1;
};

struct FragmentOutput
{
	float4 color:SV_Target;	
};

Interpolators MyVertexProgram(VertexData v)
{
	Interpolators i;
	i.pos = UnityObjectToClipPos(v.vertex);
	i.lightmapUV = v.uv1 * unity_LightmapST.xy + unity_LightmapST.zw;
	return i;
}

FragmentOutput MyFragmentProgram(Interpolators i)
{
	FragmentOutput output;
	output.color = float4(DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.lightmapUV)),1);
	return output;
}
Shader "Unlit/My First Lighing Shader"
{
	Properties
	{
	}
	SubShader
	{
		
		Pass
		{
			Tags{
				"LightMode" = "ForwardBase"
			}

			CGPROGRAM
			#pragma vertex MyVertexProgram
			#pragma fragment MyFragmentProgram
			#include "UnityCG.cginc"
			#include "My Lighting.cginc"
			ENDCG
		}
	}
}

针对上面的程序,我简单的做一个小节:
在cginc文件中,我们定义了顶点处理函数,片元处理函数。
使用 i.lightmapUV = v.uv1 * unity_LightmapST.xy + unity_LightmapST.zw;方法计算光照贴图纹理坐标。
使用float4(DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.lightmapUV)),1);进行采样光照贴图。
在shader文件中,定义了一个ForwardBase路径,此段shader非常简单,完成了对光照贴图的采样。

增加forwardadd通道

关于这个通道存在的意义,我要详细的说明一下。
1、unity为什么要提供一个add通道呢?
2、什么是像素灯呢?
3、unity里面最多支持多少个像素灯呢?
4、如何改变默认的像素灯的个数呢?
5、每个像素灯在哪里通道渲染呢?
6、多个像素灯,怎么取得灯光的颜色呢?
7、forwardadd通道对于静态物体和动态物体的都有用吗?

下面我们来一个一个解答这些问题。
1、unity为啥要提供一个add通道呢?
首先forwardadd通道是针对向前渲染的,其他的渲染方式如逐顶点渲染或者延迟渲染是没有forwardadd通道的。
其次,要查下unity的官网是如何介绍的:
https://docs.unity3d.com/Manual/RenderTech-ForwardRendering.html

**Base Pass** Base pass renders object with one per-pixel directional light and all SH/vertex lights. This pass also adds any lightmaps, ambient and emissive lighting from the shader. Directional light rendered in this pass can have Shadows. Note that Lightmapped objects do not get illumination from SH lights.

Note that when “OnlyDirectional” pass flag is used in the shader, then the forward base pass only renders main directional light, ambient/lightprobe and lightmaps (SH and vertex lights are not included into pass data).

基础通道
一个平行光且是像素灯还有其他的所有的顶点灯/SH都在这个通道计算。
这个通道还用来计算光照贴图,环境光,以及自发光。
这个通道计算的平行光可以计算阴影。
注意使用光照贴图的物体不接受SH光照,因为直接使用光照贴图。

注意当使用标签"OnlyDirectional"通道标志,那么基础通道则只能渲染主要平行光,环境光/光探针以及光照贴图。(SH和顶点光则不能在这个通道计算)。

**Additional Passes** Additional passes are rendered for each additional per-pixel light that affect this object. Lights in these passes by default do not have shadows (so in result, Forward Rendering supports one directional light with shadows), unless multi_compile_fwdadd_fullshadows variant shortcut is used. 附加通道 附加通道是针对每个额外的像素灯进行渲染计算的通道。这个通道的灯光默认是没有阴影计算的。因此向前渲染只支持一个平行光的阴影计算。除非使用multi_compile_fwdadd_fullshadows 增加shader的特性。

ok,到这里还是一头雾水,那么还是要再组织下逻辑。

首先,基础通道只能计算一个最重要的像素灯。还可以进行光照贴图的采样。
然后,其他的像素灯则要放在附加的通道中计算。

这就是最简洁的描述了。

2、什么是像素灯呢?

明白像素灯的前提是明白渲染方式,在https://docs.unity3d.com/Manual/RenderTech-VertexLit.html
提到了逐顶点渲染的方式:

Vertex Lit path generally renders each object in one pass, with lighting from all lights calculated for each vertex. It’s the fastest rendering path and has the widest hardware support. Since all lighting is calculated at the vertex level, this rendering path does not support most per-pixel effects: shadows, normal mapping, light cookies, and highly detailed specular highlights are not supported.

顶点渲染路径通常在一个通道渲染每个物体,按照逐顶点的方式计算所有灯光对其影响结果。它是最快的渲染路径。也因为是按照逐顶点的方式计算,此渲染路径不支持基于像素的效果:比如,阴影,法线映射,灯光cookies,还有镜面反射灯。

所以像素渲染,是顶点经过光栅化之后,对每个像素进行计算渲染结果。所以这个灯到底是否是像素灯,则要看摄像机采样何种渲染路径。

3、unity里面最多支持多少个像素灯呢?
4、如何改变默认的像素灯的个数呢?
这个在QualitySettings中进行设置:在这里插入图片描述
关于这里还要再次说明一下,如果一个灯强制设置为important,那么即使超过了这里设置的数字,这个灯依然会作为像素灯继续处理。
这里的数字,只会对那些全部是auto模式灯才有作用,如果所有的都是auto,那么像素的灯的个数最多为这个默认设置的数字,当然你可以调整为其他数字。

5、每个像素灯在哪里通道渲染呢?
上面已经说过,forwardbase通道只支持一个像素灯的计算,其他的像素灯则安排在forwardadd通道计算。

6、多个像素灯,怎么取得灯光的颜色呢?
举例说明:
如果有4个像素灯,分别为A、B、C、D,而且他们的重要程度依次递减,那么A则在Base中渲染,其余的灯则在Add中渲染。
可以使用FrameDebug工具,查看每个灯的渲染结果。
如何取得颜色,其实很好理解,无论是在Base中还是在Add中,都可以使用_LightColor0来取得ABCD灯的颜色。因为他们是串行执行的渲染,所以当处理A的时候,这个_LightColor0则是A的颜色;在处理B的时候,这个_LightColor0则是B的颜色,以此类推。
那有人会问,最终到底是什么颜色,这要看你是怎么混合的,在forwardadd中,你是使用one zero混合还是其他的混合模式,这个最终影响颜色的结果,但是渲染的每个步骤,都是可以再framedebug中看到其物体颜色的变化。

7、forwardadd通道对于静态物体和动态物体的都有用吗?
forwardadd,并不区分什么是静态物体还是动态物体。它对这个没有概念。首先要明白,这两个完全不是同一个问题,之所以混淆,搞不清楚,是因为不知道如何写自定义的shader去采样烘焙结果。下面详细的讲解下。

首先,静态物体和动态是什么?
静态物体顾名思义,就是场景中不会动的物体,如建筑、花草、树木、高山等,这些都是不会像主角一样,到处乱跑。
那么unity为了实现光影效果,对这些静态物体提供了一个标签,用来标记这些物体是静态。
静态的好处是什么呢?
这样和计算光照搭上了,首先实时光照是计算了光对物体的影子效果,而且物体走到哪里,影子就要跟随到哪里,这就是实时的计算。
那么能不能对静态物体不要实时计算影子呢?不要实时计算灯光对静态物体的影响呢?以及考虑灯光打到一个物体上,这个灯光会再次被反射,然后去影响其他的物体,这个光线跟踪的开销在实时计算中,肯定会很耗,所以unity在实时计算的时候只是计算一次光照对物体的影响,而没有考虑多次反射灯光的效果,这个也就是直接光照的术语了。
而经过其他物体的反射光的影响,实时灯光不计算,那么必然损失了很多的立体感觉。unity是如何解决的呢?答案是通过烘焙,将物体之间的反射光经过预先烘焙到一个贴图上,然后去采样即可实现间接光的效果。

这样最终的效果如果是:直接光+间接光=最终效果,具有很好的立体感、真实感。
所以静态物体,动态物体是针对烘焙来讲的,和渲染路径没有关系。

然后回到这个问题,那么一个物体的渲染,则是需要用到材质,材质就对应了shader,材质和shader的关系,就是一个是产品、一个是加工过程。什么样的算法实现是在shader中写的,最终的效果是shader算出的结果也就是材质。
那么问题来了,如何去渲染一个物体呢?这里有forward渲染方式,所以foward是和渲染相关。

一个物体是静态的,那么依然是可以使用forwardadd路径渲染的,比如说,你烘焙之后,我们并不一定要使用光照贴图,完全可以自己写shader去改变它的颜色,这个完全可以做到。那么计算的时候,你可以给他任意的颜色,可以有多个实时光去影响这个物体,这个和烘焙、静态与否没有半点关系。

唯一要做的是保证正确性,一个物体是静态的,那么其目的是在烘焙中使用,而烘焙之后,会得到光照贴图。得到了光照贴图,你自然会想到如何去使用这个贴图,那么怎么使用呢?哦,光照贴图是在fowardbase中去采样计算。那么forwardadd呢对其是否还有作用,当然可以有也可以没有,什么时候有作用呢,在场景中还有其他的实时的像素灯,超过一个,因为第一个重要的实时灯在forwardbase中计算,这里所说的实时,是灯光的模式为realtime,或者是mixed,而不是baked模式,因为baked模式全部被烘焙到光照贴图了,这个灯就没用了。只有realtime或者是mixed则还可以用于实时计算。那么此时就要用到forwardadd通道。

这里就介绍到这里,关于如何对于透明物体、半透明物体、cutoff物体、以及阴影下一节在详细介绍。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值