Unity_使用Shader实现玻璃和镜面效果

效果图如下:

                                                                        玻璃效果图

                                                                        镜面效果图

Step1

搭建场景→镜子使用Quad代替,放置在需要反射的墙面→创建新的材质和Shader

Step2

墙壁外创建Camera,用来渲染物体后方的视图→创建RenderTexture,赋于该相机

Step3

Shader的编写如下:

①:玻璃Shader

Shader "UnityShaderBook/Chapter10/Mirror"
{
    Properties {
		_MainTex ("Main Tex", 2D) = "white" {}
	}
	SubShader {
		Tags { "RenderType"="Opaque" "Queue"="Geometry"}
		
		Pass {
			CGPROGRAM
			
			#pragma vertex vert
			#pragma fragment frag
			
			sampler2D _MainTex;
			
			struct a2v {
				float4 vertex : POSITION;
				float3 texcoord : TEXCOORD0;
			};
			
			struct v2f {
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
			};
			
			v2f vert(a2v v) {
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				
				o.uv = v.texcoord;
				// Mirror needs to filp x
				o.uv.x = 1 - o.uv.x;
				
				return o;
			}
			
			fixed4 frag(v2f i) : SV_Target {
				return tex2D(_MainTex, i.uv);
			}
			
			ENDCG
		}
	} 
 	FallBack Off
}

②镜面Shader

Shader "Unity Shaders Book/Chapter 10/Glass Refraction" {
	Properties {
		_MainTex ("Main Tex", 2D) = "white" {}
		_BumpMap ("Normal Map", 2D) = "bump" {}
		_Cubemap ("Environment Cubemap", Cube) = "_Skybox" {}
		_Distortion ("Distortion", Range(0, 100)) = 10
		_RefractAmount ("Refract Amount", Range(0.0, 1.0)) = 1.0
	}
	SubShader {
		// We must be transparent, so other objects are drawn before this one.
		Tags { "Queue"="Transparent" "RenderType"="Opaque" }
		
		// This pass grabs the screen behind the object into a texture.
		// We can access the result in the next pass as _RefractionTex
		GrabPass { "_RefractionTex" }
		
		Pass {		
			CGPROGRAM
			
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"
			
			sampler2D _MainTex;
			float4 _MainTex_ST;
			sampler2D _BumpMap;
			float4 _BumpMap_ST;
			samplerCUBE _Cubemap;
			float _Distortion;
			fixed _RefractAmount;
			sampler2D _RefractionTex;
			float4 _RefractionTex_TexelSize;
			
			struct a2v {
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent : TANGENT; 
				float2 texcoord: TEXCOORD0;
			};
			
			struct v2f {
				float4 pos : SV_POSITION;
				float4 scrPos : TEXCOORD0;
				float4 uv : TEXCOORD1;
				float4 TtoW0 : TEXCOORD2;  
			    float4 TtoW1 : TEXCOORD3;  
			    float4 TtoW2 : TEXCOORD4; 
			};
			
			v2f vert (a2v v) {
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				
				o.scrPos = ComputeGrabScreenPos(o.pos);
				
				o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
				o.uv.zw = TRANSFORM_TEX(v.texcoord, _BumpMap);
				
				float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;  
				fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);  
				fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);  
				fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w; 
				
				o.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);  
				o.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);  
				o.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);  
				
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target {		
				float3 worldPos = float3(i.TtoW0.w, i.TtoW1.w, i.TtoW2.w);
				fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPos));
				
				// Get the normal in tangent space
				fixed3 bump = UnpackNormal(tex2D(_BumpMap, i.uv.zw));	
				
				// Compute the offset in tangent space
				float2 offset = bump.xy * _Distortion * _RefractionTex_TexelSize.xy;
				i.scrPos.xy = offset * i.scrPos.z + i.scrPos.xy;
				fixed3 refrCol = tex2D(_RefractionTex, i.scrPos.xy/i.scrPos.w).rgb;
				
				// Convert the normal to world space
				bump = normalize(half3(dot(i.TtoW0.xyz, bump), dot(i.TtoW1.xyz, bump), dot(i.TtoW2.xyz, bump)));
				fixed3 reflDir = reflect(-worldViewDir, bump);
				fixed4 texColor = tex2D(_MainTex, i.uv.xy);
				fixed3 reflCol = texCUBE(_Cubemap, reflDir).rgb * texColor.rgb;
				
				fixed3 finalColor = reflCol * (1 - _RefractAmount) + refrCol * _RefractAmount;
				
				return fixed4(finalColor, 1);
			}
			
			ENDCG
		}
	}
	
	FallBack "Diffuse"
}

