当前位置: 首页 > news >正文

如何将自发光和漫反射添加到烘焙贴图中

在https://blog.csdn.net/wodownload2/article/details/94431040
一节中,我们只是简单的进行光照贴图的采样。
https://blog.csdn.net/u012871784/article/details/81179432
但是这个教程的局限性太大了

下面我们要考虑的首要问题就是如何将自发光和漫反射光加入到烘焙贴图中,以至于能够影响间接,实现gi效果。

之前的shader不变,还是保持:

Shader "MyShader/SampleLightmap"
{
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile _ LIGHTMAP_ON
			#include"Lighting.cginc"

			struct VertexData
			{
				float4 pos:POSITION;
				float2 uv:TEXCOORD0;
				float2 uv1:TEXCOORD1;
			};

			struct V2F
			{
				float4 pos:SV_POSITION;
				float2 uv:TEXCOORD0;
				#if defined(LIGHTMAP_ON)
					float2 uv1:TEXCOORD1;
				#endif
			};


			V2F vert(VertexData v)
			{
				V2F res;
				res.pos = UnityObjectToClipPos(v.pos);
				res.uv = v.uv;
				#if defined(LIGHTMAP_ON)
				res.uv1 = v.uv1 * unity_LightmapST.xy + unity_LightmapST.zw;
				#endif
				return res;
			}

			fixed4 frag(V2F i) :SV_TARGET
			{
				fixed4 col = fixed4(1,0,0,1);
				#if defined(LIGHTMAP_ON)
					col.rgb = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uv1));
				#endif
				return col;
			}
			ENDCG
		}
	}
}

这个shader的效果只是在有烘焙贴图的时候采样烘焙贴图,无烘焙的时候默认给颜色红色(1,0,0,0,1)。

下面我们就要再编写一个通道,其LightMode=“Meta”,这样就能够将自发光和漫反射添加到烘焙结果中去了。

如下所示:

Shader "MyShader/SampleLightmap"
{
	SubShader
	{
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile _ LIGHTMAP_ON
			#include"Lighting.cginc"

			struct VertexData
			{
				float4 pos:POSITION;
				float2 uv:TEXCOORD0;
				float2 uv1:TEXCOORD1;
			};

			struct V2F
			{
				float4 pos:SV_POSITION;
				float2 uv:TEXCOORD0;
				#if defined(LIGHTMAP_ON)
					float2 uv1:TEXCOORD1;
				#endif
			};


			V2F vert(VertexData v)
			{
				V2F res;
				res.pos = UnityObjectToClipPos(v.pos);
				res.uv = v.uv;
				#if defined(LIGHTMAP_ON)
				res.uv1 = v.uv1 * unity_LightmapST.xy + unity_LightmapST.zw;
				#endif
				return res;
			}

			fixed4 frag(V2F i) :SV_TARGET
			{
				fixed4 col = fixed4(1,0,0,1);
				#if defined(LIGHTMAP_ON)
					col.rgb = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uv1));
				#endif
				return col;
			}
			ENDCG
		}


		Pass
		{
			Tags{ "LightMode" = "Meta" }

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityStandardInput.cginc"
			#include "UnityMetaPass.cginc"

	
			struct V2F
			{
				float4 pos:SV_POSITION;
				float4 uv:TEXCOORD0;
			};


			V2F vert(VertexInput v)
			{
				V2F o;
				o.pos = UnityMetaVertexPosition(v.vertex, v.uv1.xy, v.uv2.xy, unity_LightmapST, unity_DynamicLightmapST);
				o.uv = TexCoords(v);
				return o;
			}

			fixed4 frag(V2F i) :SV_TARGET
			{
				UnityMetaInput o;
				UNITY_INITIALIZE_OUTPUT(UnityMetaInput, o);
				o.Albedo = fixed3(1, 1, 0); //这里只是将漫反射添加到烘焙贴图中去
				return UnityMetaFragment(o);
			}
			ENDCG
		}
	}
}

几点说明:
1、meta的pass中,在计算uv的时候需要注意,由于是在光照贴图空间所以需要这么写。
2、UnityMetaInput中包含的分量,可以参考:UnityMetaPass.cginc

