Unity uses Perlin noise to implement random deformation elegantly

Elegant implementation of random deformations using perlin noise

First look at the renderings:

This is the rendering

poor implementation

At the beginning, I didn’t know that there was such a magical thing as Berlin noise. When our art supervisor showed me this effect with his PPT, I really didn’t know how to realize it. I built a model - an irregular sphere, like a potato. Then, I let the potato keep rotating, then wrote a solid color shader for him, and finally used a camera to render it, barely A picture with similar effect was obtained. Of course, I also feel that this kind of implementation is not very elegant, but there is no way, the project is in a hurry, no matter whether it is elegant or not, it is finally realized. .

magic perlin noise

Later, by accident, I came into contact with such a magical thing as Berlin noise! !
First use my own understanding to explain what is Perlin noise:

In fact, it is a way to obtain random numbers. It is different from Random in that the random values ​​of Random are irrelevant and non-continuous, but Perlin noise is different. The random value of Perlin noise is continuous. For example, one-dimensional Perlin noise is like the time As the temperature changes due to change, the temperature value changes continuously and cannot be abruptly changed. The smaller the time interval, the smaller the temperature difference. Perlin noise can simulate such natural changes.

Perlin noise in unity is 2-dimensional, you can give an x ​​value, a y value, and get the corresponding noise value (one-dimensional Perlin noise can be regarded as a special case of y=0 in 2-dimensional noise).

Implementation ideas

On the Perlin noise map, obtain the Perlin noise value of n points on the circle, use this value as the radius, draw a circle on the canvas, and then move the circle on the Perlin noise map to obtain a circle with a continuously changing radius.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ShapeOnGUI : MaskableGraphic
{
    
    
    public int Detail = 60;
    public float Radius = 200;
    public float Diff = 100;
    public float DataOffset = 100;

    private Vector2 _offset;
    protected override void OnPopulateMesh(VertexHelper vh)
    {
    
    
        vh.Clear();
        vh.AddVert(Vector3.zero, color, Vector4.zero);
        
        var deltaAngle = Mathf.PI * 2.0f / Detail;
        var len = Detail - 1;
        for (var i = 0; i < Detail; ++i)
        {
    
    
            var angle = deltaAngle * i;
            var r = Radius + Mathf.PerlinNoise(_offset.x + DataOffset + Mathf.Cos(angle), _offset.y + DataOffset + Mathf.Sin(angle)) * Diff;
            vh.AddVert(new Vector3(r * Mathf.Cos(angle), r * Mathf.Sin(angle), 0), color, Vector4.zero );
            if( i == len )
                vh.AddTriangle( 0, i + 1, 1 );
            else
                vh.AddTriangle(0, i + 1, i + 2);
        }
    }

    protected override void Start()
    {
    
    
        base.Start();
        StartCoroutine(OnUpdate());
    }

    protected override void OnDisable()
    {
    
    
        StopAllCoroutines();
        base.OnDisable();
    }

    private IEnumerator OnUpdate()
    {
    
    
        while (gameObject.activeSelf)
        {
    
    
            _offset += Vector2.right * 0.01f;
            //SetAllDirty();
            SetVerticesDirty();
            yield return null;
        }
    }
}

Guess you like

Origin blog.csdn.net/sdhexu/article/details/127365297