第7章
- 单张纹理
- 纹素,纹理的基本元素
- 在Properties定义纹理属性的格式
- _MainTex("Main Tex",2D) = "white"{}
- 在CG代码段里定义的纹理名
- sample2D _MainTex
- float4 _MainTex_ST代表纹理的平移和缩放
- _MainTex_ST.zw代表平移,_MainTex_ST.xy代表缩放
- tex2D(纹理,uv坐标)获得某个坐标的纹素
- 将tex2D获得的纹素和颜色属性_Color相乘获得材质反射率,再和UNITY_LIGHTMODEL_AMBIENT相乘得到材质环境光照的结果
- 入射光的颜色 x 材质反射率 x max (0,法线方向 x 光源方向)
- 纹理的属性
- wrap mode,循环模式,分为repeat,clamp,mirror(镜像)
- filter mode ,滤波模式,纹理和模型分辨率不对等时,纹理会进行变换,不同的滤波模式决定变换后的图像质量。效果:Trilinear>Bilinear>Point
- mipmapping,多级渐远纹理
- 凹凸映射
- 有两种方法来进行凹凸映射,一个用高度纹理来进行高度映射,一个用法线纹理来进行法线映射
- 法线方向和像素颜色的转换关系pixel = (normal+1)/2
- 法线纹理一般用切线空间来存储,优点如下
- 自由度高,可以用在不同模型
- 可以做UV动画
- 可以压缩,因为z方向可以由xy来推导
- 在Properties定义法线纹理的格式
- _BumpMap("Normal Map",2D) = "bump"{}
- _BumpScale("Bump Scale",Float) = 1.0
- 在CG代码段丽定义的纹理名
- sampler2D _BumpMap
- float4 _BumpMap_ST
- float _BumpScale
- 切线空间下的法线
fixed4 bumpNormal = tex2D(_BumpMap,i.uv.zw); fixed3 tangetNormal = UnpackNormal(bumpNormal); tangetNormal.xy *= _BumpScale; tangetNormal.z = sqrt(1.0 - saturate(dot(tangetNormal.xy,tangetNormal.xy)));
- 传给片元着色器的结构体需要float4 uv。xy分量存储纹理贴图的位置,zw分量存储法线贴图的位置
- 引入法线贴图后,之前计算漫反射和高光发射公式里的法向量需要重新计算,不能直接使用顶点的法向量
- 如何得到切线空间下的法线(在有法线贴图的情况下)?
- 计算顶点对应的法线贴图的位置。uv = texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw
- fixed4 packedNormal = tex2D(_BumpMap,uv).得到法线贴图记录的法线信息
- 如果纹理没有被标记为"Normal Map"
- tangentNormal.xy = (packedNormal.xy * 2-1) * _BumpScale;
- tangentNormal.z = sqrt(1-saturate(dot(tangentNormal.xy,tangentNormal.xy)
- 如果纹理被标记为"Normal Map"
- tangentNormal = UnpackNormal(packedNormal)
- tangentNormal.xy *=_BumpScale
- tangentNormal.z = sqrt(1-saturate(dot(tangentNormal.xy,tangentNormal.xy)
- 使用unity内置的shader时需要将法线纹理标记为"Normal Map"
- 渐变纹理
- 需要把渐变纹理的Wrap Mode设为Clamp模式
- 遮罩纹理
- 通过采样得到遮罩纹理的纹素值,使用某个通道的值和表面属性相乘
- tex2D(_SpecularMask,i.uv) * _SpecularScale