Unity 网格编程立方体线框,包围盒,

项目需要一个可以任意大小的包围盒,有shader可以直接实现,但是注意是任意大小, 这个shader一旦进行缩放就会有拉伸, 尝试过算上缩放值,可是由于UV的不规则性,,一直无法达到满意的效果,

先把那个shader效果和代码贴出来 ,有大佬给改一下的话就感激不尽了,

正常不缩放和缩放后的效果图如下, 没有会被拉伸.

shader代码如下

Shader "JaffHan/Wireframe" {
 Properties
 {
        _Color("Color",Color)=(1.0,1.0,1.0,0.0)
        _EdgeColor("Edge Color",Color)=(0.0,0.6,1.0,1.0)
        _Width("Width",Range(0,1))=0.02
}
  SubShader {
      Tags { 
      "Queue"="Transparent" 
      "IgnoreProjector"="True" 
      "RenderType"="Transparent" 
      }
      Blend SrcAlpha OneMinusSrcAlpha
      LOD 200
      Cull Front
      zWrite off
      Pass {
      CGPROGRAM
      #pragma vertex vert
      #pragma fragment frag
      #pragma target 3.0
      #include "UnityCG.cginc"
  
      struct a2v {
          half4 uv : TEXCOORD0 ;
          half4 vertex : POSITION ;
      };
  
      struct v2f{
          half4 pos : SV_POSITION ;
          half4 uv : TEXCOORD0  ;            
      };
      fixed4 _Color;
      fixed4 _EdgeColor;
      float _Width;
      
      v2f vert(a2v v)
      {
          v2f o;
          o.uv = v.uv;
          o.pos=UnityObjectToClipPos(v.vertex);
          return o;
      }
  
  
      fixed4 frag(v2f i) : COLOR
      {
          fixed4 col;
          float lx = step(_Width, i.uv.x);
          float ly = step(_Width, i.uv.y);
          float hx = step(i.uv.x, 1.0 - _Width);
          float hy = step(i.uv.y, 1.0 - _Width);
          col = lerp(_EdgeColor, _Color, lx*ly*hx*hy);
          return col;
      }
      ENDCG
      }
      Blend SrcAlpha OneMinusSrcAlpha
      LOD 200 
      Cull Back
      zWrite off
      Pass {
      CGPROGRAM
      #pragma vertex vert
      #pragma fragment frag
      #pragma target 3.0
      #include "UnityCG.cginc"
  
      struct a2v {
          half4 uv : TEXCOORD0 ;
          half4 vertex : POSITION ;
      };
  
      struct v2f{
          half4 pos : SV_POSITION ;
          half4 uv : TEXCOORD0  ;            
      };
      fixed4 _Color;
      fixed4 _EdgeColor;
      float _Width;
      
      v2f vert(a2v v)
      {
          v2f o;
          o.uv = v.uv;
          o.pos=UnityObjectToClipPos(v.vertex);
          return o;
      }
  
  
      fixed4 frag(v2f i) : COLOR
      {
          fixed4 col;
          float lx = step(_Width, i.uv.x);
          float ly = step(_Width, i.uv.y);
          float hx = step(i.uv.x, 1.0 - _Width);
          float hy = step(i.uv.y, 1.0 - _Width);
          col = lerp(_EdgeColor, _Color, lx*ly*hx*hy);
          return col;
     }
     ENDCG
     }
 } 
     FallBack "Diffuse"
 }

由于不会改shader 写不出让自己满意的着色器,就只能用笨方法直接编网格了...留下了没有技术的泪水.

大致思路如下,先找出最大的范围,即立方体八个顶点的坐标,如下图

然后计算每个面的内四角, 由于都是直角,宽度公开出来,根据宽度算就好了,.逻辑很简单,不一一赘述,如下图是一个面的和多个面的

