文章目录

  • 纹理
  • 单张纹理
    • 纹理的属性
      • Wrap Mode 属性
      • Filter Mode属性
  • 凹凸映射
    • 高度纹理
    • 法线纹理
  • 渐变纹理
  • 遮罩纹理
    • 其他遮罩纹理

纹理

纹理就是使用一张图片来控制模型的外观。

使用纹理映射(texture mapping)技术,我们可以把一张图“黏”在模型表面,逐纹素(texel)(纹素的名字是为了和像素进行区分)地控制模型的颜色。

在美术人员建模的时候,通常会在建模软件中利用纹理展开技术把纹理映射坐标(texture-mapping coordinates)存储在每个顶点上。纹理映射坐标定义了该顶点在纹理中对应的2D坐标。通常,这些坐标使用一个**二维变量(u, v)**来表示,其中u是横向坐标,而v是纵向坐标。因此,纹理映射坐标也被称为UV坐标


纹理的大小可以是多种多样的,如256×256或者1028×1028,但顶点UV坐标的范围通常都被归一化到[0, 1]范围内。

纹理采样时使用的纹理坐标不一定是在[0, 1]范围内。实际上,这种不在[0, 1]范围内的纹理坐标有时会非常有用。与之关系紧密的是纹理的平铺模式,它将决定渲染引擎在遇到不在[0, 1]范围内的纹理坐标时如何进行纹理采样。

单张纹理

使用一张纹理来代替物体的漫反射颜色:


// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader "Unlit/CH7-SingleTexture" {Properties {_Color ("Color Tint", Color) = (1, 1, 1, 1)// 2D是纹理属性的声明方式// 使用一个字符串后跟一个花括号作为它的初始值,"white"是内置纹理的名字,也就是一个全白的纹理。_MainTex ("Main Tex", 2D) = "white" {}_Specular ("Specular", Color) = (1, 1, 1, 1)_Gloss ("Gloss", Range(8.0, 256)) = 20}SubShader {Pass {Tags {// LightMode标签是Pass标签中的一种,它用于定义该Pass在Unity的光照流水线中的角色。"LightMode" = "ForwardBase"}CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"fixed4 _Color;sampler2D _MainTex;// 纹理名_ST的方式来声明某个纹理的属性// ST是缩放(scale)和平移(translation)的缩写// _MainTex_ST可以让我们得到该纹理的缩放和平移(偏移)值// _MainTex_ST.xy存储的是缩放值// _MainTex_ST.zw存储的是偏移值float4 _MainTex_ST; fixed4 _Specular;float _Gloss;struct a2v {float4 vertex : POSITION;float3 normal : NORMAL;float4 texcoord : TEXCOORD0;    // 将模型的第一组纹理坐标存储到该变量中};struct v2f {float4 pos : SV_POSITION;float3 worldNormal : TEXCOORD0;float3 worldPos : TEXCOORD1;float2 uv : TEXCOORD2;};v2f vert (a2v v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;o.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;return o;}fixed4 frag (v2f i) : SV_Target {fixed3 worldNormal = normalize(i.worldNormal);fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));fixed3 halfDir = normalize(worldLightDir + viewDir);fixed3 Specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);return fixed4(ambient + diffuse + Specular, 1.0);}ENDCG}}Fallback "Specular"
}

纹理的属性

Wrap Mode 属性

Repeat:如果纹理坐标超过了1,那么它的整数部分将会被舍弃,而直接使用小数部分进行采样,这样的结果是纹理将会不断重复

Clamp:如果纹理坐标大于1,那么将会截取到1,如果小于0,那么将会截取到0


上图展示了在纹理的平铺(Tiling)属性为(3, 3)时分别使用两种Wrap Mode的结果。
左图使用了Repeat模式,在这种模式下纹理将会不断重复;
右图使用了Clamp模式,在这种模式下超过范围的部分将会截取到边界值,形成一个条形结构。


上图展示了在纹理的偏移属性为(0.2, 0.6)时分别使用两种Wrap Mode的结果,左图使用了Repeat模式,右图使用了Clamp模式。

Filter Mode属性

Filter Mode属性决定了当纹理由于变换而产生拉伸时将会采用哪种滤波模式。

