高级纹理-菲涅耳反射

菲涅耳反射

定义

当光线照射到物体表面时,一部分发生反射,一部分进入物体内部,发生折射或散射。

效果

在这里插入图片描述

思路

近似公式如下:
在这里插入图片描述

实现

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/Fresnel" {
	Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _FresnelScale("_FresnelScale", Range(0,1)) = 0.5
        _Cubemap ("CubeMap", Cube) = "_Skybox" {}
	}
	SubShader {
		Tags { "RenderType"="Opaque" "Queue"="Geometry"} //  渲染类型::不透明物体        渲染队列:不透明几何体
		
		Pass { 
			Tags { "LightMode"="ForwardBase" } //前向渲染
			CGPROGRAM
			编译PassType.ForwardBase所需的所有变体
			#pragma multi_compile_fwdbase 
			
			#pragma vertex vert
			#pragma fragment frag
			#include "Lighting.cginc"
			#include "AutoLight.cginc"
			
			fixed4 _Color;
			samplerCUBE _Cubemap; //定义立方体纹理的数据类型
			float _FresnelScale;
			
			struct a2v {
				float4 vertex : POSITION;
				float3 normal : NORMAL;
			};
			
			struct v2f {
				float4 pos : SV_POSITION;
				float3 worldPos : TEXCOORD0;
				fixed3 worldNormal : TEXCOORD1;
				fixed3 worldViewDir : TEXCOORD2;
				fixed3 worldRefl : TEXCOORD3;
				SHADOW_COORDS(4)//声明了一个名为_ShadowCoord的阴影纹理坐标变量。
			};
			
			v2f vert(a2v v) {
				v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                o.worldPos = mul( unity_ObjectToWorld, v.vertex ).xyz;
                o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);
                o.worldRefl = reflect( o.worldViewDir, o.worldNormal); 
                //refract函数计算折射的出射光线的方向,
                //第一个参数是入射方向,必须归一化
                //第二个参数是表面法线,需归一化
                //第三个参数是入射光线所在介质的折射率和折射光线所在介质的折射率的比值
                //返回的是折射光线的方向
                         
                TRANSFER_SHADOW(o);
                //SHADOW_COORDS这个宏后面的参数是指第几个通道,不要和其他的出现冲突,也就是要改变投影的颜色话必须要占用一个通道。
                //在顶点处理器里调用TRANSFER_SHADOW。
                //然后像素着色器调用UNITY_LIGHT_ATTENUATION,返回的就是这个像素是否存在阴影中。
                //此时得到的atten就是综合了衰减和阴影的结果,可以用其来作为【衰减】和【阴影】的因子与最终的光照颜色相乘。
                
                return o;
			}
			
			fixed4 frag(v2f i) : SV_Target {
				fixed3 worldNormal = normalize(i.worldNormal); 
				fixed3 worldLight = normalize( UnityWorldSpaceLightDir(i.worldPos));
				fixed3 worldViewDir = normalize(i.worldViewDir);
				
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
				
				fixed3 diffuse = _LightColor0.rgb * _Color.rgb * saturate( dot( worldNormal,worldLight ));
				
				fixed3 reflection = texCUBE( _Cubemap, i.worldRefl ).rgb ; //对立方体纹理采样(提供折射的方向),
				//使用菲尼尔公式计算如下: 
				fixed fresnel = _FresnelScale   +  (1 - _FresnelScale) * pow ( 1 - dot( worldViewDir, worldNormal ),5 );
				UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
				//根据菲尼尔值, 在漫反射与反射之间取值,  应用于物体边界处,产生更加真实的效果。
				fixed3 color = (ambient + lerp( diffuse,reflection, saturate(fresnel)) * atten); //lerp(a,b,w) 根据w返回a到b之间的插值  根据折射程度变量,返回插值。
				return fixed4(color,1.0);
			}
			
			ENDCG
		}
	}
	FallBack "Reflective/VertexLit"
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值