【Unity3D Shader】学习笔记-纹理采样②
前言
上一篇对同一纹理进行多次采样混合,本篇则是通过不同的纹理采样进行混合产生一些效果。
[声明:本笔记系列文章的图片资源都源自百度图片搜索,如有问题联系我]
一、简单贴花
贴花简单来说就是在原贴图上面贴上细节贴图,就像墙面上的喷绘一样。下面这个只是最简单的例子,也就是只能在一张图(一个模型)上面贴其他细节。
fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); // 这里加了点偏移 fixed4 details = tex2D(_DetailsTex, i.uv + fixed2(-0.2, 0.0)); return lerp(col, details, details.a); }
二、法线贴图
通过将法线贴图和光照方向转换到切线空间,然后进行漫反射计算,得到模型的更多细节。
v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); // 这个矩阵用来把模型空间下的方向转换成切线空间下 TANGENT_SPACE_ROTATION; //得到切线下的光照方向 o.lightDir = normalize(mul(rotation, ObjSpaceLightDir(v.vertex))); UNITY_TRANSFER_FOG(o,o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { // 法线贴图采样 fixed4 normalColor = tex2D(_NormalTex, i.uv); // 切线空间下的法线 fixed3 tangentNormal = UnpackScaleNormal(normalColor, _BumpScale); tangentNormal = normalize(tangentNormal); fixed4 base_color = tex2D(_MainTex, i.uv); // 法线和灯光同方向为1,相互垂直为0,相反则为-1. 或者是光和法线的夹角,小于90度为正数,大于90度为负数。 float NdotL = dot(tangentNormal, i.lightDir); fixed3 diffuse = _LightColor0.rgb * base_color.rgb * saturate(NdotL); return fixed4(diffuse, 1.0); }
三、扰动图采样
通过对扰动图进行采样来计算对主纹理采样的新的uv数据,从而控制采样后的效果,更换不同的扰动图会获得不同的效果。下图类似热扭曲效果。还可以做更多的效果,例如水滴,水流,焦散等等。
fixed4 frag (v2f i) : SV_Target { // 控制uv的偏移 float _offsetU = 1.2; float _offsetV = 1.2; // 控制速度 float _Spd = 0.4; // 扰动强度 float _Force = 0.026; float2 l_uv = float2(-_Spd*_Time.x*_offsetU, _offsetV*-_Spd*_Time.x); float2 r_uv = float2(_Spd*_Time.x*_offsetU, _offsetV*_Spd*_Time.x); //贴图扰动采样 float4 distort = tex2D(_NoiseTex,i.uv + l_uv); float4 distort2 = tex2D(_NoiseTex,i.uv + r_uv); // 生成新的uv进行纹理采样 float2 n_uv = i.uv + _Force * float2(distort.r + distort2.r, distort.g + distort2.g); float4 col = tex2D(_MainTex, n_uv); return col; }