Unity3d Shader篇(七)— 纹理采样

文章目录

  • 前言
  • 一、什么是纹理采样?
    • 1. 纹理采样的工作原理
    • 2. 纹理采样的优缺点
      • 优点
      • 缺点
  • 二、使用步骤
    • 1. Shader 属性定义
    • 2. SubShader 设置
    • 3. 渲染 Pass
    • 4. 定义结构体和顶点着色器函数
    • 5. 片元着色器函数
  • 三、效果
  • 四、总结
    • 使用场景


前言

纹理采样是一种常用的图形学技术,它可以让我们在渲染物体表面时,使用一张图片来提供颜色信息,从而增强物体的细节和真实感。在本文中,我们将介绍纹理采样的基本概念,原理和实现方法,以及在 Unity Shader 中如何使用纹理采样来实现一个简单的高光反射着色器。


一、什么是纹理采样?

1. 纹理采样的工作原理

纹理采样,就是通过 uv 获取贴图对应位置的颜色。uv 是一种二维坐标系,它的取值范围是 [0,1],表示了贴图上的相对位置。例如,uv 值是 (0.5,0.5),此时采样到的就是贴图中心点的颜色值。

在 Unity Shader 中,我们可以使用 tex2D 函数来进行纹理采样,它的参数有两个,一个是纹理对象,一个是 uv 坐标,它的返回值是一个 fixed4 类型的颜色值,表示了纹理上的纹素(texel)的颜色。例如:

fixed4 col = tex2D (_MainTex, i.uv);

这段代码表示,从 _MainTex 这个纹理对象中,采样 i.uv 这个坐标处的颜色,赋值给 col 变量。

2. 纹理采样的优缺点

优点

可以大大提高物体表面的细节和真实感,使物体看起来更加美观和逼真。
可以减少顶点数据的传输和处理,提高渲染效率和性能。
可以灵活地调整和修改物体表面的颜色和效果,不需要重新编译着色器或者修改代码。

缺点

需要占用额外的内存空间和带宽,增加资源的加载和管理的开销。
需要考虑纹理的分辨率和质量,以及纹理坐标的映射和过滤,避免出现失真和锯齿的现象。
需要考虑纹理的环绕和过滤模式,以及纹理的压缩和优化,以适应不同的渲染需求和设备。

二、使用步骤

1. Shader 属性定义

// 定义属性
Properties
{
   _MainTex("MainTex",2D)="white"{}
   _Diffuse("Diffuse",Color)=(1,1,1,1) // 漫反射颜色属性,默认白色
   _Specular("Specular",Color)=(1,1,1,1) // 高光颜色属性,默认白色
   _Gloss("Gloss",Range(1,256))=5 // 高光反射系数
}

这段代码定义了Shader的属性,其中:
_MainTex: 表示图片属性,它的默认值是白色,表示如果没有指定贴图,就使用白色填充。
_Diffuse: 表示漫反射颜色属性,使用RGBA格式表示颜色,默认为白色 (1, 1, 1, 1)。
_Specular: 表示高光颜色属性,同样使用RGBA格式表示颜色,默认为白色 (1, 1, 1, 1)。
_Gloss: 表示高光反射系数属性,使用Range声明范围为1到256,默认值为5。

2. SubShader 设置

SubShader
{
    Tags
    {
        "RenderType" = "Opaque" // 渲染类型为不透明
    }
    
    LOD 100 // 细节级别
}

SubShader 定义了一组渲染设置,包括标签和细节级别。在这里,我们将渲染类型标签设置为 “Opaque”,表示物体是不透明的。

3. 渲染 Pass

Pass
{
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag

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

这里开始了渲染 Pass 部分。在这里,我们使用了 CGPROGRAM 指令来声明顶点着色器和片元着色器函数。#pragma vertex vert 和 #pragma fragment frag 分别指定了顶点着色器函数和片元着色器函数的名称。

然后,我们包含了 UnityCG.cginc 和 Lighting.cginc,它们提供了许多有用的函数和宏,用于简化编写 Shader。

4. 定义结构体和顶点着色器函数

// 定义结构体:从顶点到片元的数据传递
struct v2f
{
    float4 vertex:SV_POSITION; // 顶点位置
    fixed3 worldNormal:TEXCOORD0; // 世界空间法线
    fixed3 worldPos:TEXCOORD1;// 世界空间位置
    float2 uv:TEXCOORD2;
};

// 顶点着色器函数
v2f vert(appdata_base v)
{
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex); // 顶点位置变换到裁剪空间
    fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); // 世界空间法线
    o.worldNormal = worldNormal;

    //让外面的属性可以影响到uv
    //o.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
    //uv计算简化函数
    o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
    o.worldPos=mul(unity_ObjectToWorld,v.vertex);
    return o;
}