Filter Mode支持3种模式:Point,Bilinear以及Trilinear。
它们得到的图片滤波效果依次提升,但需要耗费的性能也依次增大。
纹理滤波会影响放大或缩小纹理时得到的图片质量。
例如,当我们把一张64×64大小的纹理贴在一个512×512大小的平面上时,就需要放大纹理。


纹理缩小的过程比放大更加复杂一些,此时原纹理中的多个像素将会对应一个目标像素。
纹理缩放更加复杂的原因在于我们往往需要处理抗锯齿问题,一个最常使用的方法就是使用多级渐远纹理(mipmapping)技术。
“mip”是拉丁文“multum in parvo”的缩写,它的意思是“在一个小空间中有许多东西”。

多级渐远纹理技术将原纹理提前用滤波处理得到很多更小的图像,形成了一个图像金字塔,每一层都是对上一层图像降采样的结果。这样在实时运行时,就可以快速得到结果像素,例如当物体远离摄像机时,可以直接使用较小的纹理。但缺点是需要使用一定的空间用于存储这些多级渐远纹理,通常会多占用33%的内存空间。这是一种典型的用空间换取时间的方法。

在Unity中,我们可以在纹理导入面板中,首先将纹理类型(Texture Type)选择成Advanced,再勾选Generate Mip Maps即可开启多级渐远纹理技术。同时,我们还可以选择生成多级渐远纹理时是否使用线性空间(用于伽玛校正,详见18.4.2节)以及采用的滤波器等。

上图给出了从一个倾斜的角度观察一个网格结构的地板时,使用不同FilterMode(同时也使用了多级渐远纹理技术)得到的效果。

在内部实现上,Point模式使用了最近邻(nearest neighbor)滤波,在放大或缩小时,它的采样像素数目通常只有一个,因此图像会看起来有种像素风格的效果。
而Bilinear滤波则使用了线性滤波,对于每个目标像素,它会找到4个邻近像素,然后对它们进行线性插值混合后得到最终像素,因此图像看起来像被模糊了。
而Trilinear滤波几乎是和Bilinear一样的,只是Trilinear还会在多级渐远纹理之间进行混合。如果一张纹理没有使用多级渐远纹理技术,那么Trilinear得到的结果是和Bilinear就一样的。
通常,我们会选择Bilinear滤波模式。需要注意的是,有时我们不希望纹理看起来是模糊的,例如对于一些类似棋盘的纹理,我们希望它就是像素风的,这时我们可能会选择Point模式。

凹凸映射

纹理的另一种常见的应用就是凹凸映射(bump mapping)。

凹凸映射的目的是使用一张纹理来修改模型表面的法线,以便为模型提供更多的细节

这种方法不会真的改变模型的顶点位置,只是让模型看起来好像是“凹凸不平”的,但可以从模型的轮廓处看出“破绽”。

有两种主要的方法可以用来进行凹凸映射:

  1. 使用一张高度纹理(height map)来模拟表面位移(displacement),然后得到一个修改后的法线值,这种方法也被称为高度映射(height mapping)
  2. 使用一张法线纹理(normal map)来直接存储表面法线,这种方法又被称为法线映射(normal mapping)

高度纹理

高度图中存储的是强度值(intensity),它用于表示模型表面局部的海拔高度。
颜色越浅表明该位置的表面越向外凸起,而颜色越深表明该位置越向里凹。

这种方法的好处是非常直观,我们可以从高度图中明确地知道一个模型表面的凹凸情况,但缺点是计算更加复杂,在实时计算时不能直接得到表面法线,而是需要由像素的灰度值计算而得,因此需要消耗更多的性能。


