• CG之基本光照模型计算公式


    在一个基本模型里,一个物体表面的颜色是由放射(emissive)、环境反射(ambient)、漫反射(diffuse)和镜面反射(specular)等光照作用的总和。每种光照作用取决于表面材质的性质(如亮度和材质颜色)和光源的性质(如光的颜色和位置)的共同作用。

    从数学上描述基本模型的高级公式如下所示:

    surfaceColor = emissive +ambient + diffuse + specular

    一、放射项

    emissive = Ke

    其中:

    Ke代表材质的放射光颜色。

    二、环境反射项

    ambient = Ka * globalAmbient

    其中:

    Ka是材质的环境反射系数。

    globalAmbient是入射环境光的颜色。

    三、漫反射项

    diffuse = Kd * lightColor * max(dot(N, L), 0)

    其中:

    Kd是材质的漫反射颜色。

    lightColor是入射漫反射光的颜色。

    N是规范化的表面法向量。

    L是规范化的从顶点到光源的向量。

    四、镜面反射项

    specular = Ks * lightColor * facing * pow(max(dot(N, H), 0), shininess)

    其中:

    Ks 是材质的镜面反射颜色。

    lightColor是入射镜面反射光的颜色。

    N是规范化的表面法向量。

    H是规范化的,顶点到光源的向量与顶点到眼睛的向量的中间向量。

    facing是,如果dot(N,L)大于0则为1,否则为0。其中L是顶点到光源位置的向量。

    shinniess是表面光泽度。

    例如,在unity3d shaderLab,在顶点shader中计算光照的代码如下:

     1 Shader "Custom/Test"
     2 {
     3     Properties
     4     {
     5         _Ke("Ke", Color) = (1,1,1,1)
     6         _Ka("Ka", Color) = (1,1,1,1)
     7         _GlobalAmbient("Global ambient", Color) = (1,1,1,1)
     8         _Kd("Kd", Color) = (1,1,1,1)
     9         _Ks("Ks", Color) = (1,1,1,1)
    10         _Shininess("", float) = 1
    11     }
    12 
    13     SubShader
    14     {
    15         Pass
    16         {
    17             Tags
    18             {
    19                 "RenderType" = "Opaque"
    20             }
    21 
    22             CGPROGRAM
    23             #pragma vertex Vert
    24             #pragma fragment Frag
    25 
    26             #include "UnityCG.cginc"
    27             #include "Lighting.cginc"
    28 
    29             uniform float4 _Ke;
    30             uniform float4 _Ka;
    31             uniform float4 _GlobalAmbient;
    32             uniform float4 _Kd;
    33             uniform float4 _Ks;
    34             uniform float _Shininess;
    35             
    36             struct VertexInput
    37             {
    38                 float4 pos : POSITION;
    39                 float2 uv : TEXCOORD0;
    40                 float3 nor : NORMAL;
    41                 float4 col : COLOR;
    42             };
    43 
    44             struct FragmentInput
    45             {
    46                 float4 pos : SV_POSITION;
    47                 float2 uv : TEXCOORD0;
    48                 float4 col : COLOR;
    49             };
    50 
    51             FragmentInput Vert(VertexInput vi)
    52             {
    53                 FragmentInput fi;
    54                 fi.pos = mul(UNITY_MATRIX_MVP, vi.pos);
    55                 fi.uv = vi.uv;
    56 
    57                 // compute emissive
    58                 float3 emissiveC = _Ke.rgb;
    59 
    60                 // compute ambient
    61                 float3 ambientC = _Ka.rgb * _GlobalAmbient.rgb;
    62 
    63                 // compute diffuse
    64                 float3 nor = mul(vi.nor, (float3x3)_World2Object);
    65                 float3 dir2Light = normalize(WorldSpaceLightDir(vi.pos));
    66                 float nl = max(0, dot(nor, dir2Light));
    67                 float3 diffuseC = _Kd.rgb * _LightColor0.rgb * nl;
    68 
    69                 // compute specular
    70                 float3 dir2Cam = normalize(WorldSpaceViewDir(vi.pos));
    71                 float nh = max(0, dot(nor, dir2Cam + dir2Light));
    72                 float specLight = nl > 0 ? pow(nh, _Shininess) : 0;
    73                 float3 specC = _Ks * _LightColor0.rgb * specLight;
    74 
    75                 fi.col.rgb = emissiveC + ambientC + diffuseC + specC;
    76                 fi.col.a = 1;
    77 
    78                 return fi;
    79             }
    80 
    81             float4 Frag(FragmentInput fi) : Color
    82             {
    83                 return fi.col;
    84             }
    85 
    86             ENDCG
    87         }
    88     }
    89 }
    shader

    效果图如下:

     转载请注明出处: http://www.cnblogs.com/jietian331/p/5549889.html

  • 相关阅读:
    剑指offer 整数中1出现的次数(从1到n整数中1出现的次数)
    剑指offer 把数组排成最小的数
    剑指offer 丑数
    剑指offer 字符串的排列
    剑指offer 数组中出现次数超过一半的数字
    剑指offer 最小的K个数
    操作系统 页面置换算法(C++实现)
    剑指offer 二叉搜索树与双向链表
    剑指offer 复杂链表的复制
    操作系统 银行家算法(C++实现)
  • 原文地址:https://www.cnblogs.com/jietian331/p/5549889.html
Copyright © 2020-2023  润新知