18.UntiyShader基础纹理
1.纹理映射-UV混合

步骤
1.读取Texture中uv坐标的颜色
2.将纹理颜色分别混合环境光和漫反射
核心代码 (在上一篇的高光模型代码中修改)
函数引用
tex2D() 传入uv坐标, 返回纹理对于像素颜色
关于纹理的Warp Mode主要有两种,一种是Repeat重复模式,一种是Clamp裁切模式
Repeat模式,超出0-1,取小数位
Clamp模式,超出0-1,错误的结果
完整代码, 素材也在目录中
https://github.com/smartgrass/MyCodes/blob/main/ShaderLearning/Texture_uv.shader
2.凹凸映射-Bump

凹凸映射有两种方式: 法线纹理 和 高度纹理(跳过)
法线纹理
存储的是表面法线方向, 用RGB颜色保存法线向量的x,y,z信息
由于纹理RGB分量在[0,1]上 , 需要映射到法线方向的分量的[-1,1]上
normal=pixel*2-1
向量的坐标系有两种: 切线空间 和 模型空间(跳过)
法线纹理一般用的是切线空间

理解
利用法线贴图中顶点法线向量,进行漫反射光照(Lambert定律)
步骤:
1.获取法线贴图中的顶点法线向量nor, 以及顶点指向灯光的向量lightDir,
2.将nor和lightDir转换到同个空间, 切线空间或世界空间都可以
3.利用Lambert计算像素亮度值, bump = max(0, dot(nor,lightDir))
4.亮度结果叠加到漫反射中,diffuse*=bump;
核心代码(切线空间)
函数引用
ObjSpaceLightDir(float4 v) 输入模型空间顶点坐标, 模型空间中从顶点指向灯光的向量
UnpackNormal(fixed4 packnormal) 颜色映射到法线向量

由于纹理压缩格式不同, 解析上有区别
在unity中, 如果Texture Type为Normal map ,压缩格式则会变为DXT5nm,
但unity的UnpackNormal()都帮我们处理好了
效果

完整代码
https://github.com/smartgrass/MyCodes/blob/main/ShaderLearning/Texture_bump.shader
选切线空间还是世界空间?
差别不大, 跟着5.x选世界空间

如果需要写世界空间代码, 需要注意, 结构体无法传3x3的矩阵, 那么可以使用3个float3来保存

3.渐变纹理-RampTex


核心代码
代码思路
计算dot(worldLightDir,worldNormal) = cosθ 得到[-1,1] 的亮度值,
映射到uv的[0,1]上, 则是 *0.5+0.5, 从而读取渐变图坐标的颜色值
最后叠加到材质颜色上 albedo*=ramp;
理解
顶点漫反射的亮度从0到1的映射到渐变纹理坐标颜色上
4.遮罩纹理-SpecularMask

遮罩纹理可以更加精细地控制光照细节,可以得到更细腻的效果
和渐变纹理类似,只不过遮罩纹理是对高光部分进行混合。
核心代码
这里取r分量作为淹码值
最后两部分相对简单...