uv是没算的 有点懒,直接贴代码了.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WD : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
       CreateBounds(gameObject);
    }

      public  MeshRenderer CreateBounds(GameObject target)
      {
          List<Vector3> points = new List<Vector3>();
          MeshFilter[] renders = target.GetComponentsInChildren<MeshFilter>();
          foreach (MeshFilter VARIABLE in renders)
          {
              for (int i = 0; i < VARIABLE.mesh.vertices.Length; i++)
              {
                  Vector3 localScale = VARIABLE.transform.localScale;
                  var mesh = VARIABLE.mesh;
                  Vector3 realPos = new Vector3(mesh.vertices[i].x * localScale.x,
                      mesh.vertices[i].y * localScale.y,
                      mesh.vertices[i].z * localScale.z);
                  Vector3 pos = realPos + VARIABLE.transform.position;
                  if (!points.Contains(pos)) points.Add(pos);
              }
          }

          //找出xyz最大最小值
          Vector3 temp;
          Vector3 max = Vector3.one * float.MinValue;
          Vector3 min = Vector3.one * float.MaxValue;
          for (int i = 0; i < points.Count; i++)
          {
              temp = points[i];
              if (max.x < temp.x) max.x = temp.x;
              if (max.y < temp.y) max.y = temp.y;
              if (max.z < temp.z) max.z = temp.z;

              if (min.x > temp.x) min.x = temp.x;
              if (min.y > temp.y) min.y = temp.y;
              if (min.z > temp.z) min.z = temp.z;
          }

          //稍微大一点 不闪面
          min -= (Vector3.one * 0.01f);
          max += (Vector3.one * 0.01f);
          var _boxGizmos = GameObject.CreatePrimitive(PrimitiveType.Cube);

          MeshRenderer render = _boxGizmos.GetComponent<MeshRenderer>();
          // render.material = BoxSelectUtils.GetWireframeMat();
          // render.shadowCastingMode = ShadowCastingMode.Off;
          _boxGizmos.transform.position = (max + min) / 2;
          _boxGizmos.transform.localScale = max - min;
          _boxGizmos.transform.parent = target.transform;
          _boxGizmos.GetComponent<Collider>().isTrigger = true;
          CreateVectices(_boxGizmos.gameObject);
          render.enabled = false;
          CreateBoxLine();
          return render;
      }

      private List<Transform> vecticesTrans = new List<Transform>();
    private void CreateVectices(GameObject _boxGizmos)
    {
        var mesh = _boxGizmos.GetComponent<MeshFilter>().mesh;
        List<string> temp = new List<string>();
        for (int i = 0; i < mesh.vertexCount; i++)
        {
            Vector3 realpos = new Vector3(
                mesh.vertices[i].x * _boxGizmos.transform.localScale.x,
                mesh.vertices[i].y * _boxGizmos.transform.localScale.y,
                mesh.vertices[i].z * _boxGizmos.transform.localScale.z);
            string te = realpos.ToString("F4");
            if (!temp.Contains(te))
            {
                temp.Add(te);
                GameObject g = new GameObject(i.ToString());
                g.transform.position = realpos + _boxGizmos.transform.position;
               // g.transform.SetParent(_boxGizmos.transform);
                vecticesTrans.Add(g.transform);
            }
        }
    }

    public float width = 0.1f;
    void CreateBoxLine()
    {
        var points = new List<Vector3>();
        foreach (var VARIABLE in vecticesTrans)
        {
            points.Add(VARIABLE.position);
        }
        points.Add(new Vector3(points[1].x + width, points[1].y + width, points[1].z)); 
        points.Add(new Vector3(points[0].x - width, points[0].y + width, points[0].z));
        points.Add(new Vector3(points[2].x - width, points[2].y - width, points[2].z));
        points.Add(new Vector3(points[3].x + width, points[3].y - width, points[3].z));
        
        points.Add(new Vector3(points[1].x, points[1].y + width, points[1].z- width));
        points.Add(new Vector3(points[7].x, points[7].y + width, points[7].z+ width));
        points.Add(new Vector3(points[3].x, points[3].y - width, points[3].z- width));
        points.Add(new Vector3(points[5].x, points[5].y - width, points[5].z+ width));
        
        points.Add(new Vector3(points[7].x+width, points[7].y + width, points[7].z));
        points.Add(new Vector3(points[6].x-width, points[6].y + width, points[6].z));
        points.Add(new Vector3(points[5].x+width, points[5].y - width, points[5].z));
        points.Add(new Vector3(points[4].x-width, points[4].y - width, points[4].z));
        
        points.Add(new Vector3(points[6].x, points[6].y + width, points[6].z+width));
        points.Add(new Vector3(points[0].x, points[0].y + width, points[0].z-width));
        points.Add(new Vector3(points[4].x, points[4].y - width, points[4].z+width));
        points.Add(new Vector3(points[2].x, points[2].y - width, points[2].z-width));
        
        points.Add(new Vector3(points[3].x+width, points[3].y, points[3].z-width));
        points.Add(new Vector3(points[2].x-width, points[2].y, points[2].z-width));
        points.Add(new Vector3(points[5].x+width, points[5].y, points[5].z+width));
        points.Add(new Vector3(points[4].x-width, points[4].y, points[4].z+width));
        
        points.Add(new Vector3(points[0].x - width, points[0].y , points[0].z- width));
        points.Add(new Vector3(points[6].x - width, points[6].y , points[6].z+ width));
        points.Add(new Vector3(points[1].x + width, points[1].y , points[1].z- width));
        points.Add(new Vector3(points[7].x + width, points[7].y , points[7].z+ width));
        
        //测试各个顶点
        for (int i = 8; i < points.Count; i++)
        {
            GameObject g = new GameObject(i.ToString());
            g.transform.position = points[i];
        }
        List<Vector3> vertices = new List<Vector3>();
        List<Vector2> uvs = new List<Vector2>();
        List<int> triangles = new List<int>();
        Mesh mesh = new Mesh();
        vertices = points;

        #region  第一个面
        triangles.Add(0);
        triangles.Add(9);
        triangles.Add(1);
        triangles.Add(1);
        triangles.Add(9);
        triangles.Add(8);
        
        triangles.Add(0);
        triangles.Add(2);
        triangles.Add(9);
        triangles.Add(2);
        triangles.Add(10);
        triangles.Add(9);
        
        triangles.Add(2);
        triangles.Add(3);
        triangles.Add(10);
        triangles.Add(10);
        triangles.Add(3);
        triangles.Add(11);
        
        triangles.Add(1);
        triangles.Add(8);
        triangles.Add(11);
        triangles.Add(1);
        triangles.Add(11);
        triangles.Add(3);
        #endregion

        #region 第二个面
        triangles.Add(1);
        triangles.Add(12);
        triangles.Add(7);
        triangles.Add(7);
        triangles.Add(12);
        triangles.Add(13);
        
        triangles.Add(1);
        triangles.Add(3);
        triangles.Add(12);
        triangles.Add(12);
        triangles.Add(3);
        triangles.Add(14);
        
        triangles.Add(3);
        triangles.Add(5);
        triangles.Add(14);
        triangles.Add(14);
        triangles.Add(5);
        triangles.Add(15);
        
        triangles.Add(13);
        triangles.Add(5);
        triangles.Add(7);
        triangles.Add(13);
        triangles.Add(15);
        triangles.Add(5);
        #endregion

        #region  第三个面
        triangles.Add(7);
        triangles.Add(16);
        triangles.Add(6);
        triangles.Add(16);
        triangles.Add(17);
        triangles.Add(6);   
        
        triangles.Add(7);
        triangles.Add(5);
        triangles.Add(18);
        triangles.Add(7);
        triangles.Add(18);
        triangles.Add(16);
        
        triangles.Add(5);
        triangles.Add(19);
        triangles.Add(18);
        triangles.Add(5);
        triangles.Add(4);
        triangles.Add(19);
        
        triangles.Add(17);
        triangles.Add(4);   
        triangles.Add(6);   
        triangles.Add(17);
        triangles.Add(19);   
        triangles.Add(4);   
        #endregion

        #region 第四个面
        triangles.Add(6);
        triangles.Add(20);
        triangles.Add(0);
        triangles.Add(20);
        triangles.Add(21);
        triangles.Add(0);
        
        triangles.Add(6);
        triangles.Add(4);
        triangles.Add(22);
        triangles.Add(6);
        triangles.Add(22);
        triangles.Add(20);
        
        triangles.Add(4);
        triangles.Add(2);
        triangles.Add(23);
        triangles.Add(4);
        triangles.Add(23);
        triangles.Add(22);
        
        triangles.Add(21); 
        triangles.Add(23);
        triangles.Add(2);
        triangles.Add(21); 
        triangles.Add(2);
        triangles.Add(0);
        #endregion

        #region  上面
        triangles.Add(5);
        triangles.Add(3);
        triangles.Add(24);
        triangles.Add(5);
        triangles.Add(24);
        triangles.Add(26);
        
        triangles.Add(3);
        triangles.Add(2);
        triangles.Add(25);
        triangles.Add(3);
        triangles.Add(25);
        triangles.Add(24);
        
        triangles.Add(2); 
        triangles.Add(4); 
        triangles.Add(27);
        triangles.Add(2); 
        triangles.Add(27);
        triangles.Add(25); 
        
        triangles.Add(5); 
        triangles.Add(27); 
        triangles.Add(4); 
        
        triangles.Add(5); 
        triangles.Add(26); 
        triangles.Add(27); 
        #endregion

        #region 底面
        triangles.Add(0);
        triangles.Add(1);
        triangles.Add(30);
        triangles.Add(0);
        triangles.Add(30);
        triangles.Add(28);

        triangles.Add(6);
        triangles.Add(28);
        triangles.Add(29);     
        triangles.Add(6);
        triangles.Add(0);
        triangles.Add(28);
        
        triangles.Add(6);
        triangles.Add(29);
        triangles.Add(31);
        triangles.Add(6);
        triangles.Add(31);
        triangles.Add(7);
        
        triangles.Add(1);
        triangles.Add(7);
        triangles.Add(31);
        triangles.Add(1);
        triangles.Add(31);
        triangles.Add(30);
        #endregion
        mesh.vertices = vertices.ToArray();
        mesh.triangles = triangles.ToArray();
        gameObject.GetComponent<MeshFilter>().mesh = mesh;
    }

    // private void Update()
    // {
    //     if (vecticesTrans.Count==8)
    //     {
    //         CreateBoxLine();
    //     }
    // }
}

补充一点, 代码获取MeshFilter的顶点的时候,要保证模型的可读写属性不然会报错

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值