比较提交

...

2 次代码提交

共有 36 个文件被更改,包括 1474 次插入0 次删除
  1. 9
      Editor/VolumeEditor.meta
  2. 9
      Editor/VolumeEditor/Editor.meta
  3. 9
      Editor/VolumeEditor/Editor/Renderers.meta
  4. 9
      Editor/VolumeEditor/Editor/Shaders.meta
  5. 81
      Editor/VolumeEditor/Editor/Shaders/SkyGray.shader
  6. 9
      Editor/VolumeEditor/Editor/Shaders/SkyGray.shader.meta
  7. 152
      Editor/VolumeEditor/Editor/Shaders/VolumeCloud.shader
  8. 9
      Editor/VolumeEditor/Editor/Shaders/VolumeCloud.shader.meta
  9. 90
      Editor/VolumeEditor/Editor/Shaders/VolumeTrailRenderer.shader
  10. 9
      Editor/VolumeEditor/Editor/Shaders/VolumeTrailRenderer.shader.meta
  11. 9
      Editor/VolumeEditor/Editor/Textures.meta
  12. 1
      Editor/VolumeEditor/Editor/Textures/heatmap.tga
  13. 76
      Editor/VolumeEditor/Editor/Textures/heatmap.tga.meta
  14. 3
      Editor/VolumeEditor/Editor/Textures/heatmap2.tga
  15. 76
      Editor/VolumeEditor/Editor/Textures/heatmap2.tga.meta
  16. 9
      Editor/VolumeEditor/Editor/Utility.meta
  17. 54
      Editor/VolumeEditor/Editor/Utility/VFFileImporter.cs
  18. 12
      Editor/VolumeEditor/Editor/Utility/VFFileImporter.cs.meta
  19. 90
      Editor/VolumeEditor/Editor/VolumeEditor.cs
  20. 12
      Editor/VolumeEditor/Editor/VolumeEditor.cs.meta
  21. 193
      Editor/VolumeEditor/Editor/VolumeEditorPreview.cs
  22. 12
      Editor/VolumeEditor/Editor/VolumeEditorPreview.cs.meta
  23. 107
      Editor/VolumeEditor/Editor/Renderers/DensityVolumeRenderer.cs
  24. 12
      Editor/VolumeEditor/Editor/Renderers/DensityVolumeRenderer.cs.meta
  25. 38
      Editor/VolumeEditor/Editor/Renderers/DummyRenderer.cs
  26. 12
      Editor/VolumeEditor/Editor/Renderers/DummyRenderer.cs.meta
  27. 12
      Editor/VolumeEditor/Editor/Renderers/VectorFieldVolumeRenderer.cs.meta
  28. 65
      Editor/VolumeEditor/Editor/Renderers/VolumeRendererBase.cs
  29. 12
      Editor/VolumeEditor/Editor/Renderers/VolumeRendererBase.cs.meta
  30. 283
      Editor/VolumeEditor/Editor/Renderers/VectorFieldVolumeRenderer.cs

9
Editor/VolumeEditor.meta


fileFormatVersion: 2
guid: cf23ee951dff48b48807aa7fa5f5ff1d
folderAsset: yes
timeCreated: 1472024712
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Editor/VolumeEditor/Editor.meta


fileFormatVersion: 2
guid: ff4f39c45913ce94d871a2337cd113b0
folderAsset: yes
timeCreated: 1472024745
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Editor/VolumeEditor/Editor/Renderers.meta


fileFormatVersion: 2
guid: eea6aa7334b932c48b2fc0ee8ea1d8ab
folderAsset: yes
timeCreated: 1472116146
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Editor/VolumeEditor/Editor/Shaders.meta


fileFormatVersion: 2
guid: 46674dd149e852e43a2d1defd60c03d7
folderAsset: yes
timeCreated: 1472032874
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

81
Editor/VolumeEditor/Editor/Shaders/SkyGray.shader


Shader "Hidden/VFXToolbox/Skybox/Gradient"
{
Properties
{
_BottomColor("BottomColor", Color) = (0.2,0.2,0.2,1.0)
_MiddleColor("MiddleColor", Color) = (0.5,0.5,0.5,1.0)
_TopColor("TopColor", Color) = (0.2,0.2,0.2,1.0)
_VerticalFalloff("Vertical Falloff", range(0.5,4.0)) = 1.0
_DitherIntensity("Dither Intensity", range(0.0,0.5)) = 0.01
}
SubShader
{
Tags { "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" }
Cull Off ZWrite Off
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
half3 rayDir : TEXCOORD1; // Vector for incoming ray, normalized ( == -eyeRay )
float4 ScreenPos : TEXCOORD2;
};
float4 _TopColor;
float4 _MiddleColor;
float4 _BottomColor;
float _VerticalFalloff;
float _DitherIntensity;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
// Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere)
float3 eyeRay = normalize(mul((float3x3)unity_ObjectToWorld, v.vertex.xyz));
o.rayDir = half3(-eyeRay);
o.ScreenPos = ComputeScreenPos(o.vertex);
return o;
}
float dither4x4(float2 position)
{
const float kernel[16] = {0.0625, 0.5625, 0.1875, 0.6875, 0.8125, 0.3125, 0.9375, 0.4375, 0.25, 0.75, 0.125, 0.625, 1.0, 0.5, 0.875, 0.375};
float v = kernel[(((int)position.y & 3) << 2) + ((int)position.x & 3)];
return v;
}
fixed4 frag (v2f i) : SV_Target
{
//float2 wcoord = (i.ScreenPos.xy/i.ScreenPos.w);
float dither = _DitherIntensity*(dither4x4(i.ScreenPos.xy) - 0.5f);
float a = -i.rayDir.y;
float4 up = lerp(_MiddleColor, _TopColor, pow(saturate(a),_VerticalFalloff + dither));
float4 down = lerp(_MiddleColor, _BottomColor, pow(saturate(-a),_VerticalFalloff + dither));
fixed4 col;
if (a >= 0.0f) col = up;
else col = down;
return col;
}
ENDCG
}
}
}

