Das handbemalte Unity-Mesh sorgt für einen Farbverlauf

 Die Anforderungen, die ich erhalten habe, sind wie folgt:

Bitte sehen Sie sich die endgültigen Renderings an

Lasst uns beginnen 

Die Vereinfachung der Anforderung besteht darin, ein Netz mit einer Breite*2 und einem Farbverlauf basierend auf 2 Punkten zu erstellen.

Für die Erstellung eines quadratischen Netzes sind vier Punkte erforderlich, und was ich hier benötige, sind nur zwei, daher betrachte ich die beiden Punkte als Mittelpunkte und verwende eine Breite, um die vier Punkte zu erhalten, die hier vorliegen.

                Vector3 pos1 = nextDrawnMesh.transform.position + new Vector3(-width, 0, 0);
                Vector3 pos2 = nextDrawnMesh.transform.position + new Vector3(width, 0, 0);
                Vector3 pos3 = currentDrawnMesh.transform.position + new Vector3(width, 0, 0);
                Vector3 pos4 = currentDrawnMesh.transform.position + new Vector3(-width, 0, 0);

Sie können sehen, dass es sich um einen Vector3 handelt, sodass dieser Wert unterschiedliche Richtungen hat, wenn er an verschiedenen Positionen angebracht wird. Sie können es selbst testen, um den gewünschten Effekt zu erzielen.

Oder Sie können selbst vier Punkte definieren und Werte ohne die Berechnung hier selbst zuweisen.

Es gibt also eine Methode addpos, mit der alle Punkte hinzugefügt werden. Addpos entspricht dem Hinzufügen von Punkten. Name entspricht dem Hinzufügen von Farbe addcolor.

                currentDrawnMesh.SetShaderColor("_ColorTop", color);
                currentDrawnMesh.SetShaderColor("_ColorMid", color);
                nextDrawnMesh.SetShaderColor("_ColorBot", color);

Sie müssen nicht verstehen, dass diese drei Dinge die Attribute des Shaders sind. Die Shader-Felder kommen hierher, was eine Falle ist. Dieser Attributname ist nicht der Name des Attributs im Shader-Code. Um die Attribute in festzulegen Shader, Sie müssen sich den Shader genau ansehen. Entsprechen Sie jedem Attributnamen unter dem Bedienfeld. Ich habe es am Anfang falsch verstanden. Ich kann den Namen im Code nicht ändern, wenn ich zum Shader gehe!

public class ProtractMeshController : MonoBehaviour
{
    public static ProtractMeshController interest;
    public float width = 0.002f;
    public GameObject MeshPosObj;
    public Color color;
    private void Awake()
    {
        interest = this;
        InitProtractMeshPos();
        widthRecording = width;
    }

    float widthRecording ;

    public void Update()
    {
        if(widthRecording!= width)
        {
            widthRecording = width;
            InitProtractMeshPos();
        }
    }

    public void AddPos(List<GameObject> pos){
 
        for(int  i=0;i< pos.Count; i++)
        {
            GameObject go = GameObject.Instantiate(MeshPosObj, pos[i].transform.position,Quaternion.identity);
            go.transform.parent = this.transform;
        }

        InitProtractMeshPos();
    }

    public void AddColor(List<Color32> colors)
    {
        if (this.transform.childCount <= 0) return;

        for (int i = 0; i < colors.Count; i++)
        {
            if (i + 1 < colors.Count)
            {
                DrawnMesh currentDrawnMesh = transform.GetChild(i).GetComponent<DrawnMesh>();
                DrawnMesh nextDrawnMesh = transform.GetChild(i + 1).GetComponent<DrawnMesh>();
                currentDrawnMesh.SetShaderColor("_ColorTop", colors[i + 1]);
                currentDrawnMesh.SetShaderColor("_ColorMid", colors[i + 1]);
                currentDrawnMesh.SetShaderColor("_ColorBot", colors[i]);
            }
        }
    }

    /// <summary>
    /// 初始化mesh点位
    /// </summary>
    public void InitProtractMeshPos()
    {
        for (int i = 0; i < transform.childCount; i++)
        {
            if (i + 1 < transform.childCount)
            {
                DrawnMesh currentDrawnMesh = transform.GetChild(i).GetComponent<DrawnMesh>();
                DrawnMesh nextDrawnMesh = transform.GetChild(i + 1).GetComponent<DrawnMesh>();
                Vector3 pos1 = nextDrawnMesh.transform.position + new Vector3(-width, 0, 0);
                Vector3 pos2 = nextDrawnMesh.transform.position + new Vector3(width, 0, 0);
                Vector3 pos3 = currentDrawnMesh.transform.position + new Vector3(width, 0, 0);
                Vector3 pos4 = currentDrawnMesh.transform.position + new Vector3(-width, 0, 0);
                currentDrawnMesh.posList = new List<Vector3>() { pos4, pos3, pos2, pos1 };
                currentDrawnMesh.SetMesh();
                currentDrawnMesh.SetShaderColor("_ColorTop", color);
                currentDrawnMesh.SetShaderColor("_ColorMid", color);
                nextDrawnMesh.SetShaderColor("_ColorBot", color);
            }
        }
    }

