zoukankan      html  css  js  c++  java
  • 基础光照模型、着色及效果(二)

    参考源Illumination Models and Shaing翻译声明仅供学习交流https://www.cnblogs.com/baolong-chen/category/1559372.html

    为了尽可能得到真实感图像画面,必须要模拟物体表面在多种光照条件影响下的图像呈现

    一、Lighting Model Method


    Lighting Model params

    light source参数

    • 位置-Position
    • 光谱光波-Electromagnetic Spectrum
    • 光源形状-Shape

    object sucface参数

    • 位置-Position
    • 反射率属性-Reflectance properties
    • 邻近面-Position of nearby surcface

    camera(eye)参数

    • 镜头位置-Position Sensor
    • spectrum sensitivities


    Ambient Illumination-环境光

    假定场景没有方向光只有环境光,且环境光入射到每个物体表面的量和方向是恒定的,这个理想的光照模型在现实世界基本不存在的。

    公式:Iamb = Ka·Ia

    Ia: 环境光强度,

    Ka∈[0,1]: 物体表面反射率

    最后把IRamb,IGamb,IBamb传递给模型顶点或像素颜色RGB

    Unity中环境光宏定义:#define UNITY_LIGHTMODEL_AMBIENT (glstate_lightmodel_ambient * 2)

     

    Diffuse Reflection-漫反射

    image图1

    漫反射公式:Idiff = Kd·Ip·Cos(θ) = Kd·Ip·(N·L)

    Lambert余弦定律:反射强度与表面的平滑度相关,与入射角度Sin(α)成反比或者Cos(θ)成正比

    Ip:光源强度,也可作为衰减光源fatt(r)Ip---光照颜色

    Kd∈[0,1]:物体表面反射率

    N:平面法线, (使用前要归一化运算)

    L:光源方向,(使用前要归一化运算)

    漫反射和环境光合并公式:I = Idiff + Iamb = Kd·Ip·(N·L) + Ka·Ia

    最后把IR IG IB 传递给模型顶点或像素颜色RGB即可

    //漫反射和环境光合并
    //可以转换到模型空间、切线空间、世界空间
    v2f vert(a2v a) {
        v2f v;
        v.pos = UnityObjectToClipPos(a.vertex);
        //模型空间
        /*fixed3 mn = normalize(a.normal);            
        fixed3 lightdir = normalize(ObjSpaceLightDir(a.vertex));
        fixed3 val =  max(0, dot(mn, lightdir));
        fixed3 diff = _Smoothness * _LightColor0.rgb * val * _Diffuse.rgb;
        v.color = UNITY_LIGHTMODEL_AMBIENT.xyz + diff;*/
        //世界空间---由于世界空间有许多信息例如环境映射、光照、视角,一般推荐转换到世界空间
        fixed3 wm = normalize(mul(a.normal, (float3x3)unity_WorldToObject));
        fixed3 lightdir = normalize(_WorldSpaceLightPos0.xyz);
        fixed3 val = max(0, dot(wm, lightdir));
        fixed3 diff = _Smoothness * _LightColor0.rgb * val * _Diffuse.rgb;
        v.color = UNITY_LIGHTMODEL_AMBIENT.xyz + diff;
        return v;
    }

     

    Specular Reflection-高光反射

    镜面(高光)反射,模拟陶瓷、金属等光滑表面材质,反射角影响反射强度。

    image图2

    image图3

    公式(Phong Model):Ispec = Ks·Ip·cosn(Φ) = Ks·Ip·(R·V)n

    Ks:物体表面高光反射率

    Ip:光源强度---光照颜色

    L:光源方向

    N:平面法线

    R:反射方向

    V:视线方向

    n:高光反射系数,决定着与理想高光反射模型的偏差

    R推导过程

    image图4

    R推导过程:理想的反射模型是等腰三角形(见图2)。L入射起点,R反射终点。

    矢量R = OR = LR–LO = 2LP-LO = 2(LO+OP)-LO = LO+2OP

    LO已知,那么求得LO在法向量上的投影OP即可,

    取得N的单位向量n:n=OP/|OP|=N/|N|

    取得三角函数值: image

    结合点积函数与三角函数可得image

    R = 2·dot(n, L)·n – L == reflect(-L,n)

    v2f vert(a2v a) {
        v2f v;
        v.position = UnityObjectToClipPos(a.vertex);
        fixed3 world_pos        = mul(a.vertex, unity_WorldToObject);
        fixed3 world_n          = normalize(mul(a.normal, (float3x3)unity_WorldToObject));
        fixed3 world_light_dir  = normalize(UnityWorldSpaceLightDir(world_pos));//顶点指向光源
        fixed3 world_view_dir   = normalize(_WorldSpaceCameraPos.xyz - world_pos);//顶点指向摄像机
        //reflect函数参数需要从入射光到顶点方向
        fixed3 world_ref_dir  = normalize(2 * dot(world_n,world_light_dir)*world_n - world_light_dir);//reflect(-world_light_dir,world_n);
        fixed3 spec_color   = _Ks * _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(world_ref_dir, world_view_dir)), _N);
        fixed3 diff_color   = _Kd * _LightColor0.rgb * saturate(dot(world_n, world_light_dir));
        fixed3 ambient      = UNITY_LIGHTMODEL_AMBIENT.xyz;
        fixed3 color        = ambient + diff_color + spec_color;
        v.color = color;
        return v;
     }



    组合环境光、漫反射、高光

    公式:I = Iamb + Idiff + Ispec = Ka·Ia + Ip (Kd· N ⋅ L + Ks (R⋅V)n)

    v2f vert(a2v a) {
        /*同上...*/
        fixed3 diff_color  = _Kd * _LightColor0.rgb * saturate(dot(world_n, world_light_dir));
        fixed3 ambient     = UNITY_LIGHTMODEL_AMBIENT.xyz;
        fixed3 color       = ambient + diff_color + spec_color;
    
        v.color = color;
         return v;
    }

    翻译声明仅供学习交流https://www.cnblogs.com/baolong-chen/category/1559372.html

    二、Polygon Rendering Methods


    Flat Shading-略

    UnityStore有一款插件:Poly World

    Gouraud Shading

    • 获取每个多边形的顶点法线
    • 带入光照模型计算每个顶点的光照强度
    • 在曲面多边形线性插值顶点强度

    根据上述三点,基本确定是在顶点着色内进行着色运算

    高洛德着色中,公共顶点法线(红点法线)来源于所有共点面法线的平均值,如下图。主要目的是对三个顶点组成的三角面内部进行着色,而其他三角面没有被照射到,就不会有光照效果。

    image图5

    实现代码,参考上面的vert(a2f a)函数即可

    Phong Shading

    • 获取每个多边形法线
    • 在曲面多边形线性插值顶点法线
    • 带入光照模型计算每个片元内像素点的光照强度

    上述三点,前面两点在顶点着色器计算,最后一步的着色计算在片元着色器

    v2f vert(a2v a) {
        v2f v;
        v.position          = UnityObjectToClipPos(a.vertex);
        v.world_normal      = UnityObjectToWorldNormal(a.normal);
        v.world_position    = mul(UNITY_MATRIX_M, a.vertex);
        v.world_light_dir   = UnityWorldSpaceLightDir(v.world_position);//顶点指向光源
        v.world_view_dir    = UnityWorldSpaceViewDir(v.world_position);//顶点指向摄像机
        return v;
    }
        fixed4 frag(v2f v) : SV_Target{
        fixed3 world_pos    = normalize(v.world_position);
        fixed3 world_n      = normalize(v.world_normal);
        fixed3 world_light_dir   = normalize(v.world_light_dir);
        fixed3 world_view_dir    = normalize(v.world_view_dir); 
        fixed3 world_ref_dir = normalize(2 * dot(world_n, world_light_dir) * world_n - world_light_dir);
        fixed3 spec_color = _Ks * _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(world_ref_dir, world_view_dir)), _N);
        fixed3 diff_color = _Kd * _LightColor0.rgb * saturate(dot(world_n, world_light_dir));
        fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
        fixed3 color   = ambient + diff_color + spec_color;
        return fixed4(color, 1.0f);
    }

    最后效果图:高洛德着色与冯着色效果如下图:

    image图6

  • 相关阅读:
    linux 短信收发
    sama5d3 环境检测 adc测试
    【Codeforces 723C】Polycarp at the Radio 贪心
    【Codeforces 723B】Text Document Analysis 模拟
    【USACO 2.2】Preface Numbering (找规律)
    【Codeforces 722C】Destroying Array (数据结构、set)
    【USACO 2.1】Hamming Codes
    【USACO 2.1】Healthy Holsteins
    【USACO 2.1】Sorting A Three-Valued Sequence
    【USACO 2.1】Ordered Fractions
  • 原文地址:https://www.cnblogs.com/baolong-chen/p/11669311.html
Copyright © 2011-2022 走看看