Step4

将RenderTexture赋于材质球

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/366836.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何使用本地私有NuGet服务器

写在前面 上一篇介绍了如何在本地搭建一个NuGet服务器, 本文将介绍如何使用本地私有NuGet服务器。 操作步骤 1.新建一个.Net类库项目 2.打包类库 操作后会生成一个.nupkg文件,当然也可以用dotnet pack命令来执行打包。 3.推送至本地NuGet服务器 打开命…

来看看Tomcat和Web应用的目录结构

在前面两篇大致了解了Tomcat的架构和运行流程,以及Tomcat应用中的web.xml。 聊一聊Tomcat的架构和运行流程,尽量通俗易懂一点-CSDN博客 来吧,好好理解一下Tomcat下的web.xml-CSDN博客 那接下来,再看看Tomcat的目录,…

el-table点击某一行选中改变背景色且执行方法

elementUI table表格点击某一行选中并且改变背景色 使用:row-style"rowStyle"及row-click“selectRow”: 其中 selectRow 方法中: row 输出:当前行的内容 column 输出:当前列的信息 event 输出:当前事件 …

Unknown custom element:<xxx>-did you register the component correctly解决方案

如图所示控制台发现了爆红(大哭): 报错解释: 当我们看到报错时,我们需要看到一些关键词,比如显眼的“component”和“name”这两个单词, 因此我们就从此处切入,大概与组件有关系。…

洛谷 B3635 硬币问题(DP入门)

[题目概述] 今有面值为 1、5、11 元的硬币各无限枚。 想要凑出 n 元,问需要的最少硬币数量。 输入格式 仅一行,一个正整数 n。 输出格式 仅一行,一个正整数,表示需要的硬币个数。 输入 15输出 3输入 12输出 2样例解释 …

深度学习入门笔记(二)神经元的结构

神经网络的基本单元是神经元,本节我们介绍神经元的结构。 2.1 神经元 一个神经元是由下面 5 部分组成的: 输入:x1,x2,…,xk。权重:w1,w2,…,wk。权重的个数与神经元输入的个数相同。偏移项:可省略。激活函数&#…

Hadoop:HDFS学习巩固——基础习题及编程实战

一 HDFS 选择题 1.对HDFS通信协议的理解错误的是? A.客户端与数据节点的交互是通过RPC(Remote Procedure Call)来实现的 B.HDFS通信协议都是构建在IoT协议基础之上的 C.名称节点和数据节点之间则使用数据节点协议进行交互 D.客户端通过一…

【Vue】指令之内容绑定,事件绑定

Vue指令[1] 内容绑定,事件绑定v-test指令v-html指令v-on基础 内容绑定,事件绑定 v-test指令 作用:设置标签的文本值(textContent) 默认写法会替换全部内容,使用差值表达式可以替换指定内容内部支持写表达…

Nicn的刷题日常之打印菱形

目录 1.题目描述 2.解题思路 3.解题 1.题目描述 用C语言在屏幕上输出以下图案: 2.解题思路 仔细观察图形,可以发现,此图形中是由空格和*按照不同个数的输出组成的。 上三角:先输出空格,后输出*,每…

谈谈BlueStore

目录 未完待续前言组成前期准备工作基础概念对象PextentextentBlobNode 线程事务磁盘的抽象与分配位图法分层位图 上电流程写流程读流程参考资料 未完待续 前言 BlueStore是什么? Ceph是一个统一的分布式存储系统。BlueStore是Ceph的存储引擎。 它的作用是什么&am…

