Unity Shader学习记录四 光照一

文章详细介绍了光线与物体交互的两个主要过程——吸收和散射,以及这两种现象如何在标准光照模型中体现,包括高光反射和漫反射。此外,还探讨了Unity中如何实现漫反射,分别展示了逐顶点光照和逐像素光照的实现方法,并提到了环境光的设置和控制。
摘要由CSDN通过智能技术生成

一、吸收和散射

光线由光源发射出来后,就会与一些物体相交,通常相交的结果有两个:吸收和散射。

光线在物体表面经过散射后,有两种方向,一种散射到物体内部,称为折射或透射;另一种散射到外部,称为反射。对于不透明物体,折射光(非单色光)被吸收一部分,可能改变光线颜色。

为区分两种散射方向,在光照模型中使用不同部分计算它们:高光反射(specular)与漫反射(diffuse)。前者表示光线在物体表面的反射,后者表示折射、吸收、散射出物体表面的光线。

二、标准光照模型

标准光照模型的基本方法是,将进入摄像机的光线分为4个部分:

1.自发光:该部分用于描述当给定一个方向时,表面本身会像该方向发射多少辐射量。(如果没有使用全局光照,自发光的表面不会照亮周围物体,只会使本身看起来更亮)

2.高光反射:该部分用于描述光源照射到物体表面时,该表面在完全镜面反射的方向反射出多少能量。

3.漫反射:该部分用于描述当光线从光源照射到物体表面时,会向每个方向散射的能量。

4.环境光:该部分用于描述其他的间接光照。

三、光照模型的计算方式

1.逐像素光照

在片元着色器中计算,以每个像素为基础,得到它的法线(对顶点法线插值或从法线纹理中采样得到),然后进行光照模型的计算。

2.逐顶点光照

在顶点着色器中计算,在每个顶点上计算光照,然后在渲染图元内部进行线性插值,最后输出像素颜色。

四、环境光设置

Window>>Rendering>>Lighting>>Environment>>Environment Lighting>>Ambient Color内控制:
在这里插入图片描述
如图,Instensity控制光的强度,调色板控制颜色。

五、Unity中实现漫反射

1.逐顶点光照:

Shader "ShaderStudy/Chapter 6/6-4"
{
    Properties
    {
        //材质的漫反射颜色
        _Diffuse("DiffuseColor",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;
                float3 color : COLOR;
            };

            //逐顶点光照
            v2f vert(a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);

                //通过变量UNITY_LOGHTMODEL_AMBIENT获得环境光。
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

                //计算世界空间下的顶点法线方向,normalize返回单位向量,mul为矩阵相乘
                fixed3 worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));
                //计算世界空间下的光线方向
                fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
                //这里就是使用基本光照模型中漫反射部分的计算公式,dot为点乘(cross为叉乘),saturate函数将所得矢量或标量的值限定在[0,1]之间
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLight));
                //对环境光和漫反射光照部分相加,得到最终的光照结果。
                o.color = ambient + diffuse;
                return o;
            }

            fixed4 frag(v2f i) :SV_Target
            {
                return fixed4(i.color,1.0);
            }
            
            ENDCG
        }
    }
}

2.逐像素光照:

            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;
                float3 worldNormal : TEXCOORD0;
            };

            //逐顶点光照
            v2f vert(a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.worldNormal = mul(v.normal,(float3x3)unity_WorldToObject);
                return o;
            }

            fixed4 frag(v2f i) :SV_Target
            {
                fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(normalize(i.worldNormal), normalize(_WorldSpaceLightPos0.xyz)));
                return fixed4(UNITY_LIGHTMODEL_AMBIENT.xyz + diffuse, 1.0);
            }
            
            ENDCG
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值