Unity引擎使用InteriorCubeMap采樣制作假室內效果

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 100Pass{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.pswp.cn/news/39554.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/39554.shtml
英文地址,請注明出處:http://en.pswp.cn/news/39554.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

柏睿向量數據庫Rapids VectorDB賦能企業級大模型構建及智能應用

ChatGPT的問世,在為沉寂已久的人工智能重新注入活力的同時,也把長期默默無聞的向量數據庫推上舞臺。今年4月以來,全球已有4家知名向量數據庫公司先后獲得融資,更加印證了向量數據庫在AI大模型時代的價值。 什么是向量數據庫? 在認識向量數據庫前,先來了解一下最常見的關…

【業務功能篇62】Spring boot maven多模塊打包時子模塊報錯問題

程序包 com.xxx.common.utils不存在或者xxx找不到符號 我們項目中一般都是會分成多個module模塊,做到解耦,方便后續做微服務拆分模塊,可以直接就每個模塊進行打包拎出來執行部署這樣就會有模塊之間的調用,比如API模塊會被Service…

【SpringBoot】SpringBoot獲取不到用戶真實IP怎么辦

文章目錄 前言問題原因解決方案修改Nginx配置文件SpringBoot代碼實現 前言 項目部署后發現服務端無法獲取到客戶端真實的IP地址,這是怎么回事呢?給我都整懵逼了,經過短暫的思考,我發現了問題的真兇,那就是我們使用了N…

Vue基礎

Vue基礎 Vue應用 <!DOCTYPE html> <html> <head><meta charset"utf-8"><title></title><!-- 開發環境版本 --><script src"https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head&g…

vue所有UI庫通用)tree-select 下拉多選(設置 maxTagPlaceholder 隱藏 tag 時顯示的內容,支持鼠標懸浮展示更多

如果可以實現記得點贊分享&#xff0c;謝謝老鐵&#xff5e; 1.需求描述 引用的下拉樹形結構支持多選&#xff0c;限制選中tag的個數&#xff0c;且超過制定個數&#xff0c;鼠標懸浮展示更多已選中。 2.先看下效果圖 3.實現思路 首先根據API文檔&#xff0c;先設置maxTagC…

【Docker】Docker network之bridge、host、none、container以及自定義網絡的詳細講解

&#x1f680;歡迎來到本文&#x1f680; &#x1f349;個人簡介&#xff1a;陳童學哦&#xff0c;目前學習C/C、算法、Python、Java等方向&#xff0c;一個正在慢慢前行的普通人。 &#x1f3c0;系列專欄&#xff1a;陳童學的日記 &#x1f4a1;其他專欄&#xff1a;CSTL&…

TCP/IP網絡江湖初探:物理層的奧秘與傳承(物理層上篇-基礎與本質)

〇、引言 在這個數字時代,計算機網絡如同廣袤的江湖,數據在其中暢游,信息傳遞成為了生活的常態。然而,在這個充滿虛擬奇觀的網絡江湖中,隱藏著一個不容忽視的存在,那就是物理層,這個江湖的基石。就如同江湖中的土地一樣,物理層作為計算機網絡的基礎,承載著數據的最初轉…

STM32 CubeMX (uart_IAP串口)簡單示例

STM32 CubeMX STM32 CubeMX &#xff08;串口IAP&#xff09; STM32 CubeMXIAP有什么用&#xff1f;整體思路 一、STM32 CubeMX 設置時鐘樹UART使能UART初始化設置 二、代碼部分文件移植![在這里插入圖片描述](https://img-blog.csdnimg.cn/0c4841d8328b4169a8833f15fe3d670c.p…

PHP Smarty中的緩存如何實現?

歡迎來到PHP Smarty的緩存世界&#xff01;這里是一個簡單的指南&#xff0c;幫助你理解如何在這個強大的模板引擎中啟用和配置緩存。 首先&#xff0c;讓我們先了解一下什么是緩存。簡單來說&#xff0c;緩存就是將需要花費大量時間處理的數據或資源存儲起來&#xff0c;以便…

2023/8/16總結

這幾天完成了私信的功能點&#xff0c;用websocket做的。 這是大概的界面&#xff0c;參考的是微信 用戶可以搜索好友&#xff1a; 如果不存在是下面這樣&#xff0c;存在就會在左邊的聊天里面顯示有這個人選項 發送消息 接下來需要把推薦算法給做了

文件IO編程 1 2

頭文件包含路徑 linux 操作系統分為兩大空間&#xff1a;用戶空間和內核空間 這樣劃分&#xff0c;是為了保護內核的核心組件&#xff0c;不被輕易訪問和修改 系統調用&#xff1a;安全的訪問內核空間 其核心是&#xff1a;函數API&#xff08;API&#xff1a;用戶編程接口&…

svn文章五:問題排查與修復 - 出了問題怎么辦?SVN故障排除與修復指南

文章五&#xff1a;問題排查與修復 - “出了問題怎么辦&#xff1f;SVN故障排除與修復指南” 概述&#xff1a;在使用SVN時&#xff0c;難免會遇到一些問題和錯誤。在這篇文章中&#xff0c;我們將教您如何進行故障排查和修復&#xff0c;保護您的SVN倉庫和數據安全。 1. 引言…

K8S系列文章之 Docker安裝使用Kafka

通過Docker拉取鏡像的方式進行安裝 照例先去DockerHub找一下鏡像源&#xff0c;看下官方提供的基本操作&#xff08;大部分時候官方教程比網上的要清晰一些&#xff0c;并且大部分教程可能也是翻譯的官方的操作步驟&#xff0c;所以直接看官方的就行&#xff09; 老實說Kafka…

“深入剖析JVM內部原理:解密Java虛擬機的奧秘“

標題&#xff1a;深入剖析JVM內部原理&#xff1a;解密Java虛擬機的奧秘 摘要&#xff1a;本文將深入探討Java虛擬機&#xff08;JVM&#xff09;的內部原理&#xff0c;包括其架構、內存管理、垃圾回收機制、即時編譯器等關鍵組成部分。通過解密JVM的奧秘&#xff0c;我們將更…

【Vue3】Vue3 UI 框架 | Element Plus —— 創建并優化表單

安裝 # NPM $ npm install element-plus --save // 或者&#xff08;下載慢切換國內鏡像&#xff09; $ npm install element-plus -S// 可以選擇性安裝 less npm install less less-loader -D // 可以選擇性配置 自動聯想src目錄Element Plus 的引入和注入 main.ts import…

解決VSCode CPU高占問題的方法

如果你也遇到VSCode的CPU占用過高的問題&#xff0c;可以嘗試使用官方自帶的插件Bisect&#xff08;擴展二分查找&#xff09;功能來查找具體是哪個擴展出了問題。 找到“糟糕”的擴展可能很容易&#xff0c;也可能很困難。 打開擴展視圖 ( CtrlShiftX )&#xff0c;禁用擴展&…

網絡:雜記

1. 完成鏈路認證后&#xff0c;STA會繼續發起鏈路服務協商&#xff0c;具體的協商是通過Association報文實現。 2. RSTP可以提高收斂速度的原因&#xff1a; RSTP的拓撲變化機制 Proposal/Agreement機制 根端口快速切換機制 邊緣端口的引入

git cherry-pick

cherry-pick命令的基本用法 對于多分支的代碼庫&#xff0c;將代碼從一個分支轉移到另一個分支是常見需求。這時分兩種情況。一種情況是&#xff0c;你需要另一個分支的所有代碼變動&#xff0c;那么就采用合并&#xff08; git merge &#xff09;。另一種情況是&#xff0c;…

總結 TCP 協議的相關特性

TCP協議段格式: 如圖, 端口號: 是其中一個重要的部分,知道端口號才能確認數據交給哪個應用程序(端口號屬于傳輸層的概念). 4位首部長度:4bit表示的范圍是0->15,在此處,單位是"4字節",因此,將這里的數值 * 4&#xff0c;才是真正的報頭長度,即TCP 報頭最大長度,60…

Cenos7 搭建Minio最新版集群部署服務器(一)

------> 道 | 法 | 術 | 器 | 勢 <------ 多臺服務器間免密登錄|免密拷貝 Cenos7 搭建Minio集群部署服務器(一) Cenos7 搭建Minio集群Nginx統一訪問入口|反向動態代理(二) Spring Boot 與Minio整合實現文件上傳與下載(三) CentOS7的journalctl日志查看方法 …