zoukankan      html  css  js  c++  java
  • CG之菲涅尔效果简单实现

      菲涅尔效果,指当光到达两种材质的接触面时,一些光在接触面的表面被反射出去,而另一部分光将发生折射穿过接触面。

      现在要用shader来实现这种效果,如果要精确地描述这种底层的物理,其计算公式是非常复杂的,性能消耗也比较大。我们的目的是使创建的图像看上去真实,因此我们不使用菲涅尔公式本身,而是使用以下经验公式,它能够用非常少的计算获得很好的效果。

    reflectionCoefficient = max(0, min(1, bias + scale * pow(1 + dot(I,N), power)))

    finalColor = reflectionCoefficient * reflectedColor + (1 - reflectionCoefficient ) * refractedColor

     

    在unity3d中的渲染效果如下:

    shader如下:

     1 Shader "Custom/Test"
     2 {
     3     Properties
     4     {
     5         _Cube("Cube", Cube) = "white" {}
     6         _EtaRatio("Eta ratio", float) = 0.8
     7         _FresnelPower("Fresnel power", float) = 2
     8         _FresnelScale("Fresnel scale", float) = 1
     9         _FresnelBias("Fresnel bias", float) = 0
    10     }
    11 
    12     SubShader
    13     {
    14         Tags
    15         {
    16             "RenderType" = "Opaque"
    17         }
    18 
    19         Pass
    20         {
    21             CGPROGRAM
    22             #pragma vertex Vert
    23             #pragma fragment Frag
    24 
    25             #include "UnityCG.cginc"
    26 
    27             uniform samplerCUBE _Cube;
    28             uniform float _EtaRatio;
    29             uniform float _FresnelPower;
    30             uniform float _FresnelScale;
    31             uniform float _FresnelBias;
    32 
    33             struct AppData
    34             {
    35                 float4 pos : POSITION;
    36                 float3 nor : NORMAL;
    37             };
    38 
    39             struct V2F
    40             {
    41                 float4 pos : SV_POSITION;
    42                 float reflectionFactor : Color;
    43                 float3 r : TEXCOORD0;
    44                 float3 t : TEXCOORD1;
    45             };
    46 
    47             V2F Vert(AppData vi)
    48             {
    49                 V2F fi;
    50                 fi.pos = mul(UNITY_MATRIX_MVP, vi.pos);
    51 
    52                 float3 n = normalize(mul(vi.nor, (float3x3)_World2Object));
    53                 float3 viewDir = WorldSpaceViewDir(vi.pos);
    54                 float3 i = normalize(-viewDir);
    55 
    56                 fi.r = reflect(i, n);                                                                        // 反射向量
    57                 fi.t = refract(i, n, _EtaRatio);                                                            // 折射向量
    58                 fi.reflectionFactor = _FresnelBias + _FresnelScale * pow(1 + dot(i, n), _FresnelPower);        // 反射颜色所占比例
    59 
    60                 return fi;
    61             }
    62 
    63             float4 Frag(V2F fi) : Color
    64             {
    65                 float4 reflectC = texCUBE(_Cube, fi.r);
    66                 float4 refractC = texCUBE(_Cube, fi.t);
    67                 return lerp(refractC, reflectC, fi.reflectionFactor);
    68             }
    69 
    70             ENDCG
    71         }
    72     }
    73 }
    shader

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

  • 相关阅读:
    shell的一本书
    linux设置网络三种方法
    BIOS讲解
    对于ssh和hadoop联系讲解和ssh的基本内容
    Httphandler
    ASP.NET配置文件
    Httpmoudle
    ASP.NET页面生命周期
    ASP.NET页面跳转方法的集合
    OutputCache的使用
  • 原文地址:https://www.cnblogs.com/jietian331/p/5564901.html
Copyright © 2011-2022 走看看