Unity中Shader立方体纹理Cubemap

文章目录

  • 前言
  • 一、什么是立方体纹理
  • 二、立方体纹理的生成方式
    • 1、使用6个面的生成方式
    • 2、使用单张图片的生成方式
  • 三、Cubemap的采样方式
  • 四、在Unity中看一下Cubemap
  • 五、在Shader中,对立方体纹理进行采样使用
    • 1、我们在属性面板定义一个Cube类型的变量来存放立方体纹理
    • 2、使用前在Pass中,声明一下该变量
    • 3、在片元着色器中,对其纹理采样
    • 4、模拟真实的反射效果 (Cubemap的环境映射)
    • 5、计算视线的反射向量
  • 六、最终效果


前言

Unity中Shader立方体纹理Cubemap


一、什么是立方体纹理

立方体纹理,也被叫做Cubemap。通常用来做反射效果

在Unity中,如果全都使用实时反射,那么对于设备性能的消耗是比较大的,所以使用一种投机取巧的方式实现的反射效果

在这里插入图片描述


二、立方体纹理的生成方式

1、使用6个面的生成方式

在这里插入图片描述
在这里插入图片描述
一般选择Auto即可,会自动适配

2、使用单张图片的生成方式

在这里插入图片描述
在这里插入图片描述
一般选择Auto即可,会自动适配


三、Cubemap的采样方式

在这里插入图片描述
由模型顶点向Cubemap发射射线,射线经过的Cubemap哪个点,那个点就是采样点


四、在Unity中看一下Cubemap

在纹理的 Inspector,按如下设置,就可以把普通纹理类型修改为立方体纹理
在这里插入图片描述
请添加图片描述


五、在Shader中,对立方体纹理进行采样使用

我们使用上一篇文章的Shader继续测试:

  • Unity中Shader纹理的环绕方式

1、我们在属性面板定义一个Cube类型的变量来存放立方体纹理

_CubeMap(“CubeMap”,Cube) = “white” {}

2、使用前在Pass中,声明一下该变量

samplerCUBE _Cubemap;

3、在片元着色器中,对其纹理采样

这里进行纹理采样时,由其原理可知,需要使用顶点的本地坐标。

在这里插入图片描述

所以,这里使用 appdata 传入的顶点数据来采样即可。

  • 我们先在 v2f 中定义一个变量来存储应用程序阶段传入的数据

我们只需要顶点的 xyz 即可

float3 localPos : TEXCOORD1;

  • 然后,在顶点着色器阶段,把 appdata 的顶点 xyz 传给 v2f 中的 localPos

o.localPos = v.vertex.xyz;

  • 返回一下采样的结果看看(已经有了采样的结果)

fixed4 cubemap = texCUBE(_CubeMap,i.localPos);
return cubemap;

在这里插入图片描述

4、模拟真实的反射效果 (Cubemap的环境映射)

要模拟出真实的反射效果,不能向之前一样,采样眼睛处的Cubemap

而是需要采样视线的反射视线经过Cubemap的点

在这里插入图片描述

5、计算视线的反射向量

因为需要计算视线的反射向量,所以需要准备一些数据:

摄像机的世界坐标、模型顶点的世界坐标、法线的世界坐标

  • 准备摄像机的世界坐标

_WorldSpaceCameraPos

  • 准备模型顶点的世界坐标

1、在 v2f 中,定义一个变量存储顶点的世界信息
float3 worldPos : TEXCOORD2;
2、在顶点着色器中,进行顶点坐标转化
o.worldPos = mul(unity_ObjectToWorld,v.vertex);

  • 准备法线的世界坐标

1、在 appdata 中传入法线信息
half3 normal : NORMAL;
2、在 v2f 中,定义一个变量存储法线世界坐标
half3 worldNormal : NORMAL;
3、在顶点着色器中,进行法线坐标转化
o.worldNormal = UnityObjectToWorldNormal(v.normal);

  • 准备最后的计算

1、计算世界坐标下 视线单位向量 V
fixed3 V = normalize(i.worldPos - _WorldSpaceCameraPos);
2、计算世界坐标下 法线单位向量 N
fixed3 N = normalize(i.worldNormal);
3、计算世界坐标下 反射向量R
fixed3 R = reflect(V,N);
4、用 R 对Cubemap进行纹理采样
fixed4 cubemap = texCUBE(_CubeMap,R);


六、最终效果

请添加图片描述

最终代码:

