ShaderLab学习小结(十)简单的支持光照贴图的shader
  5WVVrgL6K2nc 2023年11月02日 36 0

场景中建一个plane,一个cube一个cylinder 把场景平行光的强度调低一些,再加一个点光源,设置为绿色吧,俗话说的好:爱是一道光,绿到你发荒…… 把点光源的shadowtype设置为hard shadow(默认的是无阴影) 如上图,平行光和点光源都产生了阴影。

要烘焙lightmap,就要把被烘物体设置上lightmap static 平行光和点光源都把Baking设置为Baked 在lighting面板中,把Ambient GI选成Baked 烘出来感觉暗一些,稍微把General GI里的indirect Intensity调高一些到1.5(这个不为追求什么效果) 把底下的auto前面的勾选取消掉,再点击Build 然后烘出来,可以把灯光关了 物体的光照还有阴影还在

Shader代码:

Shader "Custom/TestLightMapShader" {
	Properties{
		_MainTex("Main Tex",2d) = ""{}
	}
	SubShader {
		pass {
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "unitycg.cginc"
			sampler2D _MainTex;
			float4 _MainTex_ST;
			struct v2f {
				float4 pos:POSITION;
				float2 uv0:TEXCOORD0;
				float2 uv1:TEXCOORD1;
			};
			v2f vert(appdata_full v)
			{
				v2f o;
				o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv0 = TRANSFORM_TEX(v.texcoord, _MainTex);
				o.uv1 = v.texcoord1.xy*unity_LightmapST.xy + unity_LightmapST.zw;
				return o;
			}
			fixed4 frag(v2f IN) :COLOR
			{
				fixed4 col = tex2D(_MainTex,IN.uv0);
				float3 lm = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.uv1));
				col.rgb *= lm*2;
				return col;
			}
			ENDCG
		}
	}
	FallBack "Diffuse"
}

定义了一个_MainTex,这里并没有赋纹理,为了和光照贴图有区别 结构体里定义:uv0与uv1 uv1对应的是光照贴图的处理

o.uv1 = v.texcoord1.xy*unity_LightmapST.xy + unity_LightmapST.zw;

看这个公式和unitycg.cginc里的TRANSFORM_TEX的定义好像是一样的

// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)

为什么不用TRANSFORM_TEX呢 这个unity_Lightmap和unity_LightmapST是内建的直接用 但是注意,unity_Lightmap与ST之间并无下划线,这个和TRANSFORM_TEX定义的不一样,所以得这样写 这里用到了v.texcoord1,查看unitycg.cginc,发现vert的参数得用appdata_full v.texcoord对应主纹理,v.texcoord1对应的是光照贴图(就这样理解吧)

然后到frag函数中

fixed4 col = tex2D(_MainTex,IN.uv0);
float3 lm = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.uv1));
col.rgb *= lm*2;
return col;

tex2D主纹理采样 没变 之后对lightmap贴图进行采样

float3 lm = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, IN.uv1));

这个在unitycg.cginc中定义,返回值是个half3

inline half3 DecodeLightmap( fixed4 color, half4 decodeInstructions)
{
#if defined(UNITY_NO_RGBM)
    return DecodeLightmapDoubleLDR( color );
#else
    return DecodeLightmapRGBM( color, decodeInstructions );
#endif
}

再与主颜色的rgb叠加

col.rgb *= lm*2;

这里lm*2是因为太暗,所以增加亮度 当然,从图上能看出来,lightmap与实时渲染的效果是不一样的,这个就需要调整了,本文不涉及。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  jo5M4GCiOHdG   2023年11月12日   18   0   0 Unity教程Unity
5WVVrgL6K2nc