一、使用Cubemap,做一个假反射

shader代码如下:

Shader "Custom/glassShader" {
Properties {
_MainColor("Main Color",Color)=(1,1,1,1)
_MainTex ("Base (RGB)", 2D) = "white" {}
_Cube("Cube",CUBE)=""{}
}
SubShader {
Tags {"RenderType"="Opaque"}
LOD 200 //cull off CGPROGRAM
#pragma surface surf Lambert alpha fixed4 _MainColor;
sampler2D _MainTex;
samplerCUBE _Cube; struct Input {
float2 uv_MainTex;
float3 worldRefl;
}; void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb*_MainColor.rgb;
o.Emission=texCUBE(_Cube,IN.worldRefl).rgb;
o.Alpha = c.a*_MainColor.a;
}
ENDCG
}  FallBack "Diffuse"
}

二、使用GrabPass,抓取屏幕纹理,实现实时反射

shader代码如下:

Shader "Unlit/GrabGlass"
{
Properties
{
_Color("Main Color",Color)=(1,1,1,1)
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{ Tags {"Queue"="Transparent" "RenderType"="Opaque" }//Opaque
LOD 100 //绘制半透明物体 关闭深度缓存
ZWrite Off
//透明混合
Blend SrcAlpha OneMinusSrcAlpha //如果没有命名,则可以用_GrabTexture来读取,不过开销很大,应用到特殊效果时才去应用
GrabPass
{
"_GrabTex"
} Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog #include "UnityCG.cginc" struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
}; struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
}; sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
sampler2D _GrabTex; v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
} fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv)*_Color; // apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
//调整一下uv
float2 uv=i.uv;
uv.x=1-uv.x;
return col*tex2D(_GrabTex,uv);
}
ENDCG
}
}
}

效果如下:

三、使用摄像机实现实时反射

因为GrabPass,相对来说消耗较大,只建议用于一些特殊效果,于是这里就借助辅助摄像机,来实现实时反射效果,当然这需要多写一个脚本,同时需要在辅助摄像机中屏蔽玻璃本身

shader代码如下:

