模型粒子化效果

作者:追风剑情 发布于:2020-12-30 16:09 分类:Unity3d

参考 https://www.163.com/dy/article/EVNITUM10526E124.html

工程类型:High Definition RP

工程截图

1111.png

2222.png

脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.VFX;

/// <summary>
/// 对模型粒子化
/// </summary>
public class ParticleAvatar : MonoBehaviour
{
    public GameObject VFX;
    private GameObject VFXInstance;
    private Texture2D pointCache;
    private float size;

    void Start()
    {
        CreateVFX();
        StartCoroutine(OnVFXLoop());
    }

    IEnumerator OnVFXLoop()
    {
        yield return null;
        while (true)
        {
            this.UpdateSize(gameObject);
            this.UpdateCachePoint(gameObject);
            this.VFXInstance.GetComponent<VisualEffect>().SetTexture("PointCache", this.pointCache);
            this.VFXInstance.GetComponent<VisualEffect>().SetFloat("Size", this.size);
            yield return new WaitForEndOfFrame();
        }
    }

    void CreateVFX()
    {
        this.VFXInstance = Instantiate(this.VFX);
        this.VFXInstance.transform.position = transform.position;
        this.VFXInstance.transform.rotation = transform.rotation;
    }

    void UpdateSize(GameObject character)
    {
        SkinnedMeshRenderer[] renderers = character.GetComponentsInChildren<SkinnedMeshRenderer>();
        Bounds bound = new Bounds();
        foreach (SkinnedMeshRenderer renderer in renderers)
        {
            Mesh baked = new Mesh();
            renderer.BakeMesh(baked);
            bound.Encapsulate(baked.bounds);

        }
        this.size = Mathf.Max(bound.extents.x * 2, bound.extents.y * 2, bound.extents.z * 2);
    }

    void UpdateCachePoint(GameObject character)
    {
        Mesh baked;
        Vector3[] vertices;
        Transform parent;
        SkinnedMeshRenderer[] renderers = character.GetComponentsInChildren<SkinnedMeshRenderer>();
        List<Color> normalizedVertices = new List<Color>();
        foreach (SkinnedMeshRenderer renderer in renderers)
        {
            parent = renderer.gameObject.transform.parent;
            baked = new Mesh();
            renderer.BakeMesh(baked);
            vertices = baked.vertices;
            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i] = (character.gameObject.transform.InverseTransformPoint(renderer.gameObject.transform.TransformPoint(vertices[i])) + new Vector3(size * 0.5f, 0, size * 0.5f)) / size;
                normalizedVertices.Add(new Color(vertices[i].x, vertices[i].y, vertices[i].z));
            }
        }
        if (this.pointCache == null || this.pointCache.width != normalizedVertices.Count)
        {
            this.pointCache = new Texture2D(1, normalizedVertices.Count, TextureFormat.RGBA32, false, true);
            this.pointCache.filterMode = FilterMode.Point;
        }
        this.pointCache.SetPixels(normalizedVertices.ToArray());
        this.pointCache.Apply();
    }
}

运行效果

未隐藏模型时的效果

3337.gif

隐藏模型的效果

3339.gif

标签: Unity3d

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号