• Unity Shader 菲涅尔环境反射


    菲涅尔反射描述了一种光学现象,当光照到物体表面时,一部分发生反射,另一部分则进入物体内部,发生折射或散射;相比直接的反射和折射计算,菲涅尔反射更接近真实情况。

    可用下面的等式近似计算这种反射效果:

    F=F0+(1-F0)*pow((1-dot(v,n)),p);

    其中,F0为反射系数,v为视野方向,n为法线方向,p为控制指数,一般p=5。

    代码如下:

     1 Shader "MyUnlit/FresnelReflection"
     2 {
     3     Properties
     4     {
     5         _Color("Color Tint", Color) = (1,1,1,1)
     6         _ReflectColor("Reflection Color",Color) = (1,1,1,1)
     7         _FresnelScale("Fresnel Scale",range(0,1)) = 0.5
     8         _CubeMap("Reflection CubeMap",cube) = "_skybox"{}
     9     }
    10         SubShader
    11     {
    12         Tags{ "RenderType" = "Opaque" }
    13 
    14         Pass
    15     {
    16         Tags{ "lightmode" = "forwardbase" }
    17 
    18         CGPROGRAM
    19         #pragma multi_compile_fwdbase
    20         #pragma vertex vert
    21         #pragma fragment frag
    22 
    23         #include "UnityCG.cginc"
    24         #include "autolight.cginc"
    25         #include "lighting.cginc"
    26 
    27         fixed4 _Color;
    28         fixed4 _ReflectColor;
    29         fixed _FresnelScale;
    30         samplerCUBE _CubeMap;
    31 
    32     struct appdata
    33     {
    34         float4 vertex : POSITION;
    35         float3 normal:NORMAL;
    36     };
    37 
    38     struct v2f
    39     {
    40         float3 worldPos : TEXCOORD0;
    41         float4 pos : SV_POSITION;
    42         float3 worldNormal:TEXCOORD1;
    43         float3 worldViewDir:TEXCOORD2;
    44         float3 worldRef:TEXCOORD3;
    45         SHADOW_COORDS(4)
    46     };
    47 
    48     v2f vert(appdata v)
    49     {
    50         v2f o;
    51         o.pos = UnityObjectToClipPos(v.vertex);
    52         o.worldNormal = UnityObjectToWorldNormal(v.normal);
    53         o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    54         o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);
    55         o.worldRef = reflect(-o.worldViewDir, o.worldNormal);
    56 
    57         TRANSFER_SHADOW(o);
    58         return o;
    59     }
    60 
    61     fixed4 frag(v2f i) : SV_Target
    62     {
    63         fixed3 worldNormal = normalize(i.worldNormal);
    64         fixed3 worldViewDir = normalize(i.worldViewDir);
    65         fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
    66 
    67         fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
    68         fixed3 col = texCUBE(_CubeMap, i.worldRef).rgb;
    69         fixed3 reflection = col * _ReflectColor.rgb;
    70 
    71         fixed3 diffuse = _LightColor0.rgb*_Color.rgb*saturate(dot(worldNormal, worldLightDir));
    72         fixed fresnel = _FresnelScale + (1 - _FresnelScale)*pow(1 - dot(worldViewDir, worldNormal), 5);
    73 
    74         UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
    75         fixed3 color = ambient + lerp(diffuse, reflection, saturate(fresnel))*atten;
    76         return fixed4(color,1.0);
    77     }
    78         ENDCG
    79     }
    80     }
    81         fallback "Reflective/VertexLit"
    82 }
  • 相关阅读:
    缓存
    判断空对象的方法
    Vue响应式系统如何操作运用?本文详解
    2020最新中级web前端面试题库(含详细答案,15k级别)你会几道呢?
    如何用JavaScriptJ封装拖动验证滑块?本文教你
    Nodejs中ES Modules如何操作运用?本文详解
    Vue学习总结之Vue的生命周期是怎么运用操作的?本文详解
    Vue项目如何部署?实战教你
    canvas绘制简单的霓虹灯效果
    canvas绘制五角星详细过程
  • 原文地址:https://www.cnblogs.com/koshio0219/p/11104808.html
Copyright © 2020-2023  润新知