【Unity Shader入门精要 第7章】基础纹理(一)
1. 纹理映射
每一张纹理可以看作拥有一个属于自己的2D坐标空间,其横轴用U表示,纵轴用V表示,因此也称为UV坐标空间。
UV空间的坐标范围为[0,0]到[1,1],在Unity中,UV空间也是从左下到右上,即纹理的左下角对应的UV坐标为[0,0],纹理右上角对应的UV坐标为[1,1]
在美术导出模型资源时,会通过UV展开将模型每个顶点对应的UV坐标存储到顶点信息中。渲染时通过顶点(或片元)的UV坐标映射到纹理上的某一点,这样就可以通过采样每一个顶点(或片元)对应的纹理上的颜色将纹理显示出来。
2. 纹理基础设置
以Unity 2021为例,一张纹理的Inspector面板大致如下
其中红框部分是本节主要关注的部分
-
Generate Mip Maps
- 勾选后会提前进行滤波,生成不同采样等级的Mip Map纹理
- 渲染时根据屏幕像素对应的纹理范围从对应等级的Mip Map纹理中进行采样
- 由于生成了新的纹理,因此会占用更多的内存空间
-
Wrap Mode
UV坐标空间自身的范围虽然只有0到1,但实际采样时,顶点映射的UV坐标可能超过这个范围,WrapMode属性决定了采样的UV坐标超过[0, 1]范围时的处理方式- Repeat:重复采样,即超过范围时舍弃整数部分只按小数部分采样,比如(1.1, 1.2)实际会按照(0.1, 0.2)采样
- Clamp:超过[0, 1]的部分延用相应边缘的值(0或者1)
-
Filter Mode
决定纹理采样的滤波方式- Point:就近点采样
- Bilinear:双线性插值
- Trilinear:三线性插值
关于MipMap和滤波的原理可以参照【Unity Shader入门精要 第7章】基础纹理补充内容:MipMap原理
3. 在Shader中使用纹理
- 创建Chapter_7_BaseTexture_Mat 作为测试材质
- 创建Chapter_7_BaseTexture作为测试shader,并赋给Chapter_7_BaseTexture_Mat 材质
- 场景中创建胶囊体,将Chapter_7_BaseTexture_Mat 材质赋给胶囊体
- 场景中添加一盏平行光,并调整平行光角度
在Shader中,我们通过对纹理采样得到的颜色来代替之前固定的漫反射颜色,并在片元着色器中进行逐像素的光照计算,得到最终的效果:
- 在Properties中添加属性 _MainTex(“MainTex”, 2D) = “white”{} 用于设置纹理,此时选中胶囊体可在Inspector面板中看到如下纹理设置选项
- Tiling:平铺数量,可以理解为反向的缩放度,值越大单位空间平铺数量越多,相当于对纹理缩小,反之相当与放大
- Offset:偏移
- 在CG代码段中添加与属性同名的变量 _MainTex来使用面板中设置的纹理,其类型为 sampler2D
- 顶点着色器中输入的uv坐标是模型导出时顶点对应的uv坐标,为了能够得到正确的纹理采样结果,除了考虑顶点自身的uv坐标外,还需要考虑面板中对要采样的纹理设置的缩放和偏移,这部分信息可通过在Shader中声明 XXX_ST 的变量获得,其中XXX为纹理属性的名字,当前Shader中也就是 _MainTex_ST,该变量类型为float4,其中xy表示缩放,zw表示平移
- 通过 input.uv.xy * _MainTex_ST.xy + _MainTex_ST.zw 即可得到实际采样使用的uv坐标,也可以通过内置的TRANSFORM_TEX(_MainTex, input.uv)方法获得,此时引擎会自己使用名为 _MainTex_ST 的变量进行上述计算,因此即使使用内置方法计算uv也需要声明_ST变量
- 最后在着色器中通过 tex2D(_MainTex, i.uv) 方法即可对纹理进行采样获得颜色,我们以该颜色作为物体自身的漫反射颜色系数带入漫反射光照计算
Shader如下:
Shader "MyShader/Chapter_7/Chapter_7_BaseTexture"
{Properties{_MainTex("MainTex", 2D) = "white"{}_Specular("Specular", Color) = (1,1,1,1)_Gloss("Gloss", Range(1.0, 256.0)) = 10}SubShader{Pass{Tags {"LightMode" = "ForwardBase"}CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"struct a2v{float4 vertex : POSITION;float3 normal : NORMAL;float2 uv : TEXCOORD0;};struct v2f{float4 vertex : SV_POSITION;float2 uv : TEXCOORD0;float3 worldPos : TEXCOORD1;float3 worldNormal : TEXCOORD2;};sampler2D _MainTex;float4 _MainTex_ST;fixed4 _Specular;half _Gloss;v2f vert(a2v i){v2f o;o.vertex = UnityObjectToClipPos(i.vertex);o.worldPos = mul(unity_ObjectToWorld, i.vertex);o.worldNormal = mul(i.normal, (float3x3)unity_WorldToObject);o.uv = TRANSFORM_TEX(i.uv, _MainTex);return o;}fixed4 frag(v2f i) : SV_Target{fixed3 _ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;float3 _worldNormal = normalize(i.worldNormal);float3 _worldLight = normalize(_WorldSpaceLightPos0.xyz);fixed4 _albedo = tex2D(_MainTex, i.uv);fixed3 _diffuse = _LightColor0.rgb * _albedo.rgb * saturate(dot(_worldNormal, _worldLight));float3 _worldRefl = normalize(reflect(-_worldLight, _worldNormal));float3 _worldView = normalize(_WorldSpaceCameraPos.xyz - i.worldPos);fixed3 _specular = _LightColor0.rgb * _Specular.xyz * pow( saturate(dot(_worldRefl, _worldView)),_Gloss);return fixed4(_ambient + _diffuse + _specular, 1);}ENDCG}}}
效果如下:
相关文章:

【Unity Shader入门精要 第7章】基础纹理(一)
1. 纹理映射 每一张纹理可以看作拥有一个属于自己的2D坐标空间,其横轴用U表示,纵轴用V表示,因此也称为UV坐标空间。 UV空间的坐标范围为[0,0]到[1,1],在Unity中,UV空间也是从左下到右上&#…...

el-checkbox选中后的值为id,组件显示为label中文
直接上代码 方法一 <el-checkbox v-for"item in list" :key"item.id" :label"item.id">{{中文}} </el-checkbox> 方法二 <el-checkbox-group class"flex_check" v-model"rkStatusList" v-for"item…...

03-数据结构(一)
链接:C# 数据结构_哔哩哔哩_bilibili https://www.bilibili.com/video/BV1a541147Nk/?spm_id_from333.337.search-card.all.click&vd_source6eb7d966aa03ff5cb02b63725f651e68 链接:使用 C#.Net 学习掌握数据结构 (更新中)_哔哩哔哩_bilibili 一…...
MySQL问题记录-主机被锁问题
主机被锁问题 描述:"Host ‘113.109.111.217’ is blocked because of many connection errors 原因:同一个ip在短时间内产生太多中断的数据库连接而导致的阻塞; 超过mysql数据库max_connection_errors的最大值; 解决方法…...

用好 explain 妈妈再也不用担心我的 SQL 慢了
大家好,我是聪,一个乐于分享的小小程序员。在不久之前我写了一个慢 SQL 分析工具,可以用来分析 Java Mybatis 项目的 SQL 执行情况,其中刚好涉及到了 explain 的使用。感兴趣的可以了解一下。 Github 地址⭐:https://…...

【漏洞复现】泛微OA E-Cology SignatureDownLoad SQL注入漏洞
漏洞描述: 泛微OA E-Cology是一款面向中大型组织的数字化办公产品,它基于全新的设计理念和管理思想,旨在为中大型组织创建一个全新的高效协同办公环境。泛微OA E-Cology SignatureDownLoad存在SQL注入漏洞,允许攻击者非法访问和操…...

前端工程化,前端监控,工作流,部署,性能
开发规范 创建项目的时候,配置下 ESlint,stylelint, prettier, commitlint 等; ESLint 主要功能: ESLint 是一个静态代码检查工具,用于在 JavaScript 代码中识别和报告模式。它的目标是提供一个插件化的 …...
浅析Java贪心算法
浅析Java贪心算法 在计算机科学中,贪心算法(Greedy Algorithm)是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法。贪心算法并不总是能够得到全…...

vue3.0(五) reactive全家桶
文章目录 1 reactive1.1 reactive的应用1.2 reactive的特点1.3 reactive的注意1.4 reactive的局限性 2 toRefs3 isReactive4 shallowReactive5 readonly5.1 readonly 详细信息5.2 readonly函数创建一个只读的响应式对象5.3 如何修改嵌套在只读响应式对象中的对象? 6 isReadonl…...

Selenium 自动化 —— 四种等待(wait)机制
更多关于Selenium的知识请访问CSND论坛“兰亭序咖啡”的专栏:专栏《Selenium 从入门到精通》 目录 目录 需要等待的场景 自己实现等待逻辑 Selenium 提供的三种等待机制 隐式等待(Implicit Waits) 隐式等待的优点 隐式等待的缺点 …...

每日两题 / 437. 路径总和 III 105. 从前序与中序遍历序列构造二叉树(LeetCode热题100)
437. 路径总和 III - 力扣(LeetCode) 前序遍历时,维护当前路径(根节点开始)的路径和,同时记录路径上每个节点的路径和 假设当前路径和为cur,那么ans 路径和(cur - target)的出现次数 /*** D…...

matlab使用2-基础绘图
matlab使用2-基础绘图 文章目录 matlab使用2-基础绘图1. 二维平面绘图2. 三维立体绘图3. 图形窗口的分割 1. 二维平面绘图 % 创建一些二维数据 x 0:0.01:10; % x轴的数据点,从0到10,间隔为0.01 y sin(x); % y轴的数据点,是x的正弦…...
嵌入式开发四大平台介绍
MCU(Micro Control Unit)四大平台介绍) 单片机优点:缺点:总结: DSP digital signal processingARM优点:缺点:总结 FPGA什么事FPGA(集成元件库)FPGA开发方法—…...

《Python编程从入门到实践》day28
# 昨日知识点回顾 安装Matplotlib 绘制简单的折线图 # 今日知识点学习 15.2.1 修改标签文字和线条粗细 # module backend_interagg has no attribute FigureCanvas. Did you mean: FigureCanvasAgg? # 解决办法:matplotlib切换图形界面显示终端TkAgg。 #…...

STC8增强型单片机开发【定时器Timer⭐】
目录 一、引言 二、定时器基础知识 三、STC8定时器配置 四、代码示例 五、总结 一、引言 在单片机开发中,定时器(Timer)是一个极其重要的组件,它允许开发者基于时间触发各种事件或任务。STC8增强型单片机作为一款功能丰富的…...

C语言实训项目源码-02餐厅饭卡管理系统-C语言实训C语言大作业小项目
C语言餐厅饭卡管理系统 一、主要功能 主要功能模块 页面名称 实现功能 负责人 进入页面 进入程序 主函数 系统主要功能 修改密码函数 修改密码 充值,显示函数 饭卡充值与信息显示 购买饭菜…...

Linux第四节--常见的指令介绍集合(持续更新中)
点赞关注不迷路!本节涉及初识Linux第四节,主要为常见的几条指令介绍。 如果文章对你有帮助的话 欢迎 评论💬 点赞👍🏻 收藏 ✨ 加关注👀 期待与你共同进步! 1. more指令 语法:more [选项][文件]…...

Apache Sqoop:高效数据传输工具搭建与使用教程
目录 引言一、环境准备二、安装sqoop下载sqoop包解压文件 三、配置Sqoop下载mysql驱动拷贝hive的归档文件配置环境变量修改sqoop-env.sh配置文件替换版本的commons-lang的jar包 验证Sqoop安装查看Sqoop版本测试Sqoop连接MySQL数据库是否成功查看数据库查看数据表去除警告信息 四…...

【C++初阶】第十一站:list的介绍及使用
目录 list的介绍及使用 1.list的含义 2.list的介绍 3.list的使用 1.list的构造 2.list iterator的使用 3.list capacity 4.list element access 5 list modifiers 尾插尾删 和 头插头删 insert 和 erase resize swap clear 6.list sort and reverse 7.list copy vector copy li…...

【devops】Linux 日常磁盘清理 ubuntu 清理大文件 docker 镜像清理
日常磁盘清理 1、查找大文件 find / -type f -size 1G2、清理docker无用镜像(drone产生的残余镜像文件) docker system prune -a一、清理服务器磁盘 1、查找大文件 在Ubuntu系统中,你可以使用find命令来查找大文件。find命令是一个强大的…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...
多元隐函数 偏导公式
我们来推导隐函数 z z ( x , y ) z z(x, y) zz(x,y) 的偏导公式,给定一个隐函数关系: F ( x , y , z ( x , y ) ) 0 F(x, y, z(x, y)) 0 F(x,y,z(x,y))0 🧠 目标: 求 ∂ z ∂ x \frac{\partial z}{\partial x} ∂x∂z、 …...