Home>

Mainly through reflection and refraction to achieve a transparent effect,Use Fresnel to alias.

Shader part:

shader "unlit/crystal"
{
 properties
 {
 _cube ("skybox", cube)="" {}
 //refraction angle
 _etaratio ("etaratio", range (0, 1))=0
 //Fresnel coefficient
 _fresnelbias ("fresnelbias", float)=0.5
 _fresnelscale ("fresnelscale", float)=0.5
 _fresnelpower ("fresnelpower", float)=0.5
 }
 subshader
 {
 tags {"rendertype"="opaque"}
 lod 100
 pass
 {
  cgprogram
  #pragma vertex vert
  #pragma fragment frag
  #include "unitycg.cginc"
  struct appdata
  {
  float4 vertex:position;
  float3 normal:normal;
  };
  struct v2f
  {
  float3 normaldir:texcoord0;
  float4 vertex:sv_position;
  float3 viewdir:texcoord1;
  };
  samplercube _cube;
  float _etaratio;
  float _fresnelbias;
  float _fresnelscale;
  float _fresnelpower;
  //Calculate the line of sight reflection direction (incident angle, normal)
  float3 caculatereflectdir (float3 i, float3 n) {
  float3 r=i-2.0f * n * dot (i, n);
  return r;
  }
  //Calculate the line of sight refraction direction
  float3 caculaterefractdir (float3 i, float3 n, float etaratio) {
  float costheta=dot (-i, n);
  float costheta2=sqrt (1.f-pow (etaratio, 2) * (1-pow (costheta, 2)));
  float3 t=etaratio * (i + n * costheta)-n * costheta2;
  return t;
  }
  //Calculate the Fresnel effect
  float caculatefresnel (float3 i, float3 n) {
  float fresnel=max (0, min (1, _fresnelbias + _fresnelscale * pow (min (0.0, 1.0-dot (i, n)), _fresnelpower)));
  return fresnel;
  }
  v2f vert (appdata v)
  {
  v2f o;
  o.vertex=unityobjecttoclippos (v.vertex);
  //line of sight
  o.viewdir=normalize (mul (unity_objecttoworld, v.vertex) .xyz-_worldspacecamerapos);
  //normal direction
  o.normaldir=normalize (mul ((float3x3) unity_objecttoworld, v.normal));
  return o;
  }
  fixed4 frag (v2f i):sv_target
  {
  //Sample the skybox color after reflection and refraction
  float3 reflectdir=caculatereflectdir (i.viewdir, i.normaldir);
  float4 reflectcol=texcube (_cube, reflectdir);
  float3 refractdir=caculaterefractdir (i.viewdir, i.normaldir, _etaratio);
  float4 refractcol=texcube (_cube, refractdir);
  //The more vertical the line of sight, the smaller the refraction
  float fresnel=caculatefresnel (i.viewdir, i.normaldir);
  float4 col=lerp (refractcol, reflectcol, fresnel);
  return col;
  }
  endcg
 }
 }
}
  • Previous Unity implements attack range detection and draws detection area
  • Next Unity Shader achieves dynamic fog effect