欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Unity Shader实现玻璃材质效果

程序员文章站 2023-02-19 15:32:46
unity shader学习:玻璃材质,供大家参考。主要是通过反射和折射来达到透明的效果,用菲涅尔来混叠。shader部分:shader "unlit/crystal"{ properties { _...

unity shader学习:玻璃材质,供大家参考。

主要是通过反射和折射来达到透明的效果,用菲涅尔来混叠。

Unity Shader实现玻璃材质效果

shader部分:

shader "unlit/crystal"
{
 properties
 {
 _cube("skybox",cube)=""{}
 //折射角度
 _etaratio("etaratio", range(0, 1)) = 0
 //菲涅尔系数
 _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;
  
  //计算视线反射方向(入射角,法线)
  float3 caculatereflectdir(float3 i, float3 n) {
  float3 r = i - 2.0f*n*dot(i,n);
  return r;
  }

  //计算视线折射方向
  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;
  }

  //计算菲涅尔效应
  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);
  //视线方向
  o.viewdir = normalize(mul(unity_objecttoworld, v.vertex).xyz - _worldspacecamerapos);
  //法线方向
  o.normaldir = normalize(mul((float3x3)unity_objecttoworld, v.normal));
  return o;
  }
  
  fixed4 frag (v2f i) : sv_target
  {
  //采样反射折射后的天空盒颜色
  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);
  //视线越垂直折射越小
  float fresnel = caculatefresnel(i.viewdir, i.normaldir);
  float4 col = lerp(refractcol, reflectcol, fresnel);
  return col;
  }
  endcg
 }
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。