Unity引擎使用InteriorCubeMap采样制作假室内效果

news2024/11/18 23:38:10

Unity引擎制作假室内效果

  大家好,我是阿赵。
  这次来介绍一种使用CubeMap做假室内效果的方式。这种技术名叫InteriorCubeMap,是UE引擎自带的节点效果。我这里是在Unity引擎里面的实现。

一、效果展示

这个假室内效果,要动态看才能看出效果,各位可以看看上面的视频
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  简单来说,从不同的角度看这个面片,看到的里面的内容会随着视角的变化而变化,感觉好像从窗外观看室内的效果。

二、原理分析

在这里插入图片描述

实际上,并没有什么室内效果,那些都是一个一个的面片来的。
在这里插入图片描述

  面片所显示的内容,其实是CubeMap贴图。
  CubeMap贴图的用法之前在写天空盒变化的文章里面介绍过,各位可以去看看:
  https://blog.csdn.net/liweizhao/article/details/129603219
  当时的CubeMap采样时通过计算世界空间的ViewDir和世界空间的法线方向来做的

float3 worldViewDir = UnityWorldSpaceViewDir(i.worldPos);
worldViewDir = normalize(worldViewDir);
float3 worldReflect = reflect(worldViewDir,i.worldNormal);
float4 col = texCUBE(_SkyTex1, worldReflect);

  所以如果使用在一个面片上面,也能做到里面的内容跟随这视角变化而变化,但由于面片的法线方向都是朝着同一个方向的,所以显示在上面的CubeMap是一个平面的效果。
但这个InteriorCubeMap的计算采样CubeMap的UV的方式比较特别,它会模拟成一个方形来采样CubeMap。
  我把这个InteriorCubeMap节点的代码模拟成一个方法,求出一个采样的UV:

float3 InteriorCubeMap(float3 worldPosition,  float3 worldTangent,float3 worldNormal,float3 worldBitangent,float2 uv)
{
	float3 tanToWorld0 = float3(worldTangent.x, worldBitangent.x, worldNormal.x);
	float3 tanToWorld1 = float3(worldTangent.y, worldBitangent.y, worldNormal.y);
	float3 tanToWorld2 = float3(worldTangent.z, worldBitangent.z, worldNormal.z);
	float3 worldViewDir = UnityWorldSpaceViewDir(worldPosition);
	worldViewDir = normalize(worldViewDir);
	float3 tanViewDir = tanToWorld0 * worldViewDir.x + tanToWorld1 * worldViewDir.y + tanToWorld2 * worldViewDir.z;
	tanViewDir = Unity_SafeNormalize(tanViewDir);
	float3 step1Val = (float3(-1, -1, 1) * tanViewDir);
	float3 step2Val = (1.0 / step1Val);
	float3 step3Val = (float3(((frac(((uv * float2(1, -1)) * (_Tilling).xx)) * float2(2, -2)) - float2(1, -1)), -1.0*_Depth));
	float3 step4Val = (abs(step2Val) - (step2Val * step3Val));
	float3 step5Val = ((min(min(step4Val.x, step4Val.y), step4Val.z) * step1Val) + step3Val);
	return (float3(step5Val.z, step5Val.x, step5Val.y));
}

在这里插入图片描述

  通过调节Depth参数,可以模拟不同深度的室内效果。
在这里插入图片描述

  通过调节Tilling平铺次数,可以模拟多个相同的房间放在一起的效果。

三、代码

