自言自语
今天又学习了一个映射技术 我给他翻译为三方向平面映射技术。 挺有用的 对于一些特殊需求下 再不用展UV的时候可以用到。还能在什么地方用到,我还不知道,但是听同事说前两天正好要用到这个东西,就觉得挺有用的 特地学习了下 比较简单,找着大佬们写的代码看一遍理解后自己又写了下。并且整理到一个方法中 方便以后随时回来取用。懒人。没办法。
一、效果
Debug模式下的表现
目的就是把一张贴图,蛮横无理的忽视其自身UV的情况下 相对比较平整的贴到模型上,使其从上下左右前后这六个方向上看都是平铺的。但因为上下左右前后都是对称的,也就是只有3个轴向,所以叫做三方向或者三轴向。又由于是把贴图平铺上去,不考虑物体的形状和拉伸,像一个平面一样,所以叫平面映射,最后总成三轴向平面映射,TriPlanar。
以上,全是鄙人自己瞎掰的,说的不对或者立即不对,大佬请指出。
上贴图的样子是这样的
挺平整哈 虽然还是会有拼接的痕迹,但如果是要做一些扰动啊 噪声图啊 再通过smooth平滑过渡调整一下边界的过渡平滑值,拼接痕迹就基本看不出来了 如下图
二、Shader
Shader "TNShaderPractise/Tri_Planar"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Weight("Smooth",Float) = 10
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct a2v
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
half3 normal : NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
half3 normalWS : TEXCOORD1;
float4 pos : SV_POSITION;
float4 posWS : TEXCOORD2;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _Weight;
v2f vert (a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.posWS = mul(unity_ObjectToWorld,v.vertex);
o.normalWS = UnityObjectToWorldNormal(v.normal);
return o;
}
//在这里把TriPlanar直接封装成一个方法,方便我以后自己来复制粘贴,懒人必备. 当然也可以直接写在片元着色器里.这样扩展调整更强,封装好了嘛就方便,简单.
half4 TriPlanar (float4 posWS,half3 normal,float smooth,sampler2D textures)
{
half3 normalWS = normalize(normal);
half3 weight = pow(abs(normalWS),smooth);
half3 uvWeight = weight /(weight.x+weight.y+weight.z);
half4 col0 = tex2D(textures,posWS.xy)*uvWeight.z;
half4 col1 = tex2D(textures,posWS.xz)*uvWeight.y;
half4 col2 = tex2D(textures,posWS.zy)*uvWeight.x;
return col0+col1+col2;
}
half4 frag (v2f i) : SV_Target
{
float2 uv = i.uv;
half3 normalWS = normalize(i.normalWS);
//就这么轻松愉快的调用封装方法,直接得到拼接好的最终效果.爽
half4 triCol = TriPlanar(i.posWS,normalWS,_Weight,_MainTex);
return triCol;
}
ENDCG
}
}
}
总结
深深感叹知识就是力量,学习TA的路上,总是被各种实现方法惊叹.现在学习的都还是只是比较表层的东西,图形相关,程序逻辑和算法相关的都一知半解,还得继续努力不断学习下去啊.加油,自勉