(1)眼睛,眼球,
相关介绍:
眼睛介绍
效果图:
其中用到的知识点: 视差,漫反射,环境反射
直接贴上代码:
里面有注释:
Shader "Eye"
{
Properties
{
_BaseMap ("_BaseMap", 2D) = "white" {}
_NormalMap ("_NormalMap", 2D) = "bump" {}
_Parallax("_Parallax",float) = -0.1
_DecalMap ("_DecalMap", 2D) = "white" {}
// 光滑度
_Roughness("_Roughness",range(0,1)) = 0.5
_EnvMap("_EnvMap",Cube) = "_Skybox"{}
_EnvRotate("眼球的旋转_EnvRotate",Range(0,360)) = 0
_EnvIntensity("_EnvIntensity",range(0,5)) = 1
}
SubShader
{
Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "UnityCG.cginc"
#include "AutoLight.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 texcoord0 : TEXCOORD0;
float3 normal : NORMAL;
float4 tangent : TANGENT;
// 顶点色 颜色 可以用作遮罩
float4 color : COLOR;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 posWorld : TEXCOORD1;
float3 normalDir : TEXCOORD2;
float3 tangentDir : TEXCOORD3;
float3 binormalDir : TEXCOORD4;
};
sampler2D _BaseMap,_NormalMap;
//贴花的图
sampler2D _DecalMap;
float _Roughness;
samplerCUBE _EnvMap;
float4 _EnvMap_HDR;
float _EnvIntensity;
float _EnvRotate;
float _Parallax;
//旋转
float3 RotateAround(float degree,float3 target)
{
float rad = degree * UNITY_PI / 180;
float2x2 m_rotate = float2x2(cos(rad),-sin(rad),
sin(rad),cos(rad));
float2 dir_rotate = mul(m_rotate,target.xyz);
target = float3(dir_rotate.x,target.y,dir_rotate.y);
return target;
}
/// aces 高转低
inline float3 ACESFilm(float3 x)
{
float a = 2.51f;
float b = 0.03f;
float c = 2.43f;
float d = 0.59f;
float e = 0.14f;
return saturate((x * (a * x+ b)) / (x*(c*x+d)+e));
}
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord0;
// 法线三剑客
o.normalDir = UnityObjectToWorldNormal(v.normal);
o.tangentDir = normalize(mul(unity_ObjectToWorld,float4(v.tangent.xyz,0.0))).xyz;
o.binormalDir = normalize(cross(o.normalDir,o.tangentDir) * v.tangent.w);
o.posWorld = mul(unity_ObjectToWorld,v.vertex).xyz;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//
half3 normalDir = normalize(i.normalDir);
half3 tangentDir = normalize(i.tangentDir);
half3 binormalDir = normalize(i.binormalDir);
half3 lightDir = normalize(UnityWorldSpaceLightDir(i.posWorld));
half3 viewDir = normalize(UnityWorldSpaceViewDir(i.posWorld));
// 法线贴图
float3x3 TBN = float3x3(tangentDir,binormalDir,normalDir);
float4 normal_Map = tex2D(_NormalMap,i.uv);
float3 normal_Data = UnpackNormal(normal_Map);
normalDir = normalize(mul(normal_Data,TBN));
// 视差效果 从侧面看,模拟眼球是凸出的
//float parallax_depth = 1.0 - saturate(distance(i.uv,float2(0.5,0.5)) / 0.2);
// 和上面是一样的效果,但是写法更高端一点,,用作遮罩
float parallax_depth = smoothstep(1.0,0.5,distance(i.uv,float2(0.5,0.5)) / 0.2);
float3 tanViewDir = normalize(mul(TBN,viewDir));
float2 parallax_Offset = parallax_depth * tanViewDir.xy / (tanViewDir.z + 0.42) * _Parallax;
half3 base_Color = tex2D(_BaseMap, i.uv + parallax_Offset);
half3 decal_color = tex2D(_DecalMap, i.uv).rgb;
// 眼球最外层是凸出的 ,内层是凹陷的,所以法线反向求出内陷的法线效果
normal_Data.xy = - normal_Data.xy;
float3 normalDir_Iris = normalize(mul(normal_Data,TBN));
// 漫反射
half NdotL = max(0.0,dot(normalDir_Iris,lightDir));
half half_lambert = (NdotL + 1) * 0.5;
half3 final_diffuse = pow(half_lambert * base_Color,2.2);
/// 环境反射 、 边缘光, 最外层的外层的计算 用正常的normal
float3 reflectDir = reflect(-viewDir,normalDir);
reflectDir = RotateAround(_EnvRotate,reflectDir);
float roughtness = lerp(0.0,0.95,saturate(_Roughness));
roughtness = roughtness * (1.7 - 0.7 * roughtness);
float mip_level = roughtness * 6.0;
float4 color_CubeMap = texCUBElod(_EnvMap,float4(reflectDir,mip_level));
float3 evn_Color = DecodeHDR(color_CubeMap,_EnvMap_HDR);
float3 final_evn = evn_Color * _EnvIntensity;
// 求出明度值 用明度 会让眼球的对比度更见明显
float evn_lumin = dot(final_evn,float3(0.299f,0.587f,0.114f));
final_evn = final_evn * evn_lumin;
half3 finalColor = final_diffuse +( final_diffuse * pow(final_evn,2.2) ) + decal_color;
half3 enconde_color = pow(ACESFilm(finalColor), 1 / 2.2);
return float4(enconde_color,1.0);
}
ENDCG
}
}
}