打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
【Unity Shader实战】利用凹凸纹理和边缘光模拟全息投影的效果

0x00 序言
项目需要模型在展示时,可以拥有类似全息投影的效果,类似一些科幻电影或者是高科技的场景。本文分析了如何利用凹凸纹理和边缘光来近似模拟这种效果。
0x01 效果图


0x02 基本概念
本次的shader部分主要修改了surface shader,其中的一些基本概念:

  • SurfaceOutput是预定义的输出结构:
struct SurfaceOutput {    half3 Albedo;     //纹理颜色(r,g,b)    half3 Normal;     //法向量(x,y,z)    half3 Emission;   //自发光颜色(r,g,b)    half Specular;    //镜面反射度    half Gloss;       //光泽度    half Alpha;       //透明度};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • UnpackNormal
    UnpackNormal接受一个fixed4的输入,并将其转换为所对应的法线值(fixed3),并将其赋给输出的Normal。
o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
  • 1
  • saturate( )函数

作用其实也就是将取值转化为[0,1]之内的一个值。如果 x 小于 0,返回 0;如果 x 大于 1,返回1;否则,返回 x

0x03 Shader代码
下面的代码算是强撸出来的,参考了网上一些资料。有些细节还不是很明了,希望能倒逼自己花时间把所有原理吃透。

  Shader "CoffeecatGame/Hologram" {    Properties {      _MainTex ("Texture", 2D) = "white" {}      _BumpMap ("Bumpmap", 2D) = "bump" {}      // 边缘颜色        _RimColor("Rim Color", Color) = (0.26,0.7,1.0,0.0)      // 边缘颜色强度        _RimPower("Rim Power", Range(0.1,8.0)) = 3.0      // 像素 颜色强度系数        _RimIntensity("Rim Intensity", Range(0.1,8.0)) = 3.0      // 条纹粗细        _ClipPower("Clip Power", Range(0.0,301.0)) = 200.0        _Brightness("Brightness",Range(0.0,30)) = 1.5        _Alpha("Alpha", Range(0.0,1.0)) = 0.0      // 条纹颜色插值系数        _Crackle("Crackle", Range(0.0, 1.0)) = 0.0    }    SubShader {      //"RenderType" = "Transparent"  半透明着色器      //"Queue"="Transparent" 半透明物体渲染队列      //"IgnoreProjector"="True"  忽略投影      Tags { "RenderType" = "Transparent"  "Queue"="Transparent" "IgnoreProjector"="True"}     Pass {       //ZWrite On  深度写入 开启       //ColorMask 0 设置颜色写遮罩 关闭所有颜色通道渲染        ZWrite On        ColorMask 0       }      CGPROGRAM      //Lambert,声明了表面着色器,并指定了光照模型。      #pragma surface surf Lambert alpha       struct Input {          float2 uv_MainTex;          float2 uv_BumpMap;          float3 viewDir;          float3 worldPos;              float4 screenPos;            };      sampler2D _MainTex;      sampler2D _BumpMap;      float4 _RimColor;      float _RimPower;      float _ClipPower;      float _Brightness;      float _Alpha;      float _RimIntensity;      float _Crackle;      void surf (Input IN, inout SurfaceOutput o)       {          float2 screenUV = IN.screenPos.xy / IN.screenPos.w;          // 扩散系数          float _DiffuseAmount = 1;          // 在贴图颜色与RimColor之间做插值          half4 basecol = lerp(tex2D(_MainTex, IN.uv_MainTex), _RimColor, _Crackle);          // 获取贴图颜色对应的灰度图          half3 graycol = dot(basecol.rgb, float3(0.3, 0.59, 0.11));          // frac 返回小数部分          if (frac(screenUV.y * _ClipPower) - 0.5 > 0)            _DiffuseAmount = 1;          else             _DiffuseAmount = 0;          if (_ClipPower == 0)          {            _DiffuseAmount = 1;          }          // 像素的颜色           o.Albedo = lerp(graycol, basecol, _DiffuseAmount);          // 从凹凸纹理提取法线信息          o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));          // 从_RimColor参数获取自发光颜色(_Brightness是增强因子)          half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));          o.Emission = lerp(_RimColor.rgb * pow (rim, _RimPower) * _Brightness, basecol, _DiffuseAmount) * _Brightness;          o.Alpha = _Alpha;      }      ENDCG    }     Fallback "Diffuse"  }
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Shader之LimLighting
【浅墨Unity3D Shader编程】之六 暗黑城堡篇: 表面着色器(Surface Shader...
【浅墨Unity3D Shader编程】之五 圣诞夜篇: Unity中Shader的三种形态对比&混合操作合辑
Unity shader 官网文档全方位学习(一)
猫都能学会的Unity3D Shader入门指南(一)
[原]【浅墨Unity3D Shader编程】之六 暗黑城堡篇: 表面着色器(Surface Shader)的写法(一)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服