顶点着色器的输入是一个结构体 appdata_base ,它包含了顶点的位置和法线信息等。顶点着色器的输出是一个结构体 v2f ,它包含了顶点的裁剪空间位置和世界空间法线和位置信息等。

顶点着色器的主要逻辑是:

  1. 使用 UnityObjectToClipPos 函数,将顶点的位置从对象空间变换到裁剪空间,这是渲染管线的必要步骤。

  2. 使用 UnityObjectToWorldNormal 函数,将顶点的法线从对象空间变换到世界空间,这是为了计算光照效果所需的方向向量。

  3. 使用 TRANSFORM_TEX 函数,将顶点的贴图坐标根据 _MainTex_ST 的值进行缩放和偏移,这是为了让贴图的属性可以影响到贴图的显示。

  4. 使用 unity_ObjectToWorld 矩阵,将顶点的位置从对象空间变换到世界空间,这是为了计算光照效果所需的坐标系。

5. 片元着色器函数

// 片元着色器函数
fixed4 frag(v2f i) : SV_Target
{
    //获取环境光
    fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

    //纹理采样
    fixed3 albedo = tex2D(_MainTex, i.uv).rgb;

    //漫反射
    fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
    fixed3 diffuse = _LightColor0.rgb * albedo * _Diffuse.rgb * max(0, dot(worldLightDir, i.worldNormal) * 0.5 + 0.5);

    // 高光反射
    // 计算视角方向
    fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
    // 计算半向量
    fixed3 halfDir = normalize(worldLightDir + viewDir);
    // 计算高光颜色   
    fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(i.worldNormal, halfDir)), _Gloss);

    // 组合最终颜色
    fixed3 color = diffuse + ambient + specular;
    return fixed4(color, 1); // 输出颜色
}


片元着色器的输入是一个结构体 v2f ,它包含了顶点的裁剪空间位置和世界空间法线和位置信息。片元着色器的输出是一个 fixed4 类型的颜色值,它表示了片元的颜色。

片元着色器的主要逻辑是:

  1. 使用 UNITY_LIGHTMODEL_AMBIENT 宏,获取环境光的颜色,这是 Phong 光照模型的第一个分量。

  2. 使用 tex2D 函数,对 _MainTex 进行纹理采样,根据 i 的 uv 值获取对应的像素颜色,它是物体的表面颜色。

  3. 使用 UnityWorldSpaceLightDir 函数,获取光源的方向向量,这是为了计算漫反射和高光效果所需的角度。

  4. 使用 _LightColor0 和 _Diffuse 变量,获取光源的颜色和物体的漫反射颜色,然后使用 max 和 dot 函数,计算光源和法线的夹角的余弦值,然后乘以 0.5 并加上 0.5,这是为了将 [-1, 1] 的范围映射到 [0, 1] 的范围,这是 Phong 光照模型的第二个分量

  5. 使用 UnityWorldSpaceViewDir 函数,根据 i 的 worldPos 值获取视线的方向向量,这是为了计算高光效果所需的角度。

  6. 使用 normalize 函数,计算视线方向和光源方向的半向量,这是为了简化高光效果的计算。

  7. 使用 _LightColor0 和 _Specular 变量,获取光源的颜色和物体的高光颜色,然后使用 max 和 dot 函数,计算法线和半向量的夹角的余弦值,然后使用 pow 函数,根据 _Gloss 的值计算高光的强度,这是 Phong 光照模型的第三个分量。

  8. 将环境光、漫反射和高光的颜色相加,得到最终的光照颜色,作为片元着色器的输出。

三、效果

在这里插入图片描述

四、总结

纹理采样是从一张纹理图片中获取颜色值的过程,它需要指定一个纹理坐标(uv)和一个采样器(sampler)。采样器定义了纹理的过滤方式(filter)和寻址模式(wrap)。过滤方式决定了当纹理坐标不是整数时,如何插值得到颜色值,常见的有邻近点(point)、线性(linear)和各向异性(anisotropic)三种。寻址模式决定了当纹理坐标超出[0,1]范围时,如何处理边界情况,常见的有重复(repeat)、钳位(clamp)、边框(border)和镜像(mirror)四种。

