3D Surface Plotter  1.0.0
Create 3D Surface Charts for Any Math Function
Demo: Custom Math Function from User

The true power of the Surface3DLib library is its ability to create 3D surface plots using custom math functions provided by the user. The custom math function required by this library should have the following signature:

Vector3 MyFunction(float x, float y); // Myfunction(float, float)

In this demo, we will show you how to define a custom math function and how to use it to create a 3D surface plot. The custom math functions will have the same access as the built-in math functions do to the functionalities and features provided by the Surface3DLib library, including vertex, UV, and colormap data, etc.

Set Up the Scene

From the 3D Surface Plotter/Scenes folder, double-click on the scene called UserFunction to bring up the demo.

The 3D user-function surface plot with the default jet colormap is displayed in the Scene view window. From the Hierarchy window, you can see that this scene contains only one GameObject named Surface. Click on the Surface to bring up the Inspector for it. From the Inspector, you can check the surface's properties. The material is specified using Surface3DMaterial. The surface is also attached to a C# script called UserFunction.cs, which exposes several properties that allow you to manipulate the plot and animation.

C# Script

let's examine the C# script file used in this demo. From the 3D Surface Plotter/Scripts folder, double-click on the UserFunction.cs file. Here is the code list for this file:

using System;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshFilter))]
[ExecuteInEditMode]
[Serializable]
public class UserFunction : MonoBehaviour
{
public ColormapEnum Colormaps = ColormapEnum.jet;
public bool ColormapReverse = false;
[Range(1f, 10f)]
public float Size = 2f;
[Range(0.2f, 10f)]
public float Scaling = 1f;
[Range(0f, 1f)]
public float AspectRatio = 0.3f;
public bool IsAnimation = false;
public float AnimationSpeed = 1f;
Mesh mesh;
private SurfaceData.VertexData data;
private float a = 1f;
private float b = 1f;
Vector3 MyFunction(float x, float z)
{
var y = Mathf.Sin(a * x + b * z * z);
return new Vector3(x, y, z);
}
void Start()
{
mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
CreateSurface();
}
void Update()
{
#if UNITY_EDITOR
if (!Application.isPlaying)
{
bool needsUpdate = mesh == null ||
UnityEditor.Selection.activeGameObject == gameObject;
if (needsUpdate)
{
CreateSurface();
var mf = GetComponent<MeshFilter>();
mf.sharedMesh = mesh;
}
}
#endif
if (Application.isPlaying)
{
if (IsAnimation)
{
var aa = Time.fixedTime * AnimationSpeed;
a = 2f * (1.0f + Mathf.Sin(aa));
b = 2f * (1.0f + Mathf.Cos(aa));
CreateSurface();
}
else
{
a = 1f;
b = 1f;
CreateSurface();
}
}
}
void CreateSurface()
{
SurfaceData.ColormapName = Colormaps;
SurfaceData.Scale = Scaling;
SurfaceData.Aspect = AspectRatio;
SurfaceData.ColormapReverse = ColormapReverse;
SurfaceData.UseCustomColormap = false;
data = SurfaceData.CreateData(MyFunction, -1.5f * Size, 1.5f * Size, -Size, Size);
mesh.Clear();
mesh.vertices = data.Vertices;
mesh.colors = data.Colors;
mesh.triangles = data.Triangles;
mesh.RecalculateNormals();
}
}
A static class SurfaceData.
Definition: SurfaceData.cs:12
static VertexData CreateData(Func< float, float, Vector3 > f, float XMin, float XMax, float ZMin, float ZMax)
This method generates the surface data.
Definition: SurfaceData.cs:120
Definition: Colormap.cs:7
ColormapEnum
ColormapEnum enumeration.
Definition: Colormap.cs:1015
VertexData struct.
Definition: SurfaceData.cs:256
Color[] Colors
colormap data
Definition: SurfaceData.cs:264
int[] Triangles
triangle (or index) data
Definition: SurfaceData.cs:272
Vector3[] Vertices
vertex data
Definition: SurfaceData.cs:260

Here, we define the custom math function with the following code snippet:

private float a = 1f;
private float b = 1f;
Vector3 MyFunction(float x, float z)
{
var y = Mathf.Sin(a * x + b * z * z);
return new Vector3(x, y, z);
}

Here, we pass two parameters a and b to our custom math function because we want to animate these two parameters when creating our 3D surface plot.

Inside the Update method, we define the animation parameter aa using the Unity public property Time.fixedTime that gives the time in seconds since the start of the game. We then define our parameters a and b in terms of this animation parameter aa:

if (IsAnimation)
{
var aa = Time.fixedTime * AnimationSpeed;
a = 2f * (1.0f + Mathf.Sin(aa));
b = 2f * (1.0f + Mathf.Cos(aa));
CreateSurface();
}

This way, the surface plot created using the custom math function will animate continuously.

Inside the CreateSurface method, we create the vertex, colormap, uv, and triangle data by passing our custom math function to the SurfaceData.CreateData method:

data = SurfaceData.CreateData(MyFunction, -1.5f * Size, 1.5f * Size, -Size, Size);

The rest of the code for this demo is the same as that used in creating 3D surface plots with the built-in math functions.

Start Play Mode

Now, let's start the Play mode by clicking on the Play button. You will get the surface plot created using our custom math function with the default jet colormap. From the Inspector, Check the Is Animation box, the animation will start. During animation, you can also change the other properties such as colormap, as shown in the following image:

By following the procedure described here, you can easily create your own 3D surface plots by defining any math functions.