说明:我就是用到了,写了个简单的方法。本方法比较笨,但是很容易理解。可以在这个基础上优化。
一、获取Mesh顶点位置,并在顶点生成用于控制的小球
ChangMesh.cs(pointsFather是小球的父物体,随便找个空物体就行。)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeMesh : MonoBehaviour
{
public GameObject pointsFather;
private Mesh mesh;
private GameObject newPoint;
private Vector3[] vertices;
// Start is called before the first frame update
void Start()
{
pointsFather.transform.position = this.transform.position;
mesh = this.GetComponent<MeshFilter>().mesh;
vertices = new Vector3[mesh.vertices.Length];
CreatMeshPoint();
}
private void CreatMeshPoint()
{
for (int i = 0; i < mesh.vertices.Length; i++)
{
vertices[i] = mesh.vertices[i];
}
for (int i = 0; i < mesh.vertices.Length; i++)
{
GameObject creatPoint = GameObject.CreatePrimitive(PrimitiveType.Sphere);
creatPoint.transform.localPosition = vertices[i];
creatPoint.transform.name = "EditorPoint" + i.ToString();
creatPoint.transform.localScale = new Vector3(0.01f, 0.01f, 0.01f);
creatPoint.transform.parent = pointsFather.transform;
float distance = Vector3.Distance(creatPoint.transform.localPosition, Vector3.zero);
}
}
private void MovePoint()
{
for(int i=0;i<mesh.vertices.Length;i++)
{
newPoint = GameObject.Find("EditorPoint" + i.ToString());
if(newPoint.transform.position!=vertices[i])
{
vertices[i] = newPoint.transform.position;
}
}
mesh.vertices = vertices;
mesh.RecalculateTangents();
mesh.RecalculateNormals();
}
// Update is called once per frame
void Update()
{
MovePoint();
}
}
二、编写Shader
ColorChange.shader
Shader "Custom/ColorChange"
{
Properties
{
_Color("Color",Color) = (1,1,1,1)
_Height("Normal",Float) = 1
_Ambient("Ambient",Float) = 5
_Specular("Specular",Float) = 20
}
SubShader
{
Pass
{
CGPROGRAM
fixed4 _Color;
float _Height;
float _Ambient;
float _Specular;
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct a2v {/*模型到顶点*/
fixed4 vertex : POSITION;
fixed3 normal : NORMAL;
};
struct v2f {/*顶点到面*/
fixed4 pos : SV_POSITION;
fixed3 worldNormal : TEXCOORD0;
fixed3 worldPos : TEXCOORD1;
};
v2f vert(a2v v)/*顶点函数*/
{
//v.vertex.xyz += _Height * v.normal;/**/
v2f o;
v2f old;/**/
o.pos = UnityObjectToClipPos(v.vertex);/*重要的函数UnityObjectToClipPos,转换坐标*/
o.worldNormal = UnityObjectToWorldNormal(v.normal);/*重要的函数UnityObjectToWorldNormal,转换坐标*/
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
return o;
}
fixed4 frag(v2f i) :SV_Target/*片元函数*/
{
//fixed3 l = normalize(_WorldSpaceLightPos0.xyz);
//float diff = dot(i.worldNormal, 1);
//diff = diff < 0 ? 0 : diff;
fixed3 zero = fixed3(0,0,0);
float distance = sqrt(pow(i.worldPos.x - zero.x, 2) + pow(i.worldPos.y - zero.y, 2) + pow(i.worldPos.z - zero.z, 2));
float standardV = 0.5;
//fixed3 cameraPos = _WorldSpaceCameraPos.xyz;
//fixed3 v = normalize(i.worldPos- cameraPos);
//fixed4 position = fixed4(v * 2, 1);
fixed4 position0 = fixed4(1, 1, 0, 1);
//fixed4 position1 = fixed4(1, 0, 0, 1);
//fixed4 position2 = fixed4(1, 0.647, 0, 1);
//fixed4 position3 = fixed4(1, 1, 0.5, 1);
//fixed4 position4 = fixed4(0, 1, 0, 1);
//fixed4 position5 = fixed4(0, 0.675, 1, 1);
//fixed4 position6 = fixed4(0, 0, 1, 1);
//fixed4 position7 = fixed4(0.545, 0, 1, 1);
fixed4 position1 = fixed4(1, 0.9, 0, 1);
fixed4 position2 = fixed4(1, 0.8, 0, 1);
fixed4 position3 = fixed4(1, 0.7, 0, 1);
fixed4 position4 = fixed4(1, 0.6, 0, 1);
fixed4 position5 = fixed4(1, 0.5, 0, 1);
fixed4 position6 = fixed4(1, 0.4, 0, 1);
fixed4 position7 = fixed4(1, 0.3, 0, 1);
fixed4 position8 = fixed4(1, 0.2, 0, 1);
fixed4 position9 = fixed4(1, 0.1, 0, 1);
fixed4 position10 = fixed4(1, 0, 0, 1);
fixed4 position11 = fixed4(0, 1, 0, 1);
if (distance-standardV > 0.01&&distance - standardV < 0.02)
{
return position1;
}
else if(distance - standardV > 0.02&&distance - standardV < 0.03)
{
return position2;
}
else if (distance - standardV > 0.03&&distance - standardV < 0.04)
{
return position3;
}
else if (distance - standardV > 0.04&&distance - standardV < 0.05)
{
return position4;
}
else if (distance - standardV > 0.05&&distance - standardV < 0.06)
{
return position5;
}
else if (distance - standardV > 0.06&&distance - standardV < 0.07)
{
return position6;
}
else if (distance - standardV > 0.07&&distance - standardV < 0.08)
{
return position7;
}
else if (distance - standardV > 0.08&&distance - standardV < 0.09)
{
return position8;
}
else if (distance - standardV > 0.09&&distance - standardV < 0.10)
{
return position9;
}
else if (distance - standardV >= 0.10)
{
return position10;
}
else if (distance - standardV < 0.01)
{
return position11;
}
else
{
return position0;
}
//return position;
}
ENDCG
}
}
FallBack "Diffuse"
}
这次只是实现一个简单的功能,没有考虑很多,后续会对算法等进行优化。