9
Editor/VolumeEditor/Editor/Shaders/SkyGray.shader.meta


fileFormatVersion: 2
guid: aebcf7aaf8bc7354d88b64df85d4dd3e
timeCreated: 1472719174
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

152
Editor/VolumeEditor/Editor/Shaders/VolumeCloud.shader


// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
Shader "Hidden/VFXToolbox/VolumeEditor/VolumeCloud"
{
Properties
{
_Volume ("_Volume", 3D) = "white" {}
_CameraWorldPosition("_CameraWorldPosition", Vector) = (1,1,1,1)
_LightDirection ("_LightDirection", Vector) = (0,-1,0,1)
_DensityScale ("_DensityScale", Float) = 0.1
_ScatteringScale ("_ScatteringScale", Float) = 1.0
_EditorTime("_EditorTime", Float) = 0.0
}
SubShader
{
Tags{"RenderType" = "Transparent" "Queue" = "Transparent"}
LOD 100
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Cull Back
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#define NB_VOLUME_SAMPLES 64
#define NB_LIGHT_SAMPLES 64
#define DISPLAY_NB_SAMPLES 0
#define DITHER_NOISE 0
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 worldpos : TEXCOORD0;
};
sampler3D _Volume;
float3 _CameraWorldPosition;
float3 _LightDirection;
float _DensityScale;
float _ScatteringScale;
float _EditorTime;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldpos = mul(unity_ObjectToWorld, v.vertex);
return o;
}
float simpleNoise(float2 uv)
{
return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453);
}
float dither4x4(float2 position, float time)
{
const float kernel[16] = {0.0625, 0.5625, 0.1875, 0.6875, 0.8125, 0.3125, 0.9375, 0.4375, 0.25, 0.75, 0.125, 0.625, 1.0, 0.5, 0.875, 0.375};
float v = kernel[(((int)position.y & 3) << 2) + ((int)position.x & 3)];
#if DITHER_NOISE
return frac(v + simpleNoise(position) + time);
#else
return v;
#endif
}
float invGaussian(float x, float H)
{
return 1.0 - (1.0 / pow(H*x + 1.0,2.0));
}
float LightMarch(sampler3D volume, float3 position, int maxSteps)
{
float3 dir = -normalize(_LightDirection);
float acc = 1.0f;
float step = 3.4641 / maxSteps;
for (int i = 0; i < maxSteps; i++)
{
float f = 3.4641 * (float)i / maxSteps;
float3 sampleWorldPos = position + f * dir;
float3 samplePos = sampleWorldPos + 0.5;
acc *= 1.0f - saturate(tex3Dlod(volume, float4(samplePos, 0.0)) * _DensityScale * _ScatteringScale * step);
if (abs(samplePos.x - 0.5) > 0.5 || abs(samplePos.y - 0.5) > 0.5 || abs(samplePos.z - 0.5) > 0.5) break;
if (acc < 0.1f) return 0.1f;
}
return acc;
}
float4 RayMarch(sampler3D volume, float3 dir, float3 position, int maxSteps, float dither)
{
float3 outColor = float3(-1.0f, -1.0f, -1.0f);
float step = 3.4641 / maxSteps;
int i = 0;
float acc = 0.0f;
for (i = 0; i < maxSteps; i++)
{
float f = 3.4641 * ((float)i + dither) / (float)maxSteps;
float3 sampleWorldPos = position + f * dir;
float3 samplePos = sampleWorldPos + 0.5;
if (abs(samplePos.x - 0.5) > 0.5 || abs(samplePos.y - 0.5) > 0.5 || abs(samplePos.z - 0.5) > 0.5) break;
float a = tex3Dlod(volume, float4(samplePos, 4.0)) * _DensityScale * step;
if (a > 0.001f)
{
float l = LightMarch(volume, sampleWorldPos, NB_LIGHT_SAMPLES);
if (outColor.r < 0.0f)
outColor = float3(l, l, l);
else
outColor = lerp( outColor, float3(l, l, l), a * saturate(1.0f-acc));
acc += a;
}
if (acc > 1.0f) break;
}
#if DISPLAY_NB_SAMPLES
return (float4(1, 1, 1, 1) / NB_VOLUME_SAMPLES) * (float)i;
#else
return float4(outColor, acc);
#endif
}
fixed4 frag (v2f i) : SV_Target
{
float f = dither4x4(i.vertex.xy, _EditorTime);
fixed4 col = RayMarch(_Volume, -normalize(_CameraWorldPosition - i.worldpos), i.worldpos, NB_VOLUME_SAMPLES, f);
return col;
}
ENDCG
}
}
}

9
Editor/VolumeEditor/Editor/Shaders/VolumeCloud.shader.meta


fileFormatVersion: 2
guid: 0bb96eb486d6dba4899c943113e5e9fd
timeCreated: 1472032889
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

90
Editor/VolumeEditor/Editor/Shaders/VolumeTrailRenderer.shader