【unity shader 入门精要】CH7 基础纹理相关推荐

  1. 【Unity Shader入门精要】普通纹理和高级纹理

    原作者博客链接:http://blog.csdn.net/candycat1992/article/  书籍链接:http://product.dangdang.com/23972910.html 纹 ...

  2. Unity Shader入门精要第七章 基础纹理之遮罩纹理

    Unity系列文章目录 文章目录 Unity系列文章目录 前言 一.实践 参考 前言 遮罩纹理(mask texture)是本章要介绍的最后一种纹理,它非常有用,在很多商业游戏中 都可以见到它的身影. ...

  3. Unity Shader入门精要学习笔记 - 第7章 基础纹理

    转自 冯乐乐的 <Unity Shader 入门精要> 纹理最初的目的就是使用一张图片来控制模型的外观.使用纹理映射技术,我们可以把一张图"黏"在模型表面,逐纹素地控制 ...

  4. Unity Shader入门精要第七章 基础纹理 凹凸映射之在世界空间下计算

    Unity系列文章目录 文章目录 Unity系列文章目录 前言 一.pandas是什么? 二.使用步骤 2.Unity 中的法线纹理类型 参考 前言 现在,我们来实现第二种方法,即在世界空间下计算光照 ...

  5. Unity Shader入门精要第七章 基础纹理渐变纹理

    Unity系列文章目录 文章目录 Unity系列文章目录 前言 一.渐变纹理是什么 参考 前言 尽管在一开始,我们在渲染中使用纹理是为了定义一个物体的颜色,但后来人们发现,纹理 其实可以用于存储任何表 ...

  6. 【《Unity Shader入门精要》 提炼总结】(九)第九章·UV贴图纹理概念介绍单张纹理的应用Shader常见函数总结

    本文由@唐三十胖子出品,转载请注明出处.   文章链接:https://blog.csdn.net/iceSony/article/details/84587428 这篇文章将总结和提炼<Uni ...

  7. Unity Shader入门精要——第3章 Unity Shader基础

    Unity Shader入门精要读书笔记系列 第1章 欢迎来到Shader的世界 第2章 渲染流水线 第3章 Unity Shader基础 文章目录 Unity Shader入门精要读书笔记系列 前言 ...

  8. Unity Shader入门精要第3 章 Unity Shader 基础

    Unity系列文章目录 文章目录 Unity系列文章目录 前言 一.Unity Shader 概述 二.使用步骤 1.3.1.2 Unity 中的材质 2.Unity 中的Shader 3.Unity ...

  9. unity shader入门精要_Unity Shader 入门(二):shader 基础

    一.参考与说明(需要写在开始东西): 1.1 Unity Shader 入门精要学习 https://github.com/candycat1992/Unity_Shaders_Book/tree/u ...

  10. Unity Shader入门精要学习笔记 - 第6章 开始 Unity 中的基础光照

    转自冯乐乐的<Unity Shader入门精要> 通常来讲,我们要模拟真实的光照环境来生成一张图像,需要考虑3种物理现象. 首先,光线从光源中被发射出来. 然后,光线和场景中的一些物体相交 ...

最新文章

  1. 手把手视频:万能开源Hawk抓取动态网站
  2. mysql数据库文件位置
  3. 紫金计算机网络,南京理工大学紫金学院《计算机网络技术》考试复习试题试题(含答案解析)2...
  4. linux将mysql导出表数据导入另一台服务器_远程linux服务器mysql数据库导入和导出.sql文件...
  5. android 系统(7)---android框架大全
  6. C#之不得不上的网站。
  7. jquery中checkbox全选失效的解决方法
  8. 一人身兼多个项目时的“课程表”工作模式实践
  9. matlab中的tall,tall 数组 - MATLAB Simulink - MathWorks 中国
  10. 一些常用PLSQL语句 和事务
  11. JVM本地方法栈及native方法
  12. android singletask启动模式,android:Activity启动模式之singleTask(一)(示例代码)
  13. 监控神器Prometheus
  14. 达梦DW+DSC环境mal压缩测试
  15. 再忆年少,再见年少——青春路上的我们
  16. win7下安装配置theano详解
  17. 【JavaWeb学习】HTML的基础标签
  18. 屏幕处理效果—调整屏幕的亮度,饱和度和对比度
  19. html 图片 空白,HTML图片标签空白解决方法
  20. 怎样通过易查分制作二维码查分系统

热门文章

  1. mt4修改服务器时间设置,mt4服务器时间设置
  2. kali开启流量转发进行流量分析
  3. Zed 深度相机 Python 安装
  4. STM32 四轴无人机的设计——代码整体设计
  5. vba中的replace用法
  6. 自建CDN技术选型: squid varnish nginx
  7. 如何通过盗取EMV卡的数据,让ATM机吐出5万美元
  8. 2021级计算保研经验分享
  9. 第2章 人脉圈:谁是你生命中的贵人
  10. 『QT』创客空间元件管理系统|账户登录的实现