游戏开发中建议使用半兰伯特光照

游戏开发中建议使用半兰伯特光照模型

在基本光照模型中求出漫反射部分的计算公式:
在这里插入图片描述
漫反射 = 入射光线的颜色和强度(c light) * 材质漫反射系数 (m diffuse)* 表面法线(n) * 其光源防线 (I)
在shader中为了不让 n和i的点乘结果为负数,即使用了saturate函数让值截取在[0,1]区间之内

首先 ,使用逐顶点渲染的方式渲染模型光照:

顶点着色器渲染流程如下:

            v2f vert (a2v v)
            {
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				fixed3 amlibent = UNITY_LIGHTMODEL_AMBIENT.xyz;
				
				fixed3 worldNormal = normalize(mul(v.normal , (float3x3)unity_WorldToObject));
				fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
				fixed3 diffuse =  _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal , worldLight));

				o.color = amlibent + diffuse;

				return o;
            }

将模型局部坐标转换为裁剪坐标是顶点着色器最要基本的功能,在早期版本使用mul(UNITY_MATRIX_MVP , v.vertex); 的方式,现在后期版本使用unity内部的方法UnityObjectToClipPos(v.vertex)来实现即可。

效果如下图:
在这里插入图片描述
可见背光面和迎接光面的过度明显有点粗糙

下面使用逐片元漫反射实现:

            v2f vert (a2v v)
            {
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.worldNormal = normalize(mul(v.normal , (float3x3)unity_WorldToObject));
				return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
				fixed3 worldNormal = i.worldNormal;
				fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);

				fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal , worldLight));
				fixed3 color = ambient + diffuse;
                return fixed4(color,1.0);
            }

顶点着色器这里只要获得裁剪空间,和法线的世界空间。这里使用变换矩阵的逆矩阵 unity_WorldToObject实现
在片元着色器中同样实现功能即可
_

效果如下图:
在这里插入图片描述
过度比顶点渲染的效果丝滑更多

再来对比背光面的效果,如下图:
在这里插入图片描述
左边是逐片元 右边是逐顶点

可见两个模型效果都是背光面死黑的效果。在半条命的游戏开发公司优化了兰伯特光照模型,即在此基础上做了简单的修改,称半兰伯特光照模型
公式如下:
在这里插入图片描述
这里没用用max的操作来防止n和i的点乘为负数,而是使用α 来做为缩放量 、β做为偏移量,一般情况下α和β都为0.5,此技术仅仅为视觉加强技术,没有任何物理依据
实现如下:

            fixed4 frag (v2f i) : SV_Target
            {
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
				fixed3 worldNormal = i.worldNormal;
				fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
				fixed3 halfLambert = dot(worldNormal,worldLight) * 0.5 + 0.5;

				fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * halfLambert;
				fixed3 color = ambient + diffuse;
                return fixed4(color,1.0);
            }
在逐片元漫反射基础上做了半兰伯特光照模型算式计算结果

效果如下图:
在这里插入图片描述

在这里插入图片描述

效果显著

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值