Shader "Hidden/VFXToolbox/VolumeEditor/VolumeTrail"
{
Properties
{
_Volume("_Volume", 3D) = "white" {}
_NumPointsPerTrail("_NumPointsPerTrail", Int) = 2
_ReduceFactor("_ReduceFactor", Int) = 1
_Length("_Length", Float) = 0.1
_HeatMap("_HeatMap", 2D) = "white" {}
_HeatMapScale("_HeatMapScale", Float) = 1.0
_Dimensions("_Dimensions", Vector) = (1.0,1.0,1.0,1.0)
_Offset("_Offset", Vector) = (0.0,0.0,0.0,0.0)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
float4 color : COLOR0;
};
sampler3D _Volume;
sampler2D _HeatMap;
uint _NumPointsPerTrail;
uint _ReduceFactor;
float _Length;
float _HeatMapScale;
float4 _Dimensions;
float4 _Offset;
bool Reduce(float3 pos)
{
uint x = floor(pos.x * _Dimensions.x);
uint y = floor(pos.y * _Dimensions.y);
uint z = floor(pos.z * _Dimensions.z);
return ((x % _ReduceFactor) > 0) || ((y % _ReduceFactor) > 0) || ((z % _ReduceFactor) > 0);
}
v2f vert (appdata v, uint id : SV_VertexID)
{
v2f o;
float3 pos = v.vertex + 0.5f;
float4 mag;
if (!Reduce(pos))
{
pos += _Offset;
pos += (_ReduceFactor-1) / (_Dimensions * 2);
for (uint i = 0; i < id % _NumPointsPerTrail; i++)
{
float3 val = tex3Dlod(_Volume, float4(pos, 0.0f) + 0.5f/_Dimensions) - 0.5f;
pos += val * _Length;
mag = tex2Dlod(_HeatMap, float4(pow(length(val), 2)*_HeatMapScale, 0.0f, 0, 0));
}
o.color = mag;
o.vertex = UnityObjectToClipPos(float4(pos - 0.5, v.vertex.w));
}
else
{
o.vertex = float4(2, 2, 0, 1);
o.color = float4(0, 0, 0, 0);
}
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return i.color;
}
ENDCG
}
}
}

9
Editor/VolumeEditor/Editor/Shaders/VolumeTrailRenderer.shader.meta


fileFormatVersion: 2
guid: 4cf9d45ad59501446971128c5d8ebc14
timeCreated: 1472647038
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Editor/VolumeEditor/Editor/Textures.meta


fileFormatVersion: 2
guid: fa1b11c22ddfef34b940bcf535cced6a
folderAsset: yes
timeCreated: 1472654644
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

1
Editor/VolumeEditor/Editor/Textures/heatmap.tga

之前 之后

76
Editor/VolumeEditor/Editor/Textures/heatmap.tga.meta


fileFormatVersion: 2
guid: bfaacd1dd76a5f14495e6af339ba44ce
timeCreated: 1472654644
licenseType: Pro
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
filterMode: -1
aniso: -1
mipBias: -1
wrapMode: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

3
Editor/VolumeEditor/Editor/Textures/heatmap2.tga

之前 之后

76
Editor/VolumeEditor/Editor/Textures/heatmap2.tga.meta


fileFormatVersion: 2
guid: 4efc39ba9c9767445a37d4915bbd4140
timeCreated: 1472725757
licenseType: Pro
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
filterMode: -1
aniso: -1
mipBias: -1
wrapMode: 1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:

9
Editor/VolumeEditor/Editor/Utility.meta


fileFormatVersion: 2
guid: 9c6301786d0554d4897cc84f172cf3c2
folderAsset: yes
timeCreated: 1472032558
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

54
Editor/VolumeEditor/Editor/Utility/VFFileImporter.cs


using UnityEngine;
using System.IO;
namespace UnityEditor.VFXToolbox.VolumeEditor
{
public class VFFileImporter
{
public static Texture3D LoadVFFile(string filename, TextureFormat textureformat)
{
BinaryReader br = new BinaryReader(File.OpenRead(filename));
string fourcc = new string(br.ReadChars(4));
ushort size_x = br.ReadUInt16();
ushort size_y = br.ReadUInt16();
ushort size_z = br.ReadUInt16();
int mode = -1;
if (fourcc == "VF_F")
mode = 0;
else if (fourcc == "VF_V")
mode = 1;
else
throw new System.Exception("Invalid VF FourCC");
if(mode != -1)
{
Texture3D outputFile = new Texture3D(size_x, size_y, size_z, textureformat, false);
ulong length = (ulong)size_x * (ulong)size_y * (ulong)size_z;
Color[] colors = new Color[length];
for(ulong i = 0; i < length; i++)
{
if(mode == 0)
{
float val = br.ReadSingle();
colors[i] = new Color(val, val, val);
}
else
{
float r = br.ReadSingle();
float g = br.ReadSingle();
float b = br.ReadSingle();
colors[i] = new Color(r,g,b);
}
}
outputFile.SetPixels(colors);
br.Close();
return outputFile;
}
return null;
}
}
}

12
Editor/VolumeEditor/Editor/Utility/VFFileImporter.cs.meta


fileFormatVersion: 2
guid: abecc4de2f73df24c8096a448c1fe0ba
timeCreated: 1472032558
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

90
Editor/VolumeEditor/Editor/VolumeEditor.cs


