数据查询网站如何做,如何把自己做的网站放到微信上,市场管理监督局是干什么的,小蝌蚪视频网络科技有限公司文章目录 前言一、什么是纹理采样#xff1f;1. 纹理采样的工作原理2. 纹理采样的优缺点优点缺点 二、使用步骤1. Shader 属性定义2. SubShader 设置3. 渲染 Pass4. 定义结构体和顶点着色器函数5. 片元着色器函数 三、效果四、总结使用场景 前言
纹理采样是一种常用的图形学技… 文章目录 前言一、什么是纹理采样1. 纹理采样的工作原理2. 纹理采样的优缺点优点缺点 二、使用步骤1. Shader 属性定义2. SubShader 设置3. 渲染 Pass4. 定义结构体和顶点着色器函数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.worldPosmul(unity_ObjectToWorld,v.vertex);return o;
}顶点着色器的输入是一个结构体 appdata_base 它包含了顶点的位置和法线信息等。顶点着色器的输出是一个结构体 v2f 它包含了顶点的裁剪空间位置和世界空间法线和位置信息等。
顶点着色器的主要逻辑是 使用 UnityObjectToClipPos 函数将顶点的位置从对象空间变换到裁剪空间这是渲染管线的必要步骤。 使用 UnityObjectToWorldNormal 函数将顶点的法线从对象空间变换到世界空间这是为了计算光照效果所需的方向向量。 使用 TRANSFORM_TEX 函数将顶点的贴图坐标根据 _MainTex_ST 的值进行缩放和偏移这是为了让贴图的属性可以影响到贴图的显示。 使用 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 类型的颜色值它表示了片元的颜色。
片元着色器的主要逻辑是 使用 UNITY_LIGHTMODEL_AMBIENT 宏获取环境光的颜色这是 Phong 光照模型的第一个分量。 使用 tex2D 函数对 _MainTex 进行纹理采样根据 i 的 uv 值获取对应的像素颜色它是物体的表面颜色。 使用 UnityWorldSpaceLightDir 函数获取光源的方向向量这是为了计算漫反射和高光效果所需的角度。 使用 _LightColor0 和 _Diffuse 变量获取光源的颜色和物体的漫反射颜色然后使用 max 和 dot 函数计算光源和法线的夹角的余弦值然后乘以 0.5 并加上 0.5这是为了将 [-1, 1] 的范围映射到 [0, 1] 的范围这是 Phong 光照模型的第二个分量 使用 UnityWorldSpaceViewDir 函数根据 i 的 worldPos 值获取视线的方向向量这是为了计算高光效果所需的角度。 使用 normalize 函数计算视线方向和光源方向的半向量这是为了简化高光效果的计算。 使用 _LightColor0 和 _Specular 变量获取光源的颜色和物体的高光颜色然后使用 max 和 dot 函数计算法线和半向量的夹角的余弦值然后使用 pow 函数根据 _Gloss 的值计算高光的强度这是 Phong 光照模型的第三个分量。 将环境光、漫反射和高光的颜色相加得到最终的光照颜色作为片元着色器的输出。
三、效果 四、总结
纹理采样是从一张纹理图片中获取颜色值的过程它需要指定一个纹理坐标uv和一个采样器sampler。采样器定义了纹理的过滤方式filter和寻址模式wrap。过滤方式决定了当纹理坐标不是整数时如何插值得到颜色值常见的有邻近点point、线性linear和各向异性anisotropic三种。寻址模式决定了当纹理坐标超出[0,1]范围时如何处理边界情况常见的有重复repeat、钳位clamp、边框border和镜像mirror四种。
使用场景
纹理采样的应用场景非常广泛几乎所有的图形渲染都会用到纹理采样。例如 基础颜色我们可以使用一张彩色图片作为纹理来为物体表面提供基础的颜色信息从而使物体看起来更加丰富和多样。 法线贴图我们可以使用一张法线图片作为纹理来为物体表面提供法线信息从而使物体看起来更加凹凸和立体。 高光贴图我们可以使用一张灰度图片作为纹理来为物体表面提供高光信息从而使物体看起来更加光滑和反光。 遮罩贴图我们可以使用一张黑白图片作为纹理来为物体表面提供遮罩信息从而使物体看起来更加复杂和多层次。