700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 反射 折射 菲涅尔反射总结

反射 折射 菲涅尔反射总结

时间:2020-01-06 22:03:21

相关推荐

反射 折射 菲涅尔反射总结

立方体纹理(Cubemap)最常见的是用于天空盒子以及环境映射,通常被用作具有反射,折射属性物体的反射源。Lighting-Environment中添加对应的材质。

材质对应贴图的类型要选择Cube。

反射

反射原理:根据视线方向和法线方向计算出反射方向,再把反射方向作为采样的方向,在Cubemap上采样。

反射Shader

Shader "MyCustom/Reflect"{Properties{_CubeMap ("CubeMap", Cube) = "" {}}SubShader{Tags {"RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{//位置用float4表示,它表示是齐次坐标,比如我们这样表示一个float4(x,y,z,w),当w = 1的时候它表示点(x,y,z),//当w= 0的时候它表示一个向量(x,y,z)。区别就在这里,当W为1时表示点,当W为0时表示向量。float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{//世界空间中的法线float3 worldNormal : TEXCOORD0;//世界空间中的位置float3 worldPos : TEXCOORD1;float4 vertex : SV_POSITION;};samplerCUBE _CubeMap;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.worldNormal = normalize(mul((float3x3)unity_ObjectToWorld, v.normal));o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;return o;}fixed4 frag (v2f i) : SV_Target{//视线方向,世界空间中摄像机的位置 - 世界空间中每个点的位置float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos);//注意视线方向取反float3 worldReflect = reflect(-viewDir, i.worldNormal);fixed4 col = texCUBE(_CubeMap, worldReflect);return col;}ENDCG}}}

折射

斯涅尔定律:当光从介质1沿着和表面法线夹角为θ1的方向斜射入介质2时,我们可以使用如下公式计算折射光线与法线的夹角θ2:η1sinθ1 = η2sinθ2其中,η1和η2分别是两个介质的折射率。

折射原理:利用斯涅尔定律计算出折射方向,再把折射方向作为采样的方向,在Cubemap上采样。

折射Shader

Shader "MyCustom/Refract"{Properties{_CubeMap ("CubeMap", Cube) = "" {}//该属性是两种介质折射率的比值,例如如果光是从空气射到玻璃表面,//那么这个参数应该是空气的折射率和玻璃的折射率之间的比值,即1/1.5。_RefractRatio("Refract Ratio", Range(0.1, 1)) = 0.5}SubShader{Tags {"RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{//世界空间中的法线float3 worldNormal : TEXCOORD0;//世界空间中的位置float3 worldPos : TEXCOORD1;float4 vertex : SV_POSITION;};samplerCUBE _CubeMap;float _RefractRatio;//顶点着色器和反射一样v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.worldNormal = normalize(mul((float3x3)unity_ObjectToWorld, v.normal));o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;return o;}fixed4 frag (v2f i) : SV_Target{//视线方向,世界空间中摄像机的位置 - 世界空间中每个点的位置float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos);//折射方向float3 worldRefract = refract(-viewDir, i.worldNormal, _RefractRatio);fixed4 col = texCUBE(_CubeMap, worldRefract);return col;}ENDCG}}}

菲涅耳反射

菲涅尔反射:当光线照射到物体表面上时,一部分发生反射,一部分进入物体内部,发生折射或散射。被反射的光和入射光之间存在一定的比率关系,这个比率关系可以通过菲涅耳等式进行计算。

视线越垂直于表面,反射越弱,折射越强,视线越平行于表面,反射越强。比如站在湖边,近处视线与湖面接近垂直,反射弱,能看到水面下的东西,远处视线与湖面趋于平行,只能看到水面反射的东西,看不到水下的东西。

菲涅尔等式是非常复杂的,实际渲染中会用近似公式来模拟。常用的两个近似公式:

Schlick 菲涅耳近似等式

其中F0是一个反射系数,用于控制菲涅尔反射的强度,v 是视角方向, n 是表面法线

Empricial 菲涅耳近似等式

其中,bias, scale 和 power 是控制项

Shader "MyCustom/FresnelReflection"{Properties{_CubeMap ("CubeMap", Cube) = "" {}//该属性是两种介质折射率的比值,例如如果光是从空气射到玻璃表面,//那么这个参数应该是空气的折射率和玻璃的折射率之间的比值,即1/1.5。_RefractRatio("Refract Ratio", Range(0.1, 1)) = 0.5//反射系数,用于控制菲涅尔反射的强度_FresnelRatio("Fresnel Ratio", Float) = 0.5}SubShader{Tags {"RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{//世界空间中的法线float3 worldNormal : TEXCOORD0;//世界空间中的位置float3 worldPos : TEXCOORD1;float4 vertex : SV_POSITION;};samplerCUBE _CubeMap;float _RefractRatio;float _FresnelRatio;//顶点着色器和反射一样v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.worldNormal = normalize(mul((float3x3)unity_ObjectToWorld, v.normal));o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;return o;}fixed4 frag (v2f i) : SV_Target{//视线方向,世界空间中摄像机的位置 - 世界空间中每个点的位置float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos);//反射方向float3 worldReflect = reflect(-viewDir, i.worldNormal);float4 reflectCol = texCUBE(_CubeMap, worldReflect);//折射方向float3 worldRefract = refract(-viewDir, i.worldNormal, _RefractRatio);float4 refractCol = texCUBE(_CubeMap, worldRefract);//菲涅尔公式float fresnel = _FresnelRatio + (1 - _FresnelRatio) * pow(1 - dot(viewDir, i.worldNormal), 5);fixed4 col = fresnel * reflectCol + (1 - fresnel) * refractCol;return col;}ENDCG}}}

效果对比

参考《Unity Shader入门精要》

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。