shader入门14 统一管理光照衰减与阴影

通过前两篇的学习,我们知道如何计算光照衰减与阴影.
我们知道每一次pass都是一次完整的渲染,unity为我们提供了一次pass同时计算光照衰减+光照的宏
同时atten与shadow也合并为atten. (高光反射+漫反射)* 阴影系数 *光照衰减系数
代码与阴影接收计算相似,最大的区别在于阴影计算的部分

fixed shadow = SHADOW_ATTENUATION(f);

替换为

UNITY_LIGHT_ATTENUATION(atten,f,f.worldPos);

UNITY_LIGHT_ATTENUATION宏被定义在AutoLight.cginc中,参数atten会在宏中定义,参数f为v2f类型的结构体,参数f.worldPos是世界坐标系位置

代码

Shader "Unity/Custom/NewSurfaceShader" {
	Properties{
		_Diffuse("Diffuse", Color) = (1, 1, 1, 1)//漫反射颜色
		_Specular("Specular", Color) = (1, 1, 1, 1)//高光反射颜色
		_Gloss("Gloss", Range(8.0, 256)) = 20//光泽度
	}
	SubShader{
		Pass{
			Tags{ "LightMode" = "ForwardBase" }
			CGPROGRAM
			#pragma multi_compile_fwdbase//在forwardBase中获取正确的光照变量
			#pragma vertex vert//声明顶点处理方法
			#pragma fragment frag//声明片段处理方法
			#include "Lighting.cginc"//调用光照函数库
			#include "AutoLight.cginc"//阴影投射相关的宏在这个库中
			fixed4 _Diffuse;
			fixed4 _Specular;
			float _Gloss;
			struct a2v {
				float4 vertex : POSITION;//顶点的模型空间位置 在阴影接收的宏中规定了vertex这个字段 名称不可以改
				float3 normal : NORMAL;//模型空间法线
			};
			struct v2f {
				float4 pos : SV_POSITION;//输出给剪裁空间的顶点坐标 在阴影接收的宏中规定了pos这个字段 名称不可以改
				float3 worldNormal : TEXCOORD0;//世界坐标系法线
				float3 worldPos : TEXCOORD1;//世界坐标系坐标
				SHADOW_COORDS(2)//声明一个坐标用于阴影纹理采样 2为下一个可用的寄存器索引值 也就是TEXCOORD2
			};
			v2f vert(a2v v) {
				v2f f;
				f.pos = UnityObjectToClipPos(v.vertex);//模型空间到剪裁空间转换
				f.worldNormal = UnityObjectToWorldNormal(v.normal);//模型空间到世界坐标系法线
				f.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;//模型空间到世界坐标系位置
				TRANSFER_SHADOW(f);//计算阴影纹理坐标
				return f;
			}
			fixed4 frag(v2f f) : SV_Target{
				fixed3 worldNormal = normalize(f.worldNormal);//单位化
				fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);//获取光照方向 并单位化
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;//环境光颜色
				fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(worldNormal, worldLightDir));//漫反射颜色
				fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - f.worldPos.xyz);//朝向相机的方向
				fixed3 halfDir = normalize(worldLightDir + viewDir);//h方向 用于计算高光反射补偿度
				fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);//高光反射
				UNITY_LIGHT_ATTENUATION(atten,f,f.worldPos);//光照衰减 * 阴影  atten在宏里定义了
				return fixed4(ambient + (diffuse + specular) * atten, 1.0);
			}
			ENDCG
		}
	}
	FallBack "Diffuse"
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值