using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
namespace UnityEditor.VFXToolbox.VolumeEditor
{
public class VolumeEditor : EditorWindow
{
[MenuItem("Window/Visual Effects/Volume Editor")]
public static void OpenVolumeEditor()
{
EditorWindow.GetWindow<VolumeEditor>();
}
// Debug, temporary
[MenuItem("Window/Visual Effects/VF File Importer (Texture3D)")]
public static void Create3DTexture()
{
string filename = EditorUtility.OpenFilePanel("Open VF File", "", "vf");
if(filename != null && System.IO.File.Exists(filename))
{
Texture3D texture = VFFileImporter.LoadVFFile(filename, TextureFormat.ARGB32);
string assetFileName = EditorUtility.SaveFilePanelInProject("Save 3D Texture", System.IO.Path.GetFileNameWithoutExtension(filename) + ".asset", "asset", "");
if(assetFileName != null)
{
AssetDatabase.CreateAsset(texture, assetFileName);
}
}
}
private VolumeEditorPreview m_Preview;
private void Initialize()
{
if (m_Preview == null)
{
m_Preview = new VolumeEditorPreview();
m_Preview.Initialize();
}
}
private void HandleDropData()
{
DragAndDrop.visualMode = DragAndDropVisualMode.Link;
if( Event.current.type == EventType.DragExited)
{
if(DragAndDrop.paths.Length > 0)
{
m_Preview.LoadTexture(DragAndDrop.paths[0]);
}
}
}
public void OnGUI()
{
Initialize();
HandleDropData();
titleContent = VFXToolboxGUIUtility.Get("Volume Editor");
if (Event.current.type == EventType.Repaint)
{
m_Preview.Render(position);
GUI.DrawTexture(new Rect(0,0,position.width, position.height), m_Preview.texture);
}
bool bValueChanged = false;
Rect previewWindowRect = new Rect(16, 16, 320, 360);
BeginWindows();
GUI.Window(0, previewWindowRect, DrawPreviewRendererGUIWindow, "Preview Options");
EndWindows();
if(!bValueChanged)
{
m_Preview.HandleMouse(position);
}
Repaint();
}
public void DrawPreviewRendererGUIWindow(int id)
{
m_Preview.activeRendererIndex = EditorGUILayout.IntPopup("Preview Mode",m_Preview.activeRendererIndex, m_Preview.GetRendererNames(), m_Preview.GetRendererValues());
EditorGUILayout.Space();
m_Preview.OnRendererGUI();
}
}
}

12
Editor/VolumeEditor/Editor/VolumeEditor.cs.meta


fileFormatVersion: 2
guid: 09c44c13cc054624bb064249e378a95c
timeCreated: 1472024723
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

193
Editor/VolumeEditor/Editor/VolumeEditorPreview.cs


using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.Collections.Generic;
namespace UnityEditor.VFXToolbox.VolumeEditor
{
public class VolumeEditorPreview
{
private enum NavMode
{
None = 0,
Zooming = 1,
Rotating = 2
}
public Texture texture { get { return m_PreviewTexture; } }
public List<VolumeRendererBase> renderers { get { return m_Renderers; } }
public int activeRendererIndex { get { return GetPreviewMode(); } set { SetPreviewMode(value); } }
private PreviewRenderUtility m_previewUtility;
private Texture m_PreviewTexture;
private Texture3D m_Volume;
private Material m_BackgroundMaterial;
private List<VolumeRendererBase> m_Renderers;
private VolumeRendererBase m_ActiveRenderer;
private float m_CameraPhi = 0.75f;
private float m_CameraTheta = 0.5f;
private float m_CameraDistance = 2.0f;
private NavMode m_NavMode = NavMode.None;
private Vector2 m_PreviousMousePosition = Vector2.zero;
private DummyRenderer m_DummyRenderer;
public VolumeEditorPreview()
{
}
public void Initialize()
{
if(m_BackgroundMaterial == null)
{
m_BackgroundMaterial = new Material(Shader.Find("Hidden/VFXToolbox/Skybox/Gradient"));
m_BackgroundMaterial.SetFloat("_VerticalFalloff", 4);
m_BackgroundMaterial.SetFloat("_DitherIntensity", 0.45f);
}
if(m_previewUtility == null)
{
m_previewUtility = new PreviewRenderUtility(false);
m_previewUtility.cameraFieldOfView = 50.0f;
m_previewUtility.camera.nearClipPlane = 0.1f;
m_previewUtility.camera.farClipPlane = 100.0f;
m_previewUtility.camera.transform.position = new Vector3(3, 2, 3);
m_previewUtility.camera.transform.LookAt(Vector3.zero);
m_previewUtility.camera.renderingPath = RenderingPath.Forward;
m_previewUtility.camera.allowHDR = false;
m_previewUtility.camera.clearFlags = CameraClearFlags.Skybox;
m_previewUtility.lights[0].shadows = LightShadows.None;
}
if(m_Renderers == null)
{
m_Renderers = new List<VolumeRendererBase>();
m_Renderers.Add(new DensityVolumeRenderer());
m_Renderers.Add(new VectorFieldVolumeRenderer());
m_ActiveRenderer = m_Renderers[0];
}
if(m_DummyRenderer == null)
{
m_DummyRenderer = new DummyRenderer();
}
}
public void LoadTexture(string path)
{
Texture3D texture = AssetDatabase.LoadAssetAtPath<Texture3D>(path);
if(texture != null)
{
m_Volume = texture;
m_ActiveRenderer.SetTexture(m_Volume);
}
}
public void OnRendererGUI()
{
Initialize();
m_ActiveRenderer.OnGUI();
}
private void UpdateCamera()
{
Vector3 pos = new Vector3( Mathf.Sin(m_CameraPhi)* Mathf.Cos(m_CameraTheta), Mathf.Cos(m_CameraPhi), Mathf.Sin(m_CameraPhi) * Mathf.Sin(m_CameraTheta)) * m_CameraDistance;
m_previewUtility.camera.transform.position = pos;
m_previewUtility.camera.transform.LookAt(Vector3.zero);
}
public void HandleMouse(Rect Viewport)
{
if(Event.current.type == EventType.MouseDown)
{
if (Event.current.button == 0)
m_NavMode = NavMode.Rotating;
else if (Event.current.button == 1)
m_NavMode = NavMode.Zooming;
m_PreviousMousePosition = Event.current.mousePosition;
}
if (Event.current.type == EventType.MouseUp || Event.current.rawType == EventType.MouseUp)
m_NavMode = NavMode.None;
if(m_NavMode != NavMode.None)
{
Vector2 mouseDelta = Event.current.mousePosition - m_PreviousMousePosition;
switch(m_NavMode)
{
case NavMode.Rotating:
m_CameraTheta = (m_CameraTheta - mouseDelta.x * 0.003f) % (Mathf.PI * 2);
m_CameraPhi = Mathf.Clamp(m_CameraPhi - mouseDelta.y *0.003f, 0.2f, Mathf.PI - 0.2f);
break;
case NavMode.Zooming:
m_CameraDistance = Mathf.Clamp(mouseDelta.y * 0.01f + m_CameraDistance, 1, 10);
break;
}
}
m_PreviousMousePosition = Event.current.mousePosition;
}
public void Render(Rect viewportRect)
{
Initialize();
UpdateCamera();
Material backupSkybox = RenderSettings.skybox;
RenderSettings.skybox = m_BackgroundMaterial;
m_previewUtility.BeginPreview(viewportRect, GUIStyle.none);
if(m_Volume != null)
{
m_ActiveRenderer.Render(m_previewUtility);
}
else
{
m_DummyRenderer.Render(m_previewUtility);
}
m_previewUtility.camera.Render();
m_PreviewTexture = m_previewUtility.EndPreview();
RenderSettings.skybox = backupSkybox;
}
public int GetPreviewMode()
{
return m_Renderers.IndexOf(m_ActiveRenderer);
}
public void SetPreviewMode(int mode)
{
if(mode != m_Renderers.IndexOf(m_ActiveRenderer))
{
m_ActiveRenderer = m_Renderers[mode];
if(m_Volume != null)
m_ActiveRenderer.SetTexture(m_Volume);
}
}
public string[] GetRendererNames()
{
string[] names = new string[m_Renderers.Count];
for(int i =0; i < m_Renderers.Count; i++)
{
names[i] = m_Renderers[i].ToString();
}
return names;
}
public int[] GetRendererValues()
{
int[] values = new int[m_Renderers.Count];
for(int i =0; i < m_Renderers.Count; i++)
{
values[i] = i;
}
return values;
}
}
}