struct UnityMetaInput
{
    half3 Albedo;
    half3 Emission;
    half3 SpecularColor;
};

包含了三个量:漫反射、自发光、镜面光

3、UnityMetaFragment函数也在UnityMetaPass.cginc中,可以参考下。

经过上面的编写之后,将所有的物件的材质指定我们的shader进行渲染,烘焙之前为默认红色、烘焙之后:
在这里插入图片描述

看到没有有间接光的效果了,并且这个黄色使我们加入的漫反射的颜色。
如果我们换为绿色:

	fixed4 frag(V2F i) :SV_TARGET
	{
		UnityMetaInput o;
		UNITY_INITIALIZE_OUTPUT(UnityMetaInput, o);
		o.Albedo = fixed3(0, 1, 0);
		return UnityMetaFragment(o);
	}

则其烘焙之后的结果为:
在这里插入图片描述

可以看到也是符合我们预期的。

我们也可以将自发光也加入进去:

	fixed4 frag(V2F i) :SV_TARGET
	{
			UnityMetaInput o;
			UNITY_INITIALIZE_OUTPUT(UnityMetaInput, o);
			o.Albedo = fixed3(1, 0, 0);
			o.Emission = fixed3(0, 1, 0);
			return UnityMetaFragment(o);
		}

这里漫反射为红色,自发光为绿色,最后应该得到黄色的间接光效果:
在这里插入图片描述

测试结果正确。有些时候你可能遇到,unity没有将这些自发光和漫反射光加入到烘焙贴图中去,是因为,需要设置:

foreach (Material m in editor.targets) {
				m.globalIlluminationFlags =
					MaterialGlobalIlluminationFlags.BakedEmissive;
			}

这个就需要自定义shader的gui,遍历材质球,将其自发光的加入到烘焙中去即可。
此部分可参看:https://catlikecoding.com/unity/tutorials/rendering/part-16/的3.5节即可。

相关文章:

  • Qt+QGIS二次开发:QGIS中使用QgsRubberBand类创建临时图形
  • Shadowmask和Distance Shadowmask的区别
  • Angular7_获取异步方法里面的数据
  • maven tomcat jstl 异常
  • maven下载及配置(win7 64位系统)
  • 寒假一:打印沙漏
  • unity depth texture-01
  • LinearEyeDepth和Linear01Depth
  • 打印沙漏
  • SQLAlchemy增删改查 一对多 多对多
  • 体积光,体积雾——链接
  • python 变量搜寻顺序法则LEGB之E注意事项
  • 体积雾
  • Java线程池详解(一)
  • 穷人为什么穷?
  • ES6指北【2】—— 箭头函数
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • Java教程_软件开发基础
  • Nodejs和JavaWeb协助开发
  • PHP的类修饰符与访问修饰符
  • quasar-framework cnodejs社区
  • vuex 学习笔记 01
  • 前端技术周刊 2018-12-10:前端自动化测试
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 巧用 TypeScript (一)
  • 深入浅出webpack学习(1)--核心概念
  • 微信支付JSAPI,实测!终极方案
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • ​​​​​​​​​​​​​​Γ函数
  • # 计算机视觉入门
  • # 透过事物看本质的能力怎么培养?
  • #LLM入门|Prompt#3.3_存储_Memory
  • (1)(1.13) SiK无线电高级配置(五)
  • (a /b)*c的值
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (笔试题)分解质因式
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (六)c52学习之旅-独立按键
  • (六)Hibernate的二级缓存
  • (篇九)MySQL常用内置函数
  • (十一)c52学习之旅-动态数码管
  • (图)IntelliTrace Tools 跟踪云端程序
  • (一)appium-desktop定位元素原理
  • (一)基于IDEA的JAVA基础1
  • (转)一些感悟
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .net 8 发布了,试下微软最近强推的MAUI
  • .Net Web窗口页属性
  • .Net Web项目创建比较不错的参考文章
  • .pyc文件是什么?
  • /bin/bash^M: bad interpreter: No such file ordirectory
  • /etc/X11/xorg.conf 文件被误改后进不了图形化界面
  • @RequestBody详解:用于获取请求体中的Json格式参数
  • [AIGC] Spring Interceptor 拦截器详解