Unity Shader学习-漫反射

Unity Shader学习-漫反射

光照部分漫反射计算

计算公式为:

漫反射光照 = 光源的色彩和强度 * 自发光的强度和颜色 * (世界坐标下的法线 · 世界坐标下的光照方向)

光照计算需要在同一个坐标空间下进行计算,在这里使用世界坐标来进行计算。

得到光源的强度和颜色:

需要引用UnityShader自带库 “Lighting.cginc”,通过使用自带属性 _LightColor0 可以得到场景中光源的rgb值。

自发光的强度和颜色:

自己在Properties中定义的属性

Properties{
	_Diffuse("Diffuse",Color) = (1,1,1,1)
}
世界坐标下的法线坐标:

在顶点着色器中通过方法转换到世界坐标下,然后传递给片元着色器进行计算。

v2f vert(a2v v){
	v2f o;
	o.worldNormal = UnityObjectToWorldNormal(v.normal);
	return o;
}
世界坐标下光源的光照方向

通过内置方法 UnityWorldSpaceLightDir得到。

fixed3 worldLightdir = UntyWorldSpaceLightDir(i.worldPos);

计算

标准光照模型
//saturete函数的作用是将参数的值截取到(0,1)的范围内,计算为负则将结果变为0
//saturate(x) 	如果 x 小于 0,返回 0;如果 x 大于 1,返回1;否则,返回 x
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightdir));
半兰伯特光照模型

标准光照模型在背光区域显示会有一定的缺陷,一般用半兰伯特进行改善。

//不使用saturate来防止结果为负,而是通过*0.5+0.5 将值限制在(0,1)的范围内,使光照更加自然,不同的点积结果会有不同的值而不是在计算结果为负的时候强制变为0
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * ((dot(worldNormal,worldLightDir)) * 0.5f + 0.5f);

完整代码

Shader "Custom/MyShaderHalfLight"
{
    Properties
    {
        _Diffuse("Diffuse",Color) = (1,1,1,1)
    }
    SubShader
    {
        Pass{
            Tags{"LightMode"="ForwardBase"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "Lighting.cginc"

            fixed4 _Diffuse;
            
            struct a2v{
                float4 vertex :POSITION;
                float3 normal : NORMAL;
            };
            struct v2f{
                float4 pos : SV_POSITION;
                fixed3 worldNormal : TEXCOORD0;
            }; 
            //自然光的强度颜色 * 自发光的颜色强度 * dot(法线 ,光照的方向)
            v2f vert(a2v v):POSITION{
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                //光照的计算需要在一个空间下来进行计算 所以需要将获取到的法线和光照方向的坐标转换到世界坐标下来进行计算
                //将法线从模型坐标转换为世界坐标并传递给片元着色器
                o.worldNormal = normalize(UnityObjectToWorldNormal(v.normal));
                return o;
            }
            fixed4 frag(v2f i) : SV_Target{
            	//获取环境光的属性并标准化
                fixed3 ambient =normalize(UNITY_LIGHTMODEL_AMBIENT.xyz);
                //标准化世界坐标下的法线
                fixed3 worldNormal = normalize(i.worldNormal);
                //标准化世界坐标下光源的光照方向
                fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
                //_LightColor0.rgb 必须引用"Lighting.cginc"才可以进行使用
                //使用unity shader 中自带的属性_LightColor0可以得到场景中光源的强度和颜色
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * ((dot(worldNormal,worldLightDir)) * 0.5f + 0.5f);
                //将环境光和漫反射计算的光照相加得到最终的颜色
                fixed3 color = ambient + diffuse;

                return fixed4(color,1.0);
            }
            ENDCG
            }
    }
    FallBack "Diffuse"
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值