//纹理的多级渐远 Mipmap
//纹理的环绕方式
Shader "MyShader/P2_1_5"
{Properties{_MainTex ("Texture", 2D) = "white" {}[KeywordEnum (Repeat,Clamp)]_WrapMode("WrapMode",int) = 0[IntRange]_Mipmap ("Mipmap",Range(0,10)) = 0//在属性面板定义立方体纹理_CubeMap("CubeMap",Cube) = "white" {}}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma shader_feature _WRAPMODE_REPEAT _WRAPMODE_CLAMP#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;half3 normal : NORMAL;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;float3 localPos : TEXCOORD1;float3 worldPos : TEXCOORD2;half3 worldNormal : NORMAL;};sampler2D _MainTex;float4 _MainTex_ST;half _Mipmap;samplerCUBE _CubeMap;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.localPos = v.vertex.xyz;o.worldPos = mul(unity_ObjectToWorld,v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);return o;}fixed4 frag (v2f i) : SV_Target{//WrapMode#if _WRAPMODE_REPEATi.uv = frac(i.uv);#elif _WRAPMODE_CLAMP//法一://i.uv = clamp(i.uv,0,1);//法二:i.uv = saturate(i.uv);#endiffloat4 uvMipmap = fixed4(i.uv,0,_Mipmap);fixed4 col = tex2Dlod(_MainTex, uvMipmap);//Cubefixed4 cubemap = texCUBE(_CubeMap,i.localPos);//V,N,Rfixed3 V = normalize(i.worldPos - _WorldSpaceCameraPos);fixed3 N = normalize(i.worldNormal);fixed3 R = reflect(V,N);cubemap = texCUBE(_CubeMap,R);return cubemap;return col;}ENDCG}}
}

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

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

相关文章

TCP中发送数据的情况

发送窗口和接收窗口的本质,可以叫做“TCP 的生产者 - 消费者”模型,这个只是单个网络连接的数据传输。发送窗口相当于生产者,接收窗口相当于消费者。TCP必须考虑多个连接共享在有限的带宽上,兼顾效率和公平性的控制,而…

WPF Visual, UIElement, FrameworkElement, Control这些类的区别

在WPF (Windows Presentation Foundation) 中,Visual, UIElement, FrameworkElement, 和 Control 这些类是一个类层次结构,它们分别在 WPF 的 UI 元素和控件模型中提供了不同级别的功能。下面是这些类的详细介绍: Visual:这是所有…

GetKeyState获取键盘状态(原神水龙王转转转)

先上代码&#xff1a; #include<iostream> #include<Windows.h> int main(){std::cout << "按住鼠标侧键开始旋转&#xff0c;记得要以管理员身份运行&#xff01;\n";while(true){if(GetKeyState(VK_XBUTTON1) < 0){std::cout << "…

Linux三剑客:awk的实用案例

目录 实战案例 1、awk插入几个新字段 2、awk格式化空白 3、awk筛选IPv4地址 4、awk读取.ini配置文件中的某段 5 、使用awk根据某字段去重 6、awk次数统计 7、awk统计TCP连接状态数量 8、awk统计日志中各IP访问非200状态码的次数 9、awk统计独立IP 10、awk处理字段缺…

Redis学习笔记17:基于spring data redis及lua脚本批处理scan指令查询永久有效的key

Redis的KEYS和SCAN指令都可以用于在数据库中搜索匹配指定模式的键。然而&#xff0c;它们之间有一些关键的区别&#xff1b; KEYS指令会在整个数据库中阻塞地执行匹配操作&#xff0c;并返回匹配的键列表。如果数据库很大&#xff0c;或者匹配的键很多&#xff0c;将会对性能产…

LeetCode【4】寻找两个正序数组中位数

题目&#xff1a; 思路&#xff1a; https://blog.csdn.net/a1111116/article/details/115033098 代码&#xff1a; public double findMedianSortedArrays(int[] nums1, int[] nums2) {int[] ints Arrays.copyOf(nums1, nums1.length nums2.length);System.arraycopy(nums2…

Python学习笔记--Python关键字yield

原文:http://stackoverflow.com/questions/231767/the-python-yield-keyword-explained 注:这是一篇 stackoverflow 上一个火爆帖子的译文 问题 Python 关键字 yield 的作用是什么?用来干什么的? 比如,我正在试图理解下面的代码: def node._get_child_candidates(self,…

【Unity】XML文件的解析和生成

目录 使用XPath路径语法解析 使用xml语法解析 XML文件的生成 XML文件是一种常用的数据交换格式&#xff0c;它以文本形式存储数据&#xff0c;并使用标签来描述数据。解析和生成XML文件是软件开发中常见的任务。 解析XML文件是指从XML文件中读取数据的过程。在.NET中&#…

10. Spring源码篇之BeanPostProcessor

简介 在Bean的创建过程中会有很多的后置处理器&#xff0c;例如实例化前、实例化后、初始化前、初始化后&#xff0c;属性填充等&#xff0c;这些都是通过BeanPostProcessor来实现的 那么既然每个Bean都有有这些生命周期&#xff0c;这些BeanPostProcessor肯定需要提前知道&a…

ClickHouse 语法优化规则

ClickHouse 的 SQL 优化规则是基于RBO(Rule Based Optimization)&#xff0c;下面是一些优化规则 1 准备测试用表 1&#xff09;上传官方的数据集 将visits_v1.tar和hits_v1.tar上传到虚拟机&#xff0c;解压到clickhouse数据路径下 // 解压到clickhouse数据路径 sudo tar -xvf…

图数据库Neo4J 中文分词查询及全文检索(建立全文索引)

Neo4j的全文索引是基于Lucene实现的&#xff0c;但是Lucene默认情况下只提供了基于英文的分词器&#xff0c;下篇文章我们在讨论中文分词器&#xff08;IK&#xff09;的引用&#xff0c;本篇默认基于英文分词来做。我们前边文章就举例说明过&#xff0c;比如我要搜索苹果公司&…

基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖(五)

公共字段自动填充 1.1 问题分析1.2 实现思路1.3 代码开发1.3.1 步骤一1.3.2 步骤二1.3.3 步骤三 1.4 功能测试 1.1 问题分析 在前面我们已经完成了后台系统的员工管理功能和菜品分类功能的开发&#xff0c;在新增员工或者新增菜品分类时需要设置创建时间、创建人、修改时间、修…

【JavaScript】fetch 处理流式数据,实现类 chatgpt 对话

本文只包含最基础的请求后端大佬给得对话接口&#xff0c;大部分模型的传参是差不多的&#xff0c;核心还是如何处理 fetch 获取的流数据 import { defineStore } from pinia; import { ElMessage } from element-plus;type Role system | user | assistant; export interfac…

社区分享|杭银消费金融基于MeterSphere开展接口自动化测试

杭银消费金融有限公司&#xff08;以下简称“杭银消费金融”&#xff09;成立于2015年12月&#xff0c;是经中国银保监会批准&#xff0c;由杭州银行作为主发起人&#xff0c;联合滴滴出行、中国银泰等企业组建的持牌消费金融机构&#xff0c;注册资本为25.61亿元。杭银消费金融…

Python武器库开发-flask篇之Get与Post(二十五)

flask篇之Get与Post(二十五) 在Flask中通过request对象请求相关的数据,在正常的网页请求的过程中&#xff0c;有两种请求的方式&#xff0c;Get和Post Get请求 我们现在来看看在Flask中是如何以Get方式得到我们想要的值的&#xff0c;通过request.args可以获取Get请求中的所…

深入理解网络协议:通信世界的基石

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 在当今数字化时代&#xff0c;网络协议是连接世…

openGauss通过VIP实现的故障转移

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

机器学习笔记 - Ocr识别中的文本检测EAST网络概述

一、文本检测 文本检测简单来说就是找到图像中可以出现文本的区域。例如,请参见下图,其中在检测到的文本周围绘制了绿色边框。 在进行文本检测时,你可能会遇到两种情况 具有结构化文本的图像:这是指具有干净/均匀背景和常规字体的图像。文本大多密集,行结构正确,…

php连接sqlserver 安装sqlserver 驱动windows系统

第一步下载Windows 上的 Microsoft ODBC Driver for SQL Server ODBC 驱动程序 Microsoft ODBC Driver for SQL Server 直接下载安装即可&#xff0c;安装后可查看安装版本 第二步&#xff1a;下载php_sqlsrv 驱动 安装解压后&#xff0c;会有对应php版本的驱动文件&#xf…

Python hashlib 模块详细教程:安全哈希与数据完整性保护

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python hashlib 模块详细教程&#xff0c;文章6500字&#xff0c;阅读大约17分钟&#xff0c;大家enjoy~~ hashlib模块为Python提供了一种简便的方式来使用各种哈希算法&…