Shader "Unlit/CameraGlass"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100 Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog #include "UnityCG.cginc" struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
}; struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
}; sampler2D _MainTex;
float4 _MainTex_ST; v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
} fixed4 frag (v2f i) : SV_Target
{
// sample the texture  需要调整一下uv
fixed4 col = tex2D(_MainTex, 1-i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}

脚本代码如下:

using UnityEngine;
using System.Collections; public class RenderGlassTexture : MonoBehaviour {
    
    /// <summary>
    /// 辅助摄像机 
    /// 原理:就是将辅助摄像机所看到的内容渲染到玻璃物体上,所以就实现了实时反射的镜面效果
    /// 因为玻璃也是场景中的物体,所以辅助摄像机也会看见他
    /// 所以最好能将玻璃物体单独放在一个层级中,让辅助摄像机不去渲染他
    /// </summary>
    public Camera cam;
    private RenderTexture renderTex;
    /// <summary>
    /// 玻璃shader
    /// </summary>
    public Shader glassShader;
    /// <summary>
    /// 玻璃材质
    /// </summary>
    private Material m_GlassMaterial;
    protected Material GlassMaterial
    {
        get
        {
            if (m_GlassMaterial == null)
            {
                m_GlassMaterial = new Material(glassShader);
            }
            return m_GlassMaterial;
        }
    }     // Use this for initialization
void Start () {
        renderTex = new RenderTexture(Screen.width, Screen.height, 16);
        cam.targetTexture = renderTex;
}     //在摄像机开始裁剪场景之前调用
    void OnPreCull()
    {
        GlassMaterial.SetTexture("_MainTex", renderTex);
    }     //在相机完成场景渲染后调用
    void OnPostRender()
    {
        GlassMaterial.SetTexture("_MainTex", null);
    }
}

效果如下:

unity实现玻璃效果的更多相关文章

  1. Unity Shader 玻璃效果

    一个玻璃效果主要分为两个部分,一部分是折射效果的计算,另一部分则是反射.下面分类进行讨论: 折射: 1.利用Grass Pass对当前屏幕的渲染图像进行采样 2.得到法线贴图对折射的影响 3.对采集的 ...

  2. 【Unity Shader】(九) ------ 高级纹理之渲染纹理及镜子与玻璃效果的实现

    笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题. [Unity Shader](三) ----- ...

  3. Unity shader学习之Grab Pass实现玻璃效果

    GrabPass可将当前屏幕的图像绘制在一张纹理中,可用来实现玻璃效果. 转载请注明出处:http://www.cnblogs.com/jietian331/p/7201324.html shader ...

  4. 使用canvas实现擦玻璃效果

    体验效果:http://hovertree.com/texiao/html5/25/ 效果图: 代码如下: <!DOCTYPE html> <html> <head la ...

  5. 使用canvas实现擦玻璃效果---转载

    <!DOCTYPE html> <html> <head lang="zh"> <meta name="viewport&quo ...

  6. DevExpress中透明玻璃效果

    Aero玻璃效果 下图左是DevExpress无玻璃效果,图右是Windows自带玻璃效果. Windows Aero 是从 Windows Vista 开始使用的新型用户界面,透明玻璃感让用户一眼贯 ...

  7. DWM 窗体玻璃效果实现

    我一直盼望着 Windows 新版本的发布.令人感兴趣的事情莫过于浏览 MSDN® 和 SDK 文档,查找一些可以利用和依赖的最新创新,然后让朋友和同事以及您的老板(如果幸运的话)大开眼界.Windo ...

  8. 又是玻璃效果?调用一句代码就OK了

    原文 http://www.cnblogs.com/lan-mei/archive/2012/05/11/2495740.html 最近自学WPF,网上一查资料,全是依赖属性,路由事件,动画效果等等. ...

  9. 【转】DWM 窗体玻璃效果实现

    我一直盼望着 Windows 新版本的发布.令人感兴趣的事情莫过于浏览 MSDN® 和 SDK 文档,查找一些可以利用和依赖的最新创新,然后让朋友和同事以及您的老板(如果幸运的话)大开眼界.Windo ...

随机推荐

  1. JavaScript for 循环

    循环可以将代码块执行指定的次数. JavaScript 循环 如果您希望一遍又一遍地运行相同的代码,并且每次的值都不同,那么使用循环是很方便的. 我们可以这样输出数组的值: 一般写法: documen ...

  2. 虚拟机克隆,并设置新的ip

    6.1克隆新的虚拟机 选中某个虚拟机-à右键à管理à克隆 选择下一步 选择下一步 点击完成 6.2修改主机名 [root@hadoop3 ~]# vim/etc/sysconfig/network 将 ...

  3. linux:关于Linux系统中 CPU Memory IO Network的性能监测

    我们知道:系统优化是一项复杂.繁琐.长期的工作.通常监测的子系统有以下这些:CPUMemoryIO Network 下面是常用的监测工具 Linux 系统包括很多子系统(包括刚刚介绍的CPU,Memo ...

  4. Android开发学习之路--基于vitamio的视频播放器(一)

      之前也试过vitamio这个库,后来不知道被什么事情给耽搁了,就没继续下去.近来觉得视频还是需要学习一下的,谁让直播那么火呢,就想着写一个简单的视频播放的app先吧.好了那就开始吧,暂时取名为JP ...

  5. Hibernate之实体关系映射

    延迟加载与即时加载 例如Person类和Email类是一对多关系,如果设为即时加载,当加载Person时,会自动加载Email,如果设置为延迟加载,当第一次调用person.getEmails()时才 ...

  6. EXT JS认识EXTJS,第一个EXTJS例子

    大部分内容转载自:http://blog.csdn.net/wanghuan203/article/details/8011112 和http://www.cnblogs.com/willick/p/ ...

  7. x264源代码简单分析:滤波(Filter)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  8. Erlang递归列举目录下文件

    Erlang递归列举目录下文件(金庆的专栏)%%%-------------------------------------------------------------------%%% @aut ...

  9. Java基本语法-----java流程控制语句

    1顺序语句 语句:使用分号分隔的代码称作为一个语句. 注意:没有写任何代码只是一个分号的时候,也是一条语句,称作空语句. 顺序语句就是按照从上往下的顺序执行的语句. 2判断(if-else) 在我们找 ...

  10. 与markdown的第一次接触

    什么是markdown markdown是一种比html轻量级的标记语言. markdown的介绍与学习请参考:markdown认识与入门 CSDN Markdown博客视频教程 知乎: 怎样引导新手 ...