Shader "azhao/InteriorCubeMapTest"
{
	Properties
	{
		_Tilling("Tilling", Vector) = (1,1,1,1)
		_CubeTex("Texture Sample 0", CUBE) = "white" {}
		_Depth("Depth",Range(0,5)) = 1
	}

	SubShader
	{


		Tags { "RenderType" = "Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"
			#include "UnityStandardBRDF.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float4 color : COLOR;
				float4 tangent : TANGENT;
				float3 normal : NORMAL;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
				float2 uv : TEXCOORD0;
				float3 worldPos : TEXCOORD1;
				float3 worldTangent : TEXCOORD2;
				float3 worldNormal : TEXCOORD3;
				float3 worldBitangent : TEXCOORD4;

			};

			samplerCUBE _CubeTex;
			float2 _Tilling;
			float _Depth;
			float3 InteriorCubeMap(float3 worldPosition,  float3 worldTangent,float3 worldNormal,float3 worldBitangent,float2 uv)
			{
				float3 tanToWorld0 = float3(worldTangent.x, worldBitangent.x, worldNormal.x);
				float3 tanToWorld1 = float3(worldTangent.y, worldBitangent.y, worldNormal.y);
				float3 tanToWorld2 = float3(worldTangent.z, worldBitangent.z, worldNormal.z);
				float3 worldViewDir = UnityWorldSpaceViewDir(worldPosition);
				worldViewDir = normalize(worldViewDir);
				float3 tanViewDir = tanToWorld0 * worldViewDir.x + tanToWorld1 * worldViewDir.y + tanToWorld2 * worldViewDir.z;
				tanViewDir = Unity_SafeNormalize(tanViewDir);
				float3 step1Val = (float3(-1, -1, 1) * tanViewDir);
				float3 step2Val = (1.0 / step1Val);
				float3 step3Val = (float3(((frac(((uv * float2(1, -1)) * (_Tilling).xy)) * float2(2, -2)) - float2(1, -1)), -1.0*_Depth));
				float3 step4Val = (abs(step2Val) - (step2Val * step3Val));
				float3 step5Val = ((min(min(step4Val.x, step4Val.y), step4Val.z) * step1Val) + step3Val);
				return (float3(step5Val.z, step5Val.x, step5Val.y));
			}

			v2f vert(appdata v)
			{
				v2f o;

				o.worldTangent = UnityObjectToWorldDir(v.tangent);
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				float vertexTangentSign = v.tangent.w * unity_WorldTransformParams.w;
				float3 worldBitangent = cross(o.worldNormal, o.worldTangent) * vertexTangentSign;
				o.worldBitangent.xyz = worldBitangent;
				o.uv = v.uv;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;

				return o;
			}

			half4 frag(v2f i) : SV_Target		{

				float3 cubeUV = InteriorCubeMap(i.worldPos,i.worldTangent, i.worldNormal, i.worldBitangent, i.uv);
				half4 finalColor = texCUBE(_CubeTex, cubeUV);
				return finalColor;
			}
			ENDCG
		}
	}


}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Centos上df命令执行无结果卡住没反应记录

记录linux服务器上df命令卡住,解决办法: 报错如下,执行df命令一直卡着,不返回结果,没反应: 想着是之前挂载的其他盘符,由于迁移导致的磁盘卡住,执行如下命令: strace d…

c++实现哈希桶

闭散列的回顾 在前面的学习中我们知道了闭散列的运算规则,当两个数据计算得到的位置发生冲突时,它会自动的往后寻找没有发生冲突的位置,比如说当前数据的内容如下: 当插入的数据为33时计算的位置为3,可是位置3已经被占…

经典人体模型SMPL介绍(一)

SMPL是马普所提出的经典人体模型,目前已成为姿态估计、人体重建等领域必不可少的基础先验。SMPL基于蒙皮和BlendShape实现,从数千个三维人体扫描结果得来,后通过PCA统计学习得来。 论文:SMPL: A Skinned Multi-Person Linear Mode…

教学资源VR设备中控系统为教师带来了许多便利

为提升VR实训室教学的质量,虚拟课堂VR中控系统作为一种新型的教学辅助工具,为学生和教师带来了许多独特的优势。 虚拟课堂VR中控系统作为一种新型的教育工具,为教师带来了许多便利,提高了教学质量和效果。教师可以在VR教室里的触摸…

常识判断

头像 carrin~👻 产品经理 225/753 75/302.5 30/152 15/101.5 等差数列,所以最后一个是10/101 收起 60 回复 发布于 2020-02-18 16:33

茶百道们掀起上市潮,折射出新茶饮即将迎来“惊险一跃”

一只憨态可掬的熊猫手捧一杯奶茶,它蓝白相间的颜色透露出一股清新纯净的气息。 这只名叫丁丁猫的蠢萌熊猫陪着茶百道走出四川,足迹踏遍了全国。 目前,茶百道在全国共有7117家门店,已经成长为新茶饮赛道的头部品牌。根据弗若斯特沙…

DRF 缓存

应用环境 django4.2.3 ,python3.10 由于对于服务而言,有些数据查询起来比较费时,所以,对于有些数据,我们需要将其缓存。 最近做了一个服务,用的时 DRF 的架构,刚好涉及缓存,特此记…