12
Editor/VolumeEditor/Editor/VolumeEditorPreview.cs.meta


fileFormatVersion: 2
guid: 6d29e5a48e9963c4fa42603474d20d3e
timeCreated: 1472027656
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

107
Editor/VolumeEditor/Editor/Renderers/DensityVolumeRenderer.cs


using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.Collections.Generic;
using System;
namespace UnityEditor.VFXToolbox.VolumeEditor
{
public class DensityVolumeRenderer : VolumeRendererBase
{
public float m_DensityScale = 1.0f;
public float m_ScatteringScale = 1.0f;
public float m_LightAngle = 0.0f;
protected Mesh m_PreviewMesh;
protected Material m_PreviewMeshMaterial;
public DensityVolumeRenderer() : base ()
{
m_PreviewMeshMaterial = new Material(Shader.Find("Hidden/VFXToolbox/VolumeEditor/VolumeCloud"));
CreateMesh();
}
public override void SetTexture(Texture texture)
{
m_PreviewMeshMaterial.SetTexture("_Volume", texture);
}
public override void Render(PreviewRenderUtility previewUtility)
{
float time = (float)EditorApplication.timeSinceStartup;
m_PreviewMeshMaterial.SetVector("_CameraWorldPosition", previewUtility.camera.transform.position);
m_PreviewMeshMaterial.SetVector("_LightDirection", new Vector3(Mathf.Sin(m_LightAngle), -1f, Mathf.Cos(m_LightAngle)).normalized);
m_PreviewMeshMaterial.SetFloat("_DensityScale", m_DensityScale);
m_PreviewMeshMaterial.SetFloat("_ScatteringScale", m_ScatteringScale);
m_PreviewMeshMaterial.SetFloat("_EditorTime", (float)EditorApplication.timeSinceStartup);
previewUtility.DrawMesh(m_PreviewMesh, Matrix4x4.identity, m_PreviewMeshMaterial, 0);
RenderOutlineCube(previewUtility);
}
public override void OnGUI()
{
m_DensityScale = EditorGUILayout.Slider("Density Scale", m_DensityScale, 0.0f, 5.0f);
m_ScatteringScale = EditorGUILayout.Slider("Scattering Scale", m_ScatteringScale, 0.0f, 2.0f);
m_LightAngle = EditorGUILayout.Slider("Light Direction", m_LightAngle, -Mathf.PI, Mathf.PI);
}
protected void CreateMesh()
{
if(m_PreviewMesh == null)
m_PreviewMesh = new Mesh();
m_PreviewMesh.Clear();
Vector3[] pos = new Vector3[24]
{
new Vector3(-0.5f, 0.5f, -0.5f), new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(0.5f, 0.5f, 0.5f), new Vector3(0.5f, 0.5f, -0.5f),
new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(-0.5f, 0.5f, -0.5f),
new Vector3(0.5f, -0.5f, -0.5f), new Vector3(-0.5f,-0.5f, -0.5f), new Vector3(-0.5f, 0.5f, -0.5f), new Vector3(0.5f, 0.5f, -0.5f),
new Vector3(0.5f, -0.5f, 0.5f) , new Vector3(0.5f, -0.5f, -0.5f), new Vector3(0.5f, 0.5f, -0.5f), new Vector3(0.5f, 0.5f, 0.5f),
new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(0.5f, -0.5f, 0.5f), new Vector3(0.5f, 0.5f, 0.5f), new Vector3(-0.5f, 0.5f, 0.5f),
new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(0.5f, -0.5f, -0.5f), new Vector3(0.5f, -0.5f, 0.5f), new Vector3(-0.5f, -0.5f, 0.5f)
};
Vector3[] nrm = new Vector3[24]
{
new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0),
new Vector3(0, 0, -1), new Vector3(0, 0, -1), new Vector3(0, 0, -1), new Vector3(0, 0, -1),
new Vector3(-1, 0, 0), new Vector3(-1, 0, 0), new Vector3(-1, 0, 0), new Vector3(-1, 0, 0),
new Vector3(0, 0, 1), new Vector3(0, 0, 1), new Vector3(0, 0, 1), new Vector3(0, 0, 1),
new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(1, 0, 0),
new Vector3(0, -1, 0), new Vector3(0, -1, 0), new Vector3(0, -1, 0), new Vector3(0, -1, 0)
};
List<Vector3> positions = new List<Vector3>(pos);
List<Vector3> normals = new List<Vector3>(nrm);
int[] triangles = new int[36]
{
0,1,2,
0,2,3,
4,5,6,
4,6,7,
8,9,10,
8,10,11,
12,13,14,
12,14,15,
16,17,18,
16,18,19,
20,21,22,
20,22,23
};
m_PreviewMesh.SetVertices(positions);
m_PreviewMesh.SetNormals(normals);
m_PreviewMesh.SetTriangles(triangles, 0);
m_PreviewMesh.RecalculateBounds();
}
public override string ToString()
{
return "Density";
}
}
}

