Fresnel 프레넬
프레넬 방정식(Fresnel equation) : 네이버 블로그 (naver.com)
반사와 투과가 되는 양을 표현한 방정식
fresnel equation
Properties
{
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_FresnelColor ("Fresnel Color", Color) = (1,1,1,1)
_FresnelBias ("Fresnel Bias", Float) = 0
_FresnelScale ("Fresnel Scale", Float) = 1
_FresnelPower ("Fresnel Power", Float) = 1
}
SubShader
{
Tags
{
"Queue"="Geometry"
"IgnoreProjector"="True"
"RenderType"="Opaque"
}
Cull Back
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
struct appdata_t
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
half3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
float fresnel : TEXCOORD1;
};
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
fixed4 _FresnelColor;
fixed _FresnelBias;
fixed _FresnelScale;
fixed _FresnelPower;
v2f vert(appdata_t v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.pos);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
float3 i = normalize(ObjSpaceViewDir(v.pos));
o.fresnel = _FresnelBias + _FresnelScale * pow(1 + dot(i, v.normal), _FresnelPower);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 c = tex2D(_MainTex, i.uv) * _Color;
return lerp(c, _FresnelColor, 1 - i.fresnel);
}
ENDCG
}
}
resnel equation
// CookTorrance referenced
float fresnel_val = 0.2;
float roughness_val = .06;
float k = 0.01;
wVertex = mul(unity_WorldToObject, wVertex);
float3 viewpos = -mul(UNITY_MATRIX_MV, wVertex).xyz;
float3 col = float3(0, 0, 0);
for (int i = 0; i < 2; i++)
{
// View vector, light direction, and Normal in model-view space
float3 toLight = unity_LightPosition[i].xyz;
float3 L = normalize(toLight);
float3 V = normalize(viewpos);
float3 N = mul(UNITY_MATRIX_MV, float4(normal, 0));
N = normalize(N);
// Half vector from view to light vector
float3 H = normalize(V + L);
//Dot products
float NdotL = max(dot(N, L), 0);
float NdotV = max(dot(N, V), 0);
float NdotH = max(dot(N, H), 1.0e-7);
float VdotH = max(dot(V, H), 0);
// model the geometric attenuation of the surface
float geo_numerator = 2 * NdotH;
float geo_b = (geo_numerator * NdotV) / VdotH;
float geo_c = (geo_numerator * NdotL) / VdotH;
float geometric = 2 * NdotH / VdotH;
geometric = min(1, max(0, min(geo_b, geo_c)));
//calculate the roughness of the model
float r2 = roughness_val * roughness_val;
float NdotH2 = NdotH * NdotH;
float NdotH2_r = 1 / (NdotH2 * r2);
float roughness_exp = (NdotH2 - 1) * NdotH2_r;
float roughness = exp(roughness_exp) * NdotH2_r / (4 * NdotH2);
// Calculate the fresnel value
float fresnel = pow(1.0 - VdotH, 5.0); fresnel *= 1 - fresnel_val;
fresnel += fresnel_val;
}
댓글
댓글 쓰기