mysql导入sqlserver数据库

1、 2、 3、 必须要保存密码 4、 5、 6、

史上最全的Qt控件

本软件是收费工具,学生党勿扰,闹眼子党勿扰,白嫖党勿扰 收费金额:1000元 1 概述 经过这两年的编写,写不少控件,甚至把刘某某90%的控件都绘制了一遍。当然后还有一些其他刘某没有控件。 2 功能 借用刘某博…

功率放大器在电火花加工中的作用有哪些

电火花加工技术是一种高精度、高效率的制造工艺,在模具制造、航空航天和汽车工业等领域得到了广泛应用。而功率放大器则是电火花加工设备的核心部件之一,它能够改善电火花加工的机械性能和加工质量,提高生产效率。下面我们来详细了解功率放大…

国内外常用的几款组态软件(Web组态)

组态软件,又称监控组态软件,译自英文SCADA,即 Supervision,Control and Data Acquisition(数据采集与监视控制),组态软件的应用领域很广,实际上,这些软件也是一种通用级的软件工具,可以通过灵活…

OpenWrt -- OpenVPN配置ServerClient(TUN模式)

一、前言 目标是两台设备能通过OpenVPN TUN模式建立连接。 准备如下: 设备 友善R2S两台,一台做服务器,一台做客户端。 一台小米R1C,当作网关。 固件 采用openwrt-22.03版本,下载地址:https://downloads.openwrt.org/r…

EmbedPress Pro 在WordPress网站中嵌入任何内容

EmbedPress Pro可让您通过高级自定义、自定义品牌、延迟加载和更多惊人功能嵌入源。为古腾堡块和Elementor编辑器提供支持的一体化 WordPress 嵌入解决方案。使用 EmbedPress 在古腾堡创建交互式内容。使用 EmbedPress 的古腾堡块立即将任何内容嵌入到您的网站。 网址: EmbedP…

合成数据及其在AI领域中的作用

什么是合成数据? 合成数据是由人工创建而非从现实生活中获得的数据,它从机器学习对数据的需求发展而来。最初,为了精确训练AI模型,必须获得涵盖所有可能场景的训练数据。如果某个场景没有发生或未被获得,就没有相应的…

23.8.16日总结

原先写的评论是每级评论用缩进来区分,所以最多设置的是九级评论,修改了排版和格式: 还有管理员页面,查看文章时可以进行点赞,收藏的操作,现在进行了修改,将相关操作隐藏。 还有点击查看未发布…

UE4/UE5 照明构建失败 “Lightmass crashed”解决“数组索引越界”

在构建全局光照时,经常会出现“Lightmass crashed”的错误,导致光照构建失败。本文将分析这一问题的原因,并给出解决建议。 UE4 版本4.26 报错如下: <None> === Lightmass crashed: === Assertion failed: (Index >= 0) & (Index < ArrayNum) [File:d:\build…

Android Studio 新建module报错:No signature of method

android平台uni原生插件开发过程中&#xff0c;使用Android Studio 新增 module 报错 选择app --> create new module &#xff0c;填写相关信息 Android Studio 新建module报错&#xff1a; 原因&#xff1a;Android Studio 版本过高&#xff0c;新增了namespace&#x…

Redis——hash类型详解

概述 Redis本身就是键值对结构&#xff0c;而Redis中的value可以是哈希类型&#xff0c;为了区分这两个键值对&#xff0c;Redis中的键值对是key-value&#xff0c;而value中的哈希键值对则是field-value&#xff0c;其中value必须是字符串 下面介绍一些Redis的hash类型的常用…

数据可视化和数字孪生相互促进的关系

数据可视化和数字孪生是当今数字化时代中备受关注的两大领域&#xff0c;它们在不同层面和领域为我们提供了深入洞察和智能决策的机会&#xff0c;随着两种技术的不断融合发展&#xff0c;很多人会将他们联系在一起&#xff0c;本文就带大家浅谈一下二者之间相爱相杀的关系。 …

软件工程模型-架构师之路(四)

软件工程模型 敏捷开发&#xff1a; 个体和交互 胜过 过程和工具、可以工作的软件 胜过 面面俱到的文件、客户合作胜过合同谈判、响应变化 胜过 循序计划。&#xff08;适应需求变化&#xff0c;积极响应&#xff09; 敏捷开发与其他结构化方法区别特点&#xff1a;面向人的…