12
Editor/VolumeEditor/Editor/Renderers/DensityVolumeRenderer.cs.meta


fileFormatVersion: 2
guid: 5515703f5bf270e4b90f6a6fafa0a91f
timeCreated: 1472116146
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

38
Editor/VolumeEditor/Editor/Renderers/DummyRenderer.cs


using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.Collections.Generic;
using System;
namespace UnityEditor.VFXToolbox.VolumeEditor
{
public class DummyRenderer : VolumeRendererBase
{
public DummyRenderer() : base()
{
}
public override void OnGUI()
{
}
public override void Render(PreviewRenderUtility previewUtility)
{
RenderOutlineCube(previewUtility);
Handles.Label(Vector3.zero, "No Volume Loaded, please drag a Texture3D in this window.");
}
public override void SetTexture(Texture texture)
{
}
public override string ToString()
{
return "Dummy";
}
}
}

12
Editor/VolumeEditor/Editor/Renderers/DummyRenderer.cs.meta


fileFormatVersion: 2
guid: 573c7fd050ad4ff498205aaf705ffca2
timeCreated: 1472652028
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

12
Editor/VolumeEditor/Editor/Renderers/VectorFieldVolumeRenderer.cs.meta


fileFormatVersion: 2
guid: 37db4d919536d3d43b459f897d45d8ab
timeCreated: 1472634503
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

65
Editor/VolumeEditor/Editor/Renderers/VolumeRendererBase.cs


using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.Collections.Generic;
namespace UnityEditor.VFXToolbox.VolumeEditor
{
public abstract class VolumeRendererBase
{
private Mesh m_OutlineCubeMesh;
private Material m_OutlineCubeMaterial;
public VolumeRendererBase()
{
m_OutlineCubeMaterial = new Material(Shader.Find("Unlit/Color"));
GenerateOutlineCube();
}
protected void RenderOutlineCube(PreviewRenderUtility previewUtility)
{
RenderOutlineCube(previewUtility, new Color(1, 1, 1, 0.25f));
}
protected void RenderOutlineCube(PreviewRenderUtility previewUtility, Color color)
{
m_OutlineCubeMaterial.SetColor ("_Color", color);
previewUtility.DrawMesh(m_OutlineCubeMesh, Matrix4x4.identity, m_OutlineCubeMaterial, 0);
}
public abstract void Render(PreviewRenderUtility previewUtility);
public abstract void OnGUI();
public abstract void SetTexture(Texture texture);
private void GenerateOutlineCube()
{
if (m_OutlineCubeMesh == null)
m_OutlineCubeMesh = new Mesh();
m_OutlineCubeMesh.Clear();
List<Vector3> vertices = new List<Vector3>();
vertices.Add(new Vector3(-0.5f, -0.5f, -0.5f));
vertices.Add(new Vector3(-0.5f, -0.5f, 0.5f));
vertices.Add(new Vector3(-0.5f, 0.5f, -0.5f));
vertices.Add(new Vector3(-0.5f, 0.5f, 0.5f));
vertices.Add(new Vector3(0.5f, -0.5f, -0.5f));
vertices.Add(new Vector3(0.5f, -0.5f, 0.5f));
vertices.Add(new Vector3(0.5f, 0.5f, -0.5f));
vertices.Add(new Vector3(0.5f, 0.5f, 0.5f));
int[] indices = new int[]
{
0,1,1,3,3,2,2,0,
4,5,5,7,7,6,6,4,
0,4,1,5,2,6,3,7
};
m_OutlineCubeMesh.SetVertices(vertices);
m_OutlineCubeMesh.SetIndices(indices,MeshTopology.Lines,0);
}
}
}