使用场景

纹理采样的应用场景非常广泛,几乎所有的图形渲染都会用到纹理采样。例如:
基础颜色:我们可以使用一张彩色图片作为纹理,来为物体表面提供基础的颜色信息,从而使物体看起来更加丰富和多样。
法线贴图:我们可以使用一张法线图片作为纹理,来为物体表面提供法线信息,从而使物体看起来更加凹凸和立体。
高光贴图:我们可以使用一张灰度图片作为纹理,来为物体表面提供高光信息,从而使物体看起来更加光滑和反光。
遮罩贴图:我们可以使用一张黑白图片作为纹理,来为物体表面提供遮罩信息,从而使物体看起来更加复杂和多层次。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

线性代数:向量组的秩

目录 回顾“秩” 及 向量组线性表示 相关特性 向量组的秩 例1 例2 矩阵的“秩” 及 向量组线性表示 相关特性 向量组的秩 例1 例2

详解动态内存管理!

目录 ​编辑 1.为什么要用动态内存分配 2.malloc和free 2.1 malloc 2.2 free 3.calloc和realloc 3.1 calloc 3.2 realloc 4.常见的动态内存的错误 4.1 对NULL的解引用操作 4.2 对动态内存开辟空间的越界访问 4.3 对非动态内存开辟空间用free释放 4.4 使用free释放动…

⭐北邮复试刷题106. 从中序与后序遍历序列构造二叉树__递归分治 (力扣每日一题)

106. 从中序与后序遍历序列构造二叉树 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7], postor…

RLT8762D---WDG 模块

0 Preface/Foreword 1 working mechanism 1.1 看门狗配置 1.2 喂狗定时器驱动 喂狗定时器回调函数: 1.3 初始化定时器 1.3.1 启动喂狗定时器 1.3.2 使能ROM看门狗 1.4 喂狗 定时器发送喂狗消息。 WDG_Restart()用于喂狗,comment out之后&#xff0…

Stable Diffusion 绘画入门教程(webui)-ControlNet(姿态预处理器openpose)

本片文章接着上篇文章ControlNet介绍他的控制类型,本篇介绍的预处理器为openpose 预处理器:openpose 模型:control_v11p_sd15_openpose 没下载模型的看上篇文章去下载一下哦,不然用不了 文章目录 一、干什么用的二、详细用法1、选…

YOLO-World技术小结

infopaperhttps://arxiv.org/abs/2401.17270codehttps://github.com/AILab-CVC/YOLO-Worldorg腾讯demohttps://huggingface.co/spaces/stevengrove/YOLO-World个人博客位置http://www.myhz0606.com/article/yolo_world 1 Motivation 这篇文章从计算效率的角度解决开集目标检测…

ping 8.8.8.8和ping www.baidu.com都OK,但是打不开网页

ping 8.8.8.8和ping www.baidu.com都OK,但是打不开网页 打开设置 -> 网络 找到IPV4, DNS栏输入 8.8.8.8 , apply 设置里界面变成这样 然后网页就能加载了

开源软件的利弊

目录 开源软件 优势 免费 透明 可更改 可协作 影响力 坏处 安全隐患 良莠不齐 学习成本 持续性问题 未知风险 开源软件 开源软件是一种基于开放协作和共享的软件开发模式,其利弊对于软件产业和社会发展具有重要意义 优势 免费 谁能拒绝不要钱的东西…

C# redis 菜鸟级别 订阅与频道,发送消息

// 建立 Redis 连接 发送部分代码 using StackExchange.Redis; ConnectionMultiplexer redis ConnectionMultiplexer.Connect("127.0.0.1:6379,password123456"); // 获取发布者 ISubscriber publisher redis.GetSubscriber(); // 发布消息到指定频道 string c…

day4 2/21

1>使用多线程完成两个文件的拷贝&#xff0c;第一个线程拷贝前一半&#xff0c;第二个线程拷贝后一半&#xff0c;主线程回收两个线程的资源 #include<myhead.h> typedef struct Inof {const char*srcfile;const char*destfile;int start;int len; }inof;int do_len…

洗地机哪一款好用?洗地机热门品牌测评

