154 lines
5.0 KiB
C#
Raw Normal View History

2025-09-08 17:37:12 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
//[ExecuteAlways]
public class RongMao : MonoBehaviour
{
public int Count = 0;
//public Shader shader;
[Header("渲染目标")]
public 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;
//public float FurTenacity=1.0f;
private GameObject[] layers;
// private Material mat;
// Start is called before the first frame update
void Start()
{
var t=Target.GetType();
Debug.Log(t.Name);
CreateFur();
}
// Update is called once per frame
void Update()
{
//if(Count==0) return;
//UpadteTransform();
//UpdateMat();
}
//更新每层毛发的位置
void UpadteTransform()
{
if (layers == null || layers.Length == 0)
{
return;
}
for (int i = 0; i < layers.Length; i++)
{
//依据层数、毛发长度和毛发硬度计算lerp速度
//float lerpSpeed = (layers.Length-i) * (1.0f / layers.Length)* FurTenacity;
//让Shell的位置和旋转Lerp到目标模型
//后面乘的常数完全是试出来的参数……没有具体物理解释,移动时毛发更新
//layers[i].gameObject.transform.position = Vector3.Lerp(layers[i].gameObject.transform.position, Target.transform.position, lerpSpeed * Time.deltaTime *20);
//layers[i].gameObject.transform.rotation = Quaternion.Lerp(layers[i].gameObject.transform.rotation, Target.transform.rotation, lerpSpeed * Time.deltaTime *10);
}
}
void UpdateMat()
{
float furOffset = 1.0f / LayerCount;
for (int i = 0; i < layers.Length; i++)
{
Material layerMat = layers[i].GetComponent<Renderer>().material;
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.SetTexture("_ValueMask",ValueMask);
layerMat.SetColor("_ShadowColor",ShadowColor);
Shader.SetGlobalFloat("_ShadowStrength",ShadowStrength);
layerMat.SetFloat("_LayerOffset",i*furOffset);
layerMat.SetFloat("_R",R);
//layerMat.SetFloat("_LengthMut",_LengthMut);
Shader.SetGlobalFloat("_LengthMut",_LengthMut);
}
}
//创建毛发
void CreateFur()
{
layers = new GameObject[LayerCount];
float furOffset = 1.0f / LayerCount;
for (int i = 0; i < LayerCount; i++)
{
GameObject layer = Instantiate(Target.gameObject, Target.transform.position, Target.transform.rotation, Target.transform.parent);
//layer.transform.position=new Vector3(layer.transform.position.x,layer.transform.position.y-i*0.0004f,layer.transform.position.z-i*0.0004f);
//layer.hideFlags = HideFlags.HideInHierarchy;
Material 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.SetTexture("_ValueMask",ValueMask);
layerMat.SetColor("_ShadowColor",ShadowColor);
// layerMat.SetFloat("_ShadowStrength",ShadowStrength);
layerMat.SetFloat("_LayerOffset",i*furOffset);
layerMat.SetFloat("_R",R);
//layerMat.SetVector("_FurOffset",FurFore*Mathf.Pow(i*furOffset,FurTenacity)*0.0f);
//Graphics.DrawMesh();
layerMat.renderQueue = 3000 + i+Count*LayerCount;
layer.GetComponent<Renderer>().material=layerMat;
layers[i] = layer;
}
}
//删除创建的游戏毛发
private void OnDestroy()
{
// if (layers == null || layers.length == 0)
// {
// return;
// }
//
// for (int i = 0; i < layers.length; i++)
// {
// destroy(layers[i].gameobject);
// }
}
}