12
Editor/VolumeEditor/Editor/Renderers/VolumeRendererBase.cs.meta


fileFormatVersion: 2
guid: 64c04bfb9908a0944851e3dcba2bbcaf
timeCreated: 1472116146
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

283
Editor/VolumeEditor/Editor/Renderers/VectorFieldVolumeRenderer.cs


using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.Collections.Generic;
using System;
namespace UnityEditor.VFXToolbox.VolumeEditor
{
public class VectorFieldVolumeRenderer : VolumeRendererBase
{
public enum ViewMode
{
VolumeFloaters,
SliceFloaters
}
public enum ViewModeSliceAxis
{
XY,
XZ,
YZ
}
public ViewMode viewMode { get { return m_ViewMode; } set { SetViewMode(value); } }
public ViewModeSliceAxis sliceAxis { get { return m_ViewModeSliceAxis; } set { SetSliceAxis(value); } }
public float slicePosition { get { return m_SlicePosition; } set { SetSlicePosition(value); } }
public uint reduceFactor { get { return m_ReduceFactor; } set { SetReduceFactor(value); } }
public float floaterStep { get { return m_FloaterStep; } set { m_FloaterStep =value; } }
public float heatMapScale { get { return m_HeatMapScale; } set { m_HeatMapScale =value; } }
private uint m_ReduceFactor;
private float m_FloaterStep;
private uint m_VolumeSizeX;
private uint m_VolumeSizeY;
private uint m_VolumeSizeZ;
private List<Texture2D> m_HeatMap;
private int m_CurrentHeatMap;
private float m_HeatMapScale;
private ViewMode m_ViewMode;
private ViewModeSliceAxis m_ViewModeSliceAxis;
private float m_SlicePosition;
protected List<Mesh> m_PreviewMesh;
protected Material m_PreviewMeshMaterial;
private const int NUM_POINTS_PER_TRAIL = 32;
private const uint MAX_SIZE = 64;
public VectorFieldVolumeRenderer() : base()
{
m_VolumeSizeX = 0;
m_VolumeSizeY = 0;
m_VolumeSizeZ = 0;
m_ReduceFactor = 1;
m_FloaterStep = 0.03f;
m_HeatMapScale = 3.5f;
m_ViewMode = ViewMode.VolumeFloaters;
m_ViewModeSliceAxis = ViewModeSliceAxis.XY;
m_SlicePosition = 0.5f;
m_PreviewMeshMaterial = new Material(Shader.Find("Hidden/VFXToolbox/VolumeEditor/VolumeTrail"));
m_HeatMap = new List<Texture2D>();
m_HeatMap.Add(AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.vfx-toolbox/VolumeEditor/Editor/Textures/heatmap.tga"));
m_HeatMap.Add(AssetDatabase.LoadAssetAtPath<Texture2D>("Packages/com.unity.vfx-toolbox/VolumeEditor/Editor/Textures/heatmap2.tga"));
m_PreviewMeshMaterial.SetInt("_NumPointsPerTrail", NUM_POINTS_PER_TRAIL);
}
public override void OnGUI()
{
viewMode = (ViewMode)EditorGUILayout.EnumPopup("View Mode", viewMode);
if(viewMode == ViewMode.SliceFloaters)
{
sliceAxis = (ViewModeSliceAxis)EditorGUILayout.EnumPopup("Slice Axis", sliceAxis);
slicePosition = EditorGUILayout.Slider("Slice Position", slicePosition, 0, 1);
}
reduceFactor = (uint)EditorGUILayout.IntSlider("Reduce By",(int)reduceFactor, 0, 4);
floaterStep = EditorGUILayout.Slider("Simulation Step: ", floaterStep, 0.001f, 0.05f);
heatMapScale = EditorGUILayout.Slider("HeatMap Scale", heatMapScale, 0.1f, 5.0f);
m_CurrentHeatMap = EditorGUILayout.IntPopup("Heat Map Template", m_CurrentHeatMap, new string[] { "Thermal", "Rainbow" }, new int[] { 0, 1 });
}
public override void Render(PreviewRenderUtility previewUtility)
{
if (m_VolumeSizeX > 0 && m_VolumeSizeY > 0 && m_VolumeSizeZ > 0)
{
if (m_PreviewMesh == null)
RegenerateGeometry();
m_PreviewMeshMaterial.SetFloat("_Length", m_FloaterStep);
m_PreviewMeshMaterial.SetTexture("_HeatMap", m_HeatMap[m_CurrentHeatMap]);
m_PreviewMeshMaterial.SetFloat("_HeatMapScale", m_HeatMapScale);
foreach(Mesh mesh in m_PreviewMesh)
previewUtility.DrawMesh(mesh, Matrix4x4.identity, m_PreviewMeshMaterial, 0);
RenderOutlineCube(previewUtility);
}
}
public override void SetTexture(Texture texture)
{
if(texture == null)
{
m_VolumeSizeX = 0;
m_VolumeSizeY = 0;
m_VolumeSizeZ = 0;
}
else
{
Texture3D volume = (Texture3D)texture;
m_PreviewMeshMaterial.SetTexture("_Volume", volume);
if(m_VolumeSizeX != (uint)volume.width || m_VolumeSizeY != (uint)volume.height || m_VolumeSizeZ != (uint)volume.depth)
{
m_VolumeSizeX = (uint)volume.width;
m_VolumeSizeY = (uint)volume.height;
m_VolumeSizeZ = (uint)volume.depth;
RegenerateGeometry();
m_PreviewMeshMaterial.SetVector("_Dimensions", new Vector4(m_VolumeSizeX, m_VolumeSizeY, m_VolumeSizeZ, 1.0f));
}
}
}
private void SetReduceFactor(uint factor)
{
if(factor != m_ReduceFactor)
{
m_ReduceFactor = factor;
m_PreviewMeshMaterial.SetInt("_ReduceFactor", (int)Mathf.Pow(2,reduceFactor));
}
}
private void SetViewMode(ViewMode newMode)
{
if(newMode != m_ViewMode)
{
m_ViewMode = newMode;
RegenerateGeometry();
switch(m_ViewMode)
{
case ViewMode.VolumeFloaters:
SetSlicePosition(0.0f);
break;
default: break;
}
}
}
private void SetSliceAxis(ViewModeSliceAxis axis)
{
if(m_ViewModeSliceAxis != axis)
{
m_ViewModeSliceAxis = axis;
RegenerateGeometry();
}
}
private void SetSlicePosition(float value)
{
Vector4 offset = Vector4.zero;
m_SlicePosition = value;
switch(sliceAxis)
{
case ViewModeSliceAxis.XY:
offset = new Vector4(0, 0, value, 0);
break;
case ViewModeSliceAxis.YZ:
offset = new Vector4(value, 0, 0, 0);
break;
case ViewModeSliceAxis.XZ:
offset = new Vector4(0, value, 0, 0);
break;
}
m_PreviewMeshMaterial.SetVector("_Offset", offset);
}
public void RegenerateGeometry()
{
switch(m_ViewMode)
{
case ViewMode.VolumeFloaters:
CreateVolumeFloaterMesh(false, ViewModeSliceAxis.XY);
break;
case ViewMode.SliceFloaters:
CreateVolumeFloaterMesh(true, m_ViewModeSliceAxis);
break;
}
}
protected void CreateVolumeFloaterMesh(bool bSlice, ViewModeSliceAxis axis)
{
if(m_PreviewMesh == null)
m_PreviewMesh = new List<Mesh>();
if (m_VolumeSizeX > 0 && m_VolumeSizeY > 0 && m_VolumeSizeZ > 0)
{
uint indexStride = (NUM_POINTS_PER_TRAIL-1) * 2;
uint vertexStride = NUM_POINTS_PER_TRAIL;
uint numFloatersX = (bSlice && axis == ViewModeSliceAxis.YZ)? 1 : m_VolumeSizeX;
uint numFloatersY = (bSlice && axis == ViewModeSliceAxis.XZ)? 1 : m_VolumeSizeY;
uint numFloatersZ = (bSlice && axis == ViewModeSliceAxis.XY)? 1 : m_VolumeSizeZ;
uint numFloaters = numFloatersX * numFloatersY * numFloatersZ;
uint numVertices = vertexStride * numFloaters;
uint numSplits = (numVertices+65535) / 65536;
if (m_PreviewMesh == null)
m_PreviewMesh = new List<Mesh>();
m_PreviewMesh.Clear();
uint maxChunksPerSplit = 65535 / vertexStride;
uint chunksLeft = numFloaters;
Vector3 meshCenter = new Vector3(0.5f, 0.5f, 0.5f);
for(int i = 0; i < numSplits; i++)
{
EditorUtility.DisplayProgressBar("Volume Viewer", "Creating Mesh", (float)i / numSplits);
Mesh mesh = new Mesh();
uint chunkOffset = ((uint)i * maxChunksPerSplit);
List<Vector3> vertices = new List<Vector3>();
// How many chunks this time?
uint numChunks = (chunksLeft > maxChunksPerSplit) ? maxChunksPerSplit : chunksLeft;
chunksLeft -= numChunks;
int[] indices = new int[numChunks * indexStride];
// Foreach Chunk
for(uint j = 0; j < numChunks; j++)
{
uint vertexOffset = j * vertexStride;
uint indexOffset = j * indexStride;
// Vertices & UVs
for(uint k = 0; k < vertexStride; k++)
{
Vector3 pos = PositionFromIndex(j + chunkOffset, numFloatersX, numFloatersY, numFloatersZ);
vertices.Add(pos - meshCenter);
}
// indices
for(uint k = 0; k < indexStride/2; k++)
{
indices[indexOffset + (k * 2)] = (int)(vertexOffset + k);
indices[indexOffset + (k * 2) + 1] = (int)(vertexOffset + k + 1);
}
}
mesh.SetVertices(vertices);
mesh.SetIndices(indices, MeshTopology.Lines, 0);
mesh.bounds = new Bounds(Vector3.zero, new Vector3(1, 1, 1));
m_PreviewMesh.Add(mesh);
}
EditorUtility.ClearProgressBar();
}
}
private Vector3 PositionFromIndex(uint index, uint numX, uint numY, uint numZ)
{
uint x = index % numX;
uint y = (index / numX) % numY;
uint z = (index / (numX * numY));
return new Vector3((float)x/numX, (float)y/numY, (float)z/numZ);
}
public override string ToString()
{
return "Vector Field";
}
}
}
正在加载...
取消
保存