using System; using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; using UnityEngine.Rendering; //[ExecuteAlways] public class RongMaoSkinMesh : MonoBehaviour { public int Count = 0; //public Shader shader; [Header("渲染目标")] [SerializeField] private Renderer Target; public Shader BaseShader; [Header("皮毛物理")] public int LayerCount = 10; public float FurLength = 0.5f; public Vector3 FurFore; public Texture2D Noise; public Texture2D Noise2; public Texture2D MainTex;//毛发颜色 public Texture2D Mask;//不产生毛发区域的灰度遮罩 [Header("皮毛渲染")] //毛发染色 public Color FurColor=Color.white; public Color ShadowColor=Color.white; [Range(0,1)]public float ShadowStrength = 0.3f; [Range(0.01f, 1)] public float R = 0.5f; [Range(0, 3)] public float _LengthMut = 1; [Header("是否使用GPU实例化")] public bool isInStance = false; private bool skinHasValue = false; private Renderer target; //创建毛发 private Mesh mesh; private Material layerMat; private SkinnedMeshRenderer skinnedMeshRenderer; private MaterialPropertyBlock mpb; private ComputeBuffer instanceBuffer; private Matrix4x4[] instanceMatrices; private bool isInit; void OnEnable() { isInit = Init(); } //更新毛发渲染 void LateUpdate() { //目标为空就不渲染 if(TargetChange()==false) return; if(isInStance) UpDateInstance(); else UpDateMesh(); } bool TargetChange() { if (Target != target) { target = Target; isInit = Init(); } return isInit; } //初始化毛发,返回是否初始化成功 bool Init() { if(target.IsUnityNull()) return false; CreateFur(); MeshInstancedData(); if (target.GetType() == typeof(MeshRenderer)) { mesh=target.GetComponent().sharedMesh; skinHasValue = false; } else { skinnedMeshRenderer = target.gameObject.GetComponent(); skinHasValue = true; } return true; } //初始化网格、材质、SkinnedMeshRenderer void CreateFur() { mesh = new Mesh(); layerMat =new Material(BaseShader); layerMat.SetTexture("_MainTex",MainTex); layerMat.SetColor("_Color",FurColor); layerMat.SetFloat("_FurLength",FurLength); layerMat.SetTexture("_Noise",Noise); layerMat.SetTexture("_Noise2",Noise2); layerMat.SetTexture("_Mask",Mask); layerMat.SetColor("_ShadowColor",ShadowColor); layerMat.SetFloat("_R",R); layerMat.SetFloat("_LayerCount",LayerCount); layerMat.renderQueue = 3000; mpb = new MaterialPropertyBlock(); } void MeshInstancedData() { instanceMatrices = new Matrix4x4[LayerCount]; layerMat.enableInstancing = true; // 随机生成实例的位置和旋转 for (int i = 0; i < LayerCount; i++) { Vector3 position = target.transform.position; Quaternion rotation = target.transform.rotation; Vector3 scale = Vector3.one; instanceMatrices[i] = Matrix4x4.TRS(position, rotation, scale); } } //使用GPU实例化 void UpDateInstance() { if (skinHasValue) { skinnedMeshRenderer.BakeMesh(mesh); } layerMat.EnableKeyword("INSTANCE"); Graphics.DrawMeshInstanced(mesh,0,layerMat,instanceMatrices,LayerCount); } //未使用GPU实例化 void UpDateMesh() { if (skinHasValue) { skinnedMeshRenderer.BakeMesh(mesh); } layerMat.DisableKeyword("INSTANCE"); float furOffset = 1.0f / LayerCount; for (int i = 0; i < LayerCount; i++) { mpb.SetFloat("_LayerOffset",i*furOffset); Graphics.DrawMesh(mesh,target.transform.localToWorldMatrix,layerMat,0,Camera.main,0,mpb); } } }