    public void Clean()
    {
        for(int i = transform.childCount; i> 0; i--)
        {
            GameObject.Destroy(transform.GetChild(i - 1).gameObject);
        }
    }
}

 Das zeichnet Mesh! Achten Sie darauf, dem von Ihnen gezeichneten Netz UV-Strahlen hinzuzufügen, da das Material sonst falsch aussieht!

public class DrawnMesh : MonoBehaviour
{
    public float proportion = 1f;
    public List<Vector3> posList = new List<Vector3>();//赋值顺序为顺时针或者逆时针(为世界坐标位置)
    public MeshRenderer meshRenderer;


    public GameObject ga;
    void Awake()
    {
        meshRenderer = GetComponent<MeshRenderer>();
    }

    /// <summary>
    /// 设置shader的颜色属性
    /// </summary>
    /// <param name="attributeName"> 三种 "_ColorTop","_ColorMid","_ColorBot" </param>
    /// <param name="color"></param>
    public void SetShaderColor(string attributeName, Color color)
    {
        meshRenderer.materials[0].SetColor(attributeName, color);
    }

    public void SetMiddle(float value)
    {
        meshRenderer.materials[0].SetFloat("_Middle", value);
    }

    public void SetMesh()
    {
        List<Vector3> vertices = new List<Vector3>();
        for (int i = 0; i < posList.Count; i++)
        {
            Vector3 pos = (posList[i] - transform.position) * proportion;
            vertices.Add(pos);
        }

        DrawPentagon(vertices);
    }

    void DrawPentagon(List<Vector3> vertices)
    {
        Mesh mesh = new Mesh();
        mesh.name = gameObject.name;
        int triangleAmount = vertices.Count - 2;
        int[] triangles = new int[3 * triangleAmount];

        //根据三角形的个数,来计算绘制三角形的顶点顺序(索引)  
        //顺序必须为顺时针或者逆时针  
        for (int i = 0; i < triangleAmount; i++)
        {
            triangles[3 * i] = 0;
            triangles[3 * i + 1] = i + 1;
            triangles[3 * i + 2] = i + 2;
        }

        Vector2[] baseUVs = new Vector2[] { new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1), };

        mesh.vertices = vertices.ToArray();
        mesh.uv = baseUVs;
        mesh.triangles = triangles;

        GetComponent<MeshFilter>().mesh = mesh;
    }
}

 Dies ist der Shader für Farbkollisionen.

Shader "Unlit/Gradient"
{
	Properties
	{
		[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
		_ColorTop("Top Color", Color) = (1, 1, 1, 1)
		_ColorMid("Mid Color", Color) = (1, 1, 1, 1)
		_ColorBot("Bot Color", Color) = (1, 1, 1, 1)
		_Middle("Middle", Range(0.001, 0.999)) = 1
		_test("Test", Range(0.001, 0.999)) = 1
	}
		SubShader
		{
		Tags {"Queue" = "Background"  "IgnoreProjector" = "True"}
		LOD 100
		ZWrite On
		Pass
		{
		CGPROGRAM
#pragma vertex vert  
#pragma fragment frag
#include "UnityCG.cginc"
		fixed4 _ColorTop;
	fixed4 _ColorMid;
	fixed4 _ColorBot;
	float  _Middle;
	float _test;
	struct v2f
	{
		float4 pos : SV_POSITION;
		float4 texcoord : TEXCOORD0;
	};
	v2f vert(appdata_full v)
	{
		v2f o;
		if (v.vertex.y > _test)
		{
			v.vertex.y = _test;
	}
		o.pos = UnityObjectToClipPos(v.vertex);
	o.texcoord = v.texcoord;
	return o;
	}
		fixed4 frag(v2f i) : COLOR
	{
		fixed4 c = lerp(_ColorBot, _ColorMid, i.texcoord.y / _Middle) * step(i.texcoord.y, _Middle);
	c += lerp(_ColorMid, _ColorTop, (i.texcoord.y - _Middle) / (1 - _Middle)) * step(_Middle, i.texcoord.y);
	c.a = 1;
	return c;
	}
		ENDCG
		}
		}
}

Supongo que te gusta

Origin blog.csdn.net/weixin_52599679/article/details/134304174
Recomendado
Clasificación