IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity学习shader笔记[三十八]CubeMap -> 正文阅读

[游戏开发]Unity学习shader笔记[三十八]CubeMap

CubeMap生成原理

我们不管是在某个点用工或者用反射探针reflectionProbe生成CubeMap,
原理上都是以透视视角的方式,下面以RP生成CubeMap为例来说
从点的位置以点到物体的每个顶点的连线为方向投影映射到物体应该对应的长方体贴图的面上,
可能投影到三个面或者两个面或者四五个面,取决于物体到点的距离和物体在六个投影面中的位置和物体大小。

如下图中,RP周围的物体无论是在黄色长方体里面还是外面都会映射到对应的面上
在这里插入图片描述

这个长方体可以包括或者不包括需要映射的物体,取决于想要的效果。

CubeMap不适合做反射情况

与Cubemap生成点不同位置并且要反射的物体有一定体积的反射

我们实际上可能会CubeMap做地面的反射

用CubeMap做地面反射时
如果反射面的边缘与实际的黄色矩形的面有一定的距离
单个CubeMap不能完整将远近所有的映射都完整的怼齐到真实的物体
根据原理
有一定体积的物体或者比较靠近反射探针的物体映射过去都是有面积的偏差的。
虽然靠近对应的投影面但有一定体积的物体或者比较靠近反射探针的物体映射过去会产生比较大的CubeMap占比面积。

这时如果我们观察反射的位置不和反射探针一致
通过地面来对这部分进行采样做反射就会产生不太正确的效果了

如下图所示靠近反射探针的物体被映射到了A点的面,然后地面进行反射时采样A点得到了错误的结果。
在这里插入图片描述
但是图中A的反射如果是在RP点去观察反射,结果将会是正确的。

CubeMap适合做反射情况

观察点与RP相同

根据原理,不论是物体多大在什么位置和旋转,在RP点去观察反射一定是对的

观察点任意,但所有反射五都面类型并且很贴齐到反射矩形的物体

如果环境中应该映射到某个面的物体都很贴齐到那个面
并且他们和反射探针之间没有其他 物体阻挡,并且要反射的地面恰好和反射探针的底面基本重合,
则映射的结果会比较正确。

如下图所示,这里的黄色框的四个面刚好保卫的地面的四个边缘
请添加图片描述
这里的窗户也是对的齐的
下图中的四面墙中墙壁上的窗子和墙壁,他们都很贴近CubeMap那个面,他们和反射探针之间也没有其他的遮挡物。
在这里插入图片描述

CubeMap Shader代码

Shader "JiZhan/GlassPureCubeMap"
{
    Properties
    {
        _MatcapTex("高光贴图", Cube) = ""{}
        _boxCenter ("天空盒中心", vector) = (0,0,0,0) 
		_boxSize ("天空盒长宽高", vector) = (0,0,0,0) 
        _alpha("透明度", float) =  0.5
        
        
        
    }
    SubShader
    {
        Tags { 
            "RenderType"="Opaque"
            "Queue" = "Transparent"
             }
        LOD 100

        
        Pass
        {
            
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            
            samplerCUBE _MatcapTex;
            float4 _MatcapTex_ST;

            float _alpha;
            float4 _boxCenter;
	        float4 _boxSize;
            
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float3 reflectionDir : TEXCOORD3;
                float3 pos_WS : TEXCOORD4;
                float4 vertex : SV_POSITION;
            };
        

            

            fixed4 GetCubeMapColor(v2f input)
            {
                 
                float4 boxMin = _boxCenter - _boxSize * 0.5;
                    float4 boxMax = _boxCenter + _boxSize * 0.5;

                   _boxCenter.w = 1;
                float3 reflectDir =
                    BoxProjectedCubemapDirection(normalize(input.reflectionDir), input.pos_WS,
                                                             _boxCenter, boxMin,
                                                             boxMax);

                
                 
                fixed4 cubeMapColor = texCUBE(_MatcapTex, reflectDir);
                
                return cubeMapColor;
            }

             float3 GetRelfectionDir(appdata v)
            {
                float3 worldNormal = UnityObjectToWorldNormal(v.normal);
                float3 worldViewDir = WorldSpaceViewDir(v.vertex);
                float3 reflectionDir = reflect(-worldViewDir, worldNormal);
                return reflectionDir;
            }
            
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.reflectionDir = GetRelfectionDir(v);
                o.pos_WS = mul(unity_ObjectToWorld, v.vertex);
                 
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 cubeMapColor = GetCubeMapColor(i);
                
                cubeMapColor.a = _alpha * cubeMapColor.r;
                
                return cubeMapColor;
            }
            ENDCG
        }
    }
}

使用注意事项

  • 可以使用反射探针Bake生成的图作为Shader中的Cubemap 反射探针生成的图的后缀是.exr
    一些工具调用UnityAPI生成的图的后缀可能不同 但实际上好像都是Cubemap

  • 最好用ReflectionProbe渲染的CubeMap,这样用上述代码读取CubeMap纹理时,
    ReflectionProbe也对应开启BoxProjection选项,读取出来的CubeMap在映射时才容易与场景对称。

  • 根据原理 如果要做反射 注意ReflectionProbe的BoxSize调成四个面与反射面的边缘衔接

  • 只有标记为”ReflectionProbe Static”的对象才会被反射探头取样 从属性接口上静态对象(Static)的下拉选单打勾即可

  • 调节ReflectionProbe的范围注意这两个地方要打开并且同时要选中反射探针

在这里插入图片描述

  • 临时为了判断调节RP的尺寸和位置是否正确将使用CubeMap的反射,可以用Standard材质作为平面的材质然后勾选Reflections同时将Smoothness调节到最大。
  • 在有两个RP的情况下,RP之间重合的区域,内置管线中是通过这两个RP的importance进行调节过渡的,类似于A的颜色乘以A的IMPORTANCE/总IMPORTANCE+B的颜色乘以B的IMPORTANCE/总IMPORTANCE。但是在URP中,重合区域直接显示IMPORTANCE大的RP的颜色,并且URP没有BoxProjectionCubeMapDirection这个函数了,Cubemap好像被Unity抛弃了。
  • 在Unity 2019.3.8f1中, 使用BoxProjectedCubemapDirection时,如果是这样写
BoxProjectedCubemapDirection(normalize(input.reflectionDir), input.pos_WS,
                                                                 unity_SpecCube0_ProbePosition,
                                                                 unity_SpecCube0_BoxMin,
                                                                 unity_SpecCube0_BoxMax);

那么BoxProjectedCubemapDirection函数里面的最外围的判断

if (cubemapCenter.w > 0.0)

会根据实际的情况去走正确或者错误的判断

但是如果后面传的三个参数是自定义的参数,如下面这样写

float4 boxMin = _BoxCenter - _BoxSize * 0.5;
                    float4 boxMax = _BoxCenter + _BoxSize * 0.5;
                   
                    float3 reflectDir =
                        BoxProjectionCubeMap(normalize(input.reflectionDir), input.pos_WS,
                                                                 _BoxCenter, boxMin,
                                                                 boxMax);

                    fixed4 cubeMapColor = texCUBE(_CubeTex, reflectDir);

那么要自己注意传入的第三个参数的w分量是0还是1,

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-08-03 11:32:18  更:2021-08-03 11:33:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 23:15:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码