当前位置:   article > 正文

Unity 模型上绘制贴图融合_unity怎么绘制多个tilling采样多个贴图

unity怎么绘制多个tilling采样多个贴图

    首先功能是在Unity中能在任意的模型上实现类似unity自带的地形系统里的贴图绘制功能。

能够支持最多4张自定义贴图的融合。

源码是在微元素论坛上大佬写的,可以在论坛搜索下E3D MeshPainter这个插件。我稍微改了下并且融合到了自己的Shader中,这里记录下学习的过程。

    主要原理是利用一张贴图(SplatMap)的RGBA通道,分别指定不同的模型区域。一个通道对应一套需要融合的贴图。为了优化效果,一套贴图只有两张图,第一张图的RGB通道存放固有色,A通道存放高度信息,A通道的图是为了在刷地形的过程中能实现先绘制缝隙(高度图黑色区域)的功能。第二张图RG通道存放法线信息,B通道存放粗糙度。金属度用0-1的值控制。

  1. //采样所有贴图
  2. float4 OutPutBaseColor;
  3. half4 OutPutBaseColor0 = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, i.uv * _BaseMap_ST.xy + _BaseMap_ST.zw) * _BaseColor;
  4. half4 OutPutBaseColor1 = SAMPLE_TEXTURE2D(_BaseMap1, sampler_BaseMap1, i.uv * _BaseMap1_ST.xy + _BaseMap1_ST.zw) * _BaseColor1;
  5. half4 OutPutBaseColor2 = SAMPLE_TEXTURE2D(_BaseMap2, sampler_BaseMap2, i.uv * _BaseMap2_ST.xy + _BaseMap2_ST.zw) * _BaseColor2;
  6. half4 OutPutBaseColor3 = SAMPLE_TEXTURE2D(_BaseMap3, sampler_BaseMap3, i.uv * _BaseMap3_ST.xy + _BaseMap3_ST.zw) * _BaseColor3;
  7. half3 normalTangent0 = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, i.uv * _BaseMap_ST.xy + _BaseMap_ST.z).xyz;
  8. half3 normalTangent1 = SAMPLE_TEXTURE2D(_NormalMap1, sampler_NormalMap1, i.uv * _BaseMap1_ST.xy + _BaseMap1_ST.zw).xyz;
  9. half3 normalTangent2 = SAMPLE_TEXTURE2D(_NormalMap2, sampler_NormalMap2, i.uv * _BaseMap2_ST.xy + _BaseMap2_ST.zw).xyz;
  10. half3 normalTangent3 = SAMPLE_TEXTURE2D(_NormalMap3, sampler_NormalMap3, i.uv * _BaseMap3_ST.xy + _BaseMap3_ST.zw).xyz;
  11. half4 var_Control = SAMPLE_TEXTURE2D(_Control, sampler_Control, i.uv * _Control_ST.xy + _Control_ST.zw);
  12. half4 blend = HeightBlendTex(_BlendWeight,OutPutBaseColor0.a,OutPutBaseColor1.a,OutPutBaseColor2.a,OutPutBaseColor3.a,var_Control);
  13. OutPutBaseColor = (OutPutBaseColor0 * blend.r + OutPutBaseColor1 * blend.g + OutPutBaseColor2 * blend.b + OutPutBaseColor3 * blend.a) * _ColorAll;
  14. half OutPutSpecGloss;
  15. OutPutSpecGloss = blend.r * lerp(0.0,normalTangent0.b,_BlendRoughness.x)
  16. + blend.g * lerp(0.0,normalTangent1.b,_BlendRoughness.y)
  17. + blend.b * lerp(0.0,normalTangent2.b,_BlendRoughness.z)
  18. + blend.a * lerp(0.0,normalTangent3.b,_BlendRoughness.w);
  19. float OutPutRoughness = 1-sqrt(OutPutSpecGloss);
  20. half OutPutMetallicGloss;
  21. OutPutMetallicGloss = _BlendMetallic.r * blend.r + _BlendMetallic.g * blend.g + _BlendMetallic.b * blend.b + _BlendMetallic.a * blend.a;
  22. half3 normal = (float3(normalTangent0.rg,1) * 2 - 0.42) * blend.r;
  23. half3 normal1 = (float3(normalTangent1.rg,1) * 2 - 0.42) * blend.g;
  24. half3 normal2 = (float3(normalTangent2.rg,1) * 2 - 0.42) * blend.b;
  25. half3 normal3 = (float3(normalTangent3.rg,1) * 2 - 0.42) * blend.a;
  26. half3 normalTangent = normalize(normal + normal1 + normal2 + normal3);
  27. half3 normalWorld = normalize(half3(
  28. dot(i.TtoW0.xyz, normalTangent),
  29. dot(i.TtoW1.xyz, normalTangent),
  30. dot(i.TtoW2.xyz, normalTangent)));
  31. half4 HeightBlendTex(half weight,half depth1,half depth2,half depth3,half depth4,half4 control)
  32. {
  33. half4 blend ;
  34. blend.r =depth1 * control.r;
  35. blend.g =depth2 * control.g;
  36. blend.b =depth3 * control.b;
  37. blend.a =depth4 * control.a;
  38. half ma = max(blend.r, max(blend.g, max(blend.b, blend.a)));
  39. blend = max(blend - ma + weight , 0) * control;
  40. return blend/(blend.r + blend.g + blend.b + blend.a);
  41. }

那么现在的问题就是如何在编辑模式下如何实时修改那种控制图。 原理是先使用射线检测得到鼠标点击到的信息,得到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。

  1. //定义绘制的颜色
  2. Color targetColor = new Color(1f, 0f, 0f, 0f);
  3. switch (selTex) //选择绘制的贴图
  4. {
  5. case 0:
  6. targetColor = new Color(1f, 0f, 0f, 0f);
  7. break;
  8. case 1:
  9. targetColor = new Color(0f, 1f, 0f, 0f);
  10. break;
  11. case 2:
  12. targetColor = new Color(0f, 0f, 1f, 0f);
  13. break;
  14. case 3:
  15. targetColor = new Color(0f, 0f, 0f, 1f);
  16. break;
  17. }
  18. //使用笔刷在原颜色和绘制颜色中Lerp
  19. terrainBay[index] = Color.Lerp(terrainBay[index], targetColor, Stronger); //设置颜色绘制的颜色 使用Stronger在原图和绘制颜色中做Lerp

最后将新的颜色传回控制图。

MaskTex.SetPixels(x, y, width, height, terrainBay, 0);  //使用terrainBay颜色 绘制x,y位置width,height尺寸的颜色信息

剩下的就是一些UnityEditor的编辑器样式修改。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/98029
推荐阅读
相关标签
  

闽ICP备14008679号