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

2024-02-03 22:52

本文主要是介绍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 fragsampler2D _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 xo.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 _RefractionTexGrabPass { "_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 spacefixed3 bump = UnpackNormal(tex2D(_BumpMap, i.uv.zw));	// Compute the offset in tangent spacefloat2 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 spacebump = 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赋于材质球

这篇关于Unity_使用Shader实现玻璃和镜面效果的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/675668

相关文章

Python实现AVIF图片与其他图片格式间的批量转换

《Python实现AVIF图片与其他图片格式间的批量转换》这篇文章主要为大家详细介绍了如何使用Pillow库实现AVIF与其他格式的相互转换,即将AVIF转换为常见的格式,比如JPG或PNG,需要的小... 目录环境配置1.将单个 AVIF 图片转换为 JPG 和 PNG2.批量转换目录下所有 AVIF 图

Pydantic中Optional 和Union类型的使用

《Pydantic中Optional和Union类型的使用》本文主要介绍了Pydantic中Optional和Union类型的使用,这两者在处理可选字段和多类型字段时尤为重要,文中通过示例代码介绍的... 目录简介Optional 类型Union 类型Optional 和 Union 的组合总结简介Pyd

Pydantic中model_validator的实现

《Pydantic中model_validator的实现》本文主要介绍了Pydantic中model_validator的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录引言基础知识创建 Pydantic 模型使用 model_validator 装饰器高级用法mo

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

AJAX请求上传下载进度监控实现方式

《AJAX请求上传下载进度监控实现方式》在日常Web开发中,AJAX(AsynchronousJavaScriptandXML)被广泛用于异步请求数据,而无需刷新整个页面,:本文主要介绍AJAX请... 目录1. 前言2. 基于XMLHttpRequest的进度监控2.1 基础版文件上传监控2.2 增强版多

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建

Redis分片集群的实现

《Redis分片集群的实现》Redis分片集群是一种将Redis数据库分散到多个节点上的方式,以提供更高的性能和可伸缩性,本文主要介绍了Redis分片集群的实现,具有一定的参考价值,感兴趣的可以了解一... 目录1. Redis Cluster的核心概念哈希槽(Hash Slots)主从复制与故障转移2.

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

使用Python实现一键隐藏屏幕并锁定输入

《使用Python实现一键隐藏屏幕并锁定输入》本文主要介绍了使用Python编写一个一键隐藏屏幕并锁定输入的黑科技程序,能够在指定热键触发后立即遮挡屏幕,并禁止一切键盘鼠标输入,这样就再也不用担心自己... 目录1. 概述2. 功能亮点3.代码实现4.使用方法5. 展示效果6. 代码优化与拓展7. 总结1.

Mybatis 传参与排序模糊查询功能实现

《Mybatis传参与排序模糊查询功能实现》:本文主要介绍Mybatis传参与排序模糊查询功能实现,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、#{ }和${ }传参的区别二、排序三、like查询四、数据库连接池五、mysql 开发企业规范一、#{ }和${ }传参的