C语言:内存函数(memcpy memmove memset memcmp使用)

和黛玉学编程呀------------- 后续更新的节奏就快啦 memcpy使用和模拟实现 使用 void * memcpy ( void * destination, const void * source, size_t num ) 1.函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。 2.这个函数在遇到 \0 的时候…

深入理解网络编程之BIO和NIO

目录 原生JDK网络编程BIO BIO通信模型服务端代码 BIO通信模型客户端代码 伪异步模型服务端代码(客户端跟之前一致) 原生JDK网络编程NIO 什么是NIO? NIO和BIO的主要区别 阻塞与非阻塞IO NIO之Reactor模式 NIO中Reactor模式的基本组成…

【深度学习】基于PyTorch架构神经网络学习总结(基础概念基本网络搭建)

神经网络整体架构 类似于人体的神经元 神经网络工作原来为层次结构,一层一层的变换数据。如上述示例有4层,1层输入层、2层隐藏层、1层输出层神经元:数据的量或矩阵的大小,如上述示例中输入层中有三个神经元代表输入数据有3个特征…

国家博物馆逆向抢票协议

逆向工程的具体步骤可以因项目和目标系统的不同而有所变化。然而,以下是一般逆向工程的一般步骤: 1. 分析目标系统:对待逆向的系统进行调研和了解,包括其架构、功能、使用的技术等方面的信息。 2. 反汇编或反编译:使…

简单实践 java spring boot 自动配置模拟

1.概要 1.1 需求,自己写一个redis-spring-boot-starter模拟自动配置 自动配置就是在引入*-starter坐标后,可以已经spring框架的规则实现一些Bean的自动注入,并设置一些参数的默认值,且也可以在引入的工程中修改这些配置的值。这…

【算法】约数之和(数论)

题目 给定 n 个正整数 ai,请你输出这些数的乘积的约数之和,答案对 1097 取模。 输入格式 第一行包含整数 n。 接下来 n 行,每行包含一个整数 ai。 输出格式 输出一个整数,表示所给正整数的乘积的约数之和,答案需…

openssl3.2 - 官方demo学习 - pkcs12 - pkwrite.c

文章目录 openssl3.2 - 官方demo学习 - pkcs12 - pkwrite.c概述学到的知识点笔记PEM证书可以拼接实验 pkcs12 - pkwrite.c用win10的证书管理器安装P12证书是成功的END openssl3.2 - 官方demo学习 - pkcs12 - pkwrite.c 概述 openssl3.2 - 官方demo学习 - 索引贴 上次PKCS12的…

比瓴科技入围软件供应链安全赛道!为关键信息基础设施安全建设注入新动力

1月20日,中关村华安关键信息基础设施安全保护联盟会员大会暨关键信息基础设施安全保护论坛在北京成功举办,比瓴科技作为会员单位受邀出席。 本次论坛发布了《关键信息基础设施安全保护支撑能力白皮书(2023)》,比瓴科技…

智能分析网关V4+EasyCVR视频融合平台——高速公路交通情况的实时监控和分析一体化方案

随着2024年春运帷幕的拉开,不少人的返乡之旅也即将开启,从这几日的新闻来看,高速上一路飘红。伴随恶劣天气,加上激增的车流,极易导致高速瘫痪,无法正常使用。为解决此问题,助力高速高效运营&…

Cmake语法学习2:常用变量

目录 1.常用变量简介 1.1提供信息的变量 1.2改变行为的变量 1.3描述系统的变量 ​编辑1.4控制编译的变量 2.提供信息的变量 2.1PROJECT_SOURCE_DIR 和 PROJECT_BINARY_DIR 2.2 CMAKE_SOURCE_DIR 和 CMAKE_BINARY_DIR 2.3CMAKE_CURRENT_SOURCE_DIR 和CMAKE_CURRENT_BIN…
最新文章