美文网首页
光照模型

光照模型

作者: somnusand | 来源:发表于2021-12-30 18:06 被阅读0次
漫反射模型
  • Lambert光照模型 : 漫反射=光照颜色 * max(0,cos(光照方向•模型法线方向))

diffuse=LightColor * max(L·N,0)

  • Half Lambert光照模型 -- 漫反射=光照颜色 x dot(光照方向•模型法线方向)*0.5+0.5

diffuse = LightColor * (L·N*0.5+0.5)

  • Oren-Nayar模型
    学习中...
高光模型
  • blinn光照模型 -- 光源颜色*pow(max(0,dot(反射光方向•视野方向)),gloss)

R=reflect(-L,N)
gloss = LightColor*[max(0,normalized(R·V))]^n

  • Blinn-Phone光照模型 -- 光源颜色*pow(max(0,cos(法线方向•x)),gloss) x=光线方向和视野方向的平分线

half=(L+V)/2
gloss = LightColor * [max(0,N·half)]^n

(L是从交点到光源的向量,N是交点的法线,V是观察的方向向量, R是L在交点上的反射向量)(译者注:上式中最后的n为n次幂,n是幂指数,可调节)

最终颜色:color = diffuse * DiffuseColor + gloss * GlossColor + ambient

UnityShader 代码示例
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'

Shader "Som/learn/diffuse"
{
    Properties
    {
        [Header(Diffuse)]
        _Diffuse("Color",Color) = (1,1,1,1)
        [Enum(DiffuseMode)]//自定义Enum
        _DiffuseMode("DiffuseMode", Int) = 0

        [Space(10)][Header(Gloss)]
        _GlossColor("Gloss Color",Color) = (1,1,1,1)
        [Enum(GlossMode)]
        _GlossMode("GlossMode", Int) = 0
        _Gloss("Gloss",Range(8,200)) = 10

    }


    SubShader
    {
        Pass
        {   
            Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
    
            CGPROGRAM
    #include "Lighting.cginc"
    #pragma vertex vert  //声明顶点函数
    #pragma fragment frag //声明片元函数
    
            int _DiffuseMode;
            int _GlossMode;
    
            fixed4 _Diffuse;
            fixed4 _GlossColor;
            half _Gloss;
    
            struct a2v
            {
                float4 vertex:POSITION;
                float3 normal:NORMAL;
            };
    
            struct v2f
            {
                float4 position:SV_POSITION;
                float3 color:COLOR0;
            };
    
            //_LightColor0:取得第一个直射光的颜色,_WorldSpaceLightPos0取得第一个直射光的位置,_WorldSpaceCameraPos相机位置
            v2f vert(a2v v)
            {
                 v2f f;
                 f.position = UnityObjectToClipPos(v.vertex);
                 //--Diffuse
                 fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;//unity内置函数,获取环境光颜色
                 //fixed3 normalDir = normalize(mul(v.normal, (float3x3)unity_WorldToObject));//old模型空间的法线转化为世界空间
                 fixed3 normalDir = normalize(UnityObjectToWorldNormal(v.normal));//模型空间的法线转化为世界空间
                 //fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
                 fixed3 lightDir = normalize(WorldSpaceLightDir(v.vertex));// 模型空间中的顶点坐标 == 》世界空间中从这个点到光源的方向
                 fixed3 diffuse;
                 if (_DiffuseMode == 0)
                 {
                     //兰伯特光照模型 -- 漫反射=光照颜色*max(0,cos(光照方向•模型法线方向))
                     diffuse = _LightColor0.rgb * max(0, dot(normalDir, lightDir));
                 }
                 else
                 {
                     //半兰伯特光照模型 -- 漫反射=光照颜色*cos(光照方向•模型法线方向)*0.5+0.5
                     diffuse = _LightColor0.rgb * (dot(normalDir, lightDir) * 0.5 + 0.5);
                 }
                 //--Gloss
                 //fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(v.vertex, (float3x3)unity_WorldToObject).xyz);//视野方向
                 fixed3 viewDir = normalize(WorldSpaceViewDir(v.vertex)); //模型空间的顶点坐标 == 》世界空间从这个点到摄像机的观察方向;
                 fixed3 gloss;
                 switch (_GlossMode)
                 {
                    case 0: //blinn光照模型 --  光源颜色*pow(max(0,dot(反射光方向•视野方向)),gloss)
                        fixed3 reflectDir = normalize(reflect(-lightDir, normalDir));//反射光方向
                        gloss = _LightColor0.rgb * _GlossColor * pow(max(dot(reflectDir, viewDir), 0), _Gloss);
                        break;
                    case 1: //blinn-Phong光照模型  -- 光源颜色*pow(max(0,cos(法线方向•x)),gloss) x=光线方向和视野方向的平分线
                        fixed3 halfDir = normalize(lightDir + viewDir);//光照方向和视野方向的平分线
                        gloss = _LightColor0.rgb * _GlossColor * pow(max(dot(normalDir, halfDir), 0), _Gloss);
                        break;
                 }
                 f.color = diffuse * _Diffuse + gloss;
                 return f;
             }
    
             fixed4 frag(v2f f) : SV_TARGET
             {
                 return fixed4(f.color,1);
             }
            ENDCG
        }
    }
}

相关文章

网友评论

      本文标题:光照模型

      本文链接:https://www.haomeiwen.com/subject/gpaiqrtx.html