虽然说现在市面上有很多洗地机牌子不断推陈出新&#xff0c;但是洗地机的功能使用总是不分你我&#xff0c;因为不管产品怎么变&#xff0c;一款优秀的洗地机都必须要具备良好的操控性能以及优秀的续航水平&#xff0c;另外在此基础上&#xff0c;继续考察其贴边清洁效果和杀菌…

【医学大模型】InMD-X:超精细化 + 内科医生的大语言模型

InMD-X&#xff1a;超精细化 内科医生的大语言模型 提出背景数据训练持续预训练监督式微调参数高效微调 提出背景 论文&#xff1a;https://arxiv.org/pdf/2402.11883.pdf 现有的医学语言模型往往将医疗健康视为一个单一领域&#xff0c;忽视了其复杂的子专业。 解法: 将内科…

【代码随想录python笔记整理】第十二课 · 位置互换

前言:本笔记仅仅只是对内容的整理和自行消化,并不是完整内容,如有侵权,联系立删。 一、变量交换的实现 这节我们讨论一个简单的问题——怎么交换两个变量的值。比如说,一个瓶子里是水,一个瓶子里是油,想要将两个瓶子中的东西互换,我们应该怎么做呢?要实现上述过程,我们…

测试环境搭建整套大数据系统(四:ubuntu22.4创建普通用户)

一&#xff1a;创建用户&#xff0c;修改密码&#xff0c;增加sudo权限。 useradd dolphinscheduler #输入密码 passwd dolphinscheduler # 配置 sudo 免密 sed -i $adolphinscheduler ALL(ALL) NOPASSWD: NOPASSWD: ALL /etc/sudoers sed -i s/Defaults requirett/#Defa…

【OpenSSH+Jenkins搭建项目自动化部署】

OpenSSHJenkins搭建项目自动化部署 一、Windows安装OpenSSH1.下载2.解压3.安装4.启停服务5.SSH免密登录 二、Jenkins安装1.下载2.安装启动3.登录 三、项目自动化部署1.SSH配置2.项目配置3.权限控制 一、Windows安装OpenSSH 1.下载 https://github.com/PowerShell/Win32-0penS…

2024,深层互联第二代IndoorLink领夹式讲解器面世!

新年之初&#xff0c;每一步都举足轻重。2024开年之际&#xff0c;资深讲解器厂家深层互联重磅推出第二代IndoorLink领夹式无线讲解器&#xff0c;各项性能指标全线升级&#xff0c;成为新的行业标杆&#xff0c;一经面世即引起巨大反响。 2023年2月&#xff0c;首代IndoorLin…

WSL2配置Linux、Docker、VS Code、zsh、oh my zsh

0. 写在前面 本篇笔记来自于UP主麦兜搞IT的合集视频Windows10开发环境搭建中的部分内容 1. 安装WSL2 按照微软官方文档进行操作&#xff0c;当然也可以直接wsl --install 也可以按照 旧版手动安装的步骤 来进行操作 选择安装的是Ubuntu 20.04 LTS 注&#xff1a;WSL默认安装…

SparkSQL学习01

目录 1.SparkSQL特点1.1易整合1.2统一的数据访问1.3兼容Hive1.4标准的数据连接 2 SparkSQL编程模型DataFrameDataSet2.1 SQL2.2 DataFrame是什么2.3 DataSet是什么2.4 RDD&#xff0c;DataSet&#xff0c;DataFrame 3 SparkSQL核心编程3.1 编程入口3.2 SparkSQL基本编程3.2.1编…

《VitePress 简易速速上手小册》第2章:Markdown 与页面创建(2024 最新版)

文章目录 2.1 Markdown 基础及扩展2.1.1 基础知识点解析2.1.2 重点案例&#xff1a;技术博客2.1.3 拓展案例 1&#xff1a;食谱分享2.1.4 拓展案例 2&#xff1a;个人旅行日记 2.2 页面结构与布局设计2.2.1 基础知识点解析2.2.2 重点案例&#xff1a;公司官网2.2.3 拓展案例 1&…

来看看投资界最关心的 Sora 几大问题

作者&#xff1a;苍何&#xff0c;前大厂高级 Java 工程师&#xff0c;阿里云专家博主&#xff0c;CSDN 2023 年 实力新星&#xff0c;土木转码&#xff0c;现任部门技术 leader&#xff0c;专注于互联网技术分享&#xff0c;职场经验分享。 &#x1f525;热门文章推荐&#xf…
最新文章