赞
踩
首先功能是在Unity中能在任意的模型上实现类似unity自带的地形系统里的贴图绘制功能。
能够支持最多4张自定义贴图的融合。
源码是在微元素论坛上大佬写的,可以在论坛搜索下E3D MeshPainter这个插件。我稍微改了下并且融合到了自己的Shader中,这里记录下学习的过程。
主要原理是利用一张贴图(SplatMap)的RGBA通道,分别指定不同的模型区域。一个通道对应一套需要融合的贴图。为了优化效果,一套贴图只有两张图,第一张图的RGB通道存放固有色,A通道存放高度信息,A通道的图是为了在刷地形的过程中能实现先绘制缝隙(高度图黑色区域)的功能。第二张图RG通道存放法线信息,B通道存放粗糙度。金属度用0-1的值控制。
-
- //采样所有贴图
- float4 OutPutBaseColor;
- half4 OutPutBaseColor0 = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, i.uv * _BaseMap_ST.xy + _BaseMap_ST.zw) * _BaseColor;
- half4 OutPutBaseColor1 = SAMPLE_TEXTURE2D(_BaseMap1, sampler_BaseMap1, i.uv * _BaseMap1_ST.xy + _BaseMap1_ST.zw) * _BaseColor1;
- half4 OutPutBaseColor2 = SAMPLE_TEXTURE2D(_BaseMap2, sampler_BaseMap2, i.uv * _BaseMap2_ST.xy + _BaseMap2_ST.zw) * _BaseColor2;
- half4 OutPutBaseColor3 = SAMPLE_TEXTURE2D(_BaseMap3, sampler_BaseMap3, i.uv * _BaseMap3_ST.xy + _BaseMap3_ST.zw) * _BaseColor3;
- half3 normalTangent0 = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, i.uv * _BaseMap_ST.xy + _BaseMap_ST.z).xyz;
- half3 normalTangent1 = SAMPLE_TEXTURE2D(_NormalMap1, sampler_NormalMap1, i.uv * _BaseMap1_ST.xy + _BaseMap1_ST.zw).xyz;
- half3 normalTangent2 = SAMPLE_TEXTURE2D(_NormalMap2, sampler_NormalMap2, i.uv * _BaseMap2_ST.xy + _BaseMap2_ST.zw).xyz;
- half3 normalTangent3 = SAMPLE_TEXTURE2D(_NormalMap3, sampler_NormalMap3, i.uv * _BaseMap3_ST.xy + _BaseMap3_ST.zw).xyz;
-
- half4 var_Control = SAMPLE_TEXTURE2D(_Control, sampler_Control, i.uv * _Control_ST.xy + _Control_ST.zw);
- half4 blend = HeightBlendTex(_BlendWeight,OutPutBaseColor0.a,OutPutBaseColor1.a,OutPutBaseColor2.a,OutPutBaseColor3.a,var_Control);
-
- OutPutBaseColor = (OutPutBaseColor0 * blend.r + OutPutBaseColor1 * blend.g + OutPutBaseColor2 * blend.b + OutPutBaseColor3 * blend.a) * _ColorAll;
-
- half OutPutSpecGloss;
-
- OutPutSpecGloss = blend.r * lerp(0.0,normalTangent0.b,_BlendRoughness.x)
- + blend.g * lerp(0.0,normalTangent1.b,_BlendRoughness.y)
- + blend.b * lerp(0.0,normalTangent2.b,_BlendRoughness.z)
- + blend.a * lerp(0.0,normalTangent3.b,_BlendRoughness.w);
- float OutPutRoughness = 1-sqrt(OutPutSpecGloss);
-
- half OutPutMetallicGloss;
- OutPutMetallicGloss = _BlendMetallic.r * blend.r + _BlendMetallic.g * blend.g + _BlendMetallic.b * blend.b + _BlendMetallic.a * blend.a;
-
-
- half3 normal = (float3(normalTangent0.rg,1) * 2 - 0.42) * blend.r;
- half3 normal1 = (float3(normalTangent1.rg,1) * 2 - 0.42) * blend.g;
- half3 normal2 = (float3(normalTangent2.rg,1) * 2 - 0.42) * blend.b;
- half3 normal3 = (float3(normalTangent3.rg,1) * 2 - 0.42) * blend.a;
-
- half3 normalTangent = normalize(normal + normal1 + normal2 + normal3);
-
- half3 normalWorld = normalize(half3(
- dot(i.TtoW0.xyz, normalTangent),
- dot(i.TtoW1.xyz, normalTangent),
- dot(i.TtoW2.xyz, normalTangent)));
-
- half4 HeightBlendTex(half weight,half depth1,half depth2,half depth3,half depth4,half4 control)
- {
- half4 blend ;
-
- blend.r =depth1 * control.r;
- blend.g =depth2 * control.g;
- blend.b =depth3 * control.b;
- blend.a =depth4 * control.a;
-
- half ma = max(blend.r, max(blend.g, max(blend.b, blend.a)));
- blend = max(blend - ma + weight , 0) * control;
- return blend/(blend.r + blend.g + blend.b + blend.a);
- }
那么现在的问题就是如何在编辑模式下如何实时修改那种控制图。 原理是先使用射线检测得到鼠标点击到的信息,得到UV位置等信息。
Physics.Raycast(terrain, out raycastHit, Mathf.Infinity, 1 << LayerMask.NameToLayer(useLayers[i]))
然后将控制图的颜色信息提取出来。
Color[] terrainBay = MaskTex.GetPixels(x, y, width, height, 0); //得到x,y位置width,height笔刷尺寸的颜色信息
提取出来后将颜色信息和需要绘制的颜色做Lerp。绘制的颜色需要4个颜色,分别是纯的RGBA。
- //定义绘制的颜色
- Color targetColor = new Color(1f, 0f, 0f, 0f);
- switch (selTex) //选择绘制的贴图
- {
- case 0:
- targetColor = new Color(1f, 0f, 0f, 0f);
- break;
- case 1:
- targetColor = new Color(0f, 1f, 0f, 0f);
- break;
- case 2:
- targetColor = new Color(0f, 0f, 1f, 0f);
- break;
- case 3:
- targetColor = new Color(0f, 0f, 0f, 1f);
- break;
- }
-
-
- //使用笔刷在原颜色和绘制颜色中Lerp
- terrainBay[index] = Color.Lerp(terrainBay[index], targetColor, Stronger); //设置颜色绘制的颜色 使用Stronger在原图和绘制颜色中做Lerp
最后将新的颜色传回控制图。
MaskTex.SetPixels(x, y, width, height, terrainBay, 0); //使用terrainBay颜色 绘制x,y位置width,height尺寸的颜色信息
剩下的就是一些UnityEditor的编辑器样式修改。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。