一、使用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. 使用Spring实现定时任务

    一.分类 从实现的技术上来分类,目前主要有三种技术(或者说有三种产品): Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可 ...

  2. Ruby 2.x 命名参数特性简介

    我以前曾有一个梦想,就是我的爹是李嘉诚-,那个-,不是啦,我的梦想是ruby像ObjC,或是现在的swift那样给方法提供命名参数. 之前的ruby只能用hash来模拟这个行为,不过你没法很容易的定义 ...

  3. Ribbon WorkBench 当ValueRule的值为空时的设置

    在定制Ribbon按钮的规则的时候,有时需要根据某个字段值是否为空不设定Ribbon按钮的Display rules或Enable Rules,根据Crm的版本的不同,设置有所差别: 对于Dynami ...

  4. EBS销售订单挑库发放处理程序

    来自:http://blog.csdn.net/cunxiyuan108/article/details/6014769 在EBS实施中,经常遇到从外部传进来一个被登记的销售订单,需要通过程序进行销售 ...

  5. tomcat生命周期的管理——生命周期统一接口Lifecycle

    我们知道Tomcat的架构设计是清晰的.模块化的,其拥有很多组件,假如我们要启动Tomcat,可以一个一个启动组件,但这样启动有很多缺点,不仅麻烦,而且容易漏了组件启动,还会对后面动态组件扩展带来麻烦 ...

  6. FORM的静态提交

     在form中进行保存时,如果使用commit_form的话会弹出信息提示"没有修改需要保存"或者"几条记录已保存"类似的字样,有时候不想被提示,可以使用A ...

  7. C库源码中的移位函数

    #include <stdio.h> /* _lrotr()将一个无符号长整形数左循环移位的函数 原形:unsigned long _lrotr(unsigned long value,i ...

  8. UE4成批处理透明材质

    项目中需要控制成批的物体的透明度,但是默认的时候他又不能是透明的,对,项目的要求就这么诡异. 然而却没有找到设置材质的BlendMode的功能,于是只有换了一种办法,物体需要透明时更换为透明材质,默认 ...

  9. Android 自定义View-android学习之旅(十四)

    自定义View的步骤 当andoid提供的系统组件不满足要求时候,完全可以集成View来派生自定义组件. 首定定义一个继承View的子类,然后重写他一个或几个方法. 重写的方法介绍 构造器:这是定制V ...

  10. Sky(dart)语言介绍-android学习之旅(十)

    认识dart语言 google于2011年10月10日发布了"dart"语言的"早起预览版",google希望利用这款语言,帮助开发者克服javaScript的 ...