├── .gitignore
├── Assets
├── HeadScan_Texture3D.asset
├── HeadScan_Texture3D.asset.meta
├── Texture3D preview in Inspector.unity
├── Texture3D preview in Inspector.unity.meta
├── Texture3DPreview.meta
├── Texture3DPreview
│ ├── Attributes.meta
│ ├── Attributes
│ │ ├── Texture3DPreviewAttribute.cs
│ │ └── Texture3DPreviewAttribute.cs.meta
│ ├── Editor.meta
│ └── Editor
│ │ ├── Drawers.meta
│ │ ├── Drawers
│ │ ├── Texture3DPreviewDrawer.cs
│ │ └── Texture3DPreviewDrawer.cs.meta
│ │ ├── Editors.meta
│ │ ├── Editors
│ │ ├── Texture3DEditor.cs
│ │ └── Texture3DEditor.cs.meta
│ │ ├── Extensions.meta
│ │ ├── Extensions
│ │ ├── Texture3DExtensions.cs
│ │ └── Texture3DExtensions.cs.meta
│ │ ├── Helpers.meta
│ │ ├── Helpers
│ │ ├── MeshHelpers.cs
│ │ ├── MeshHelpers.cs.meta
│ │ ├── PreviewRenderUtilityHelpers.cs
│ │ └── PreviewRenderUtilityHelpers.cs.meta
│ │ ├── Shaders.meta
│ │ └── Shaders
│ │ ├── Texture3DPreviewShader.shader
│ │ └── Texture3DPreviewShader.shader.meta
├── Texture3DPreviewInInspector.cs
└── Texture3DPreviewInInspector.cs.meta
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | /[Ll]ibrary/
2 | /[Tt]emp/
3 | /[Oo]bj/
4 | /[Bb]uild/
5 | /[Bb]uilds/
6 | /Assets/AssetStoreTools*
7 |
8 | # Visual Studio 2015 cache directory
9 | /.vs/
10 |
11 | # Autogenerated VS/MD/Consulo solution and project files
12 | ExportedObj/
13 | .consulo/
14 | *.csproj
15 | *.unityproj
16 | *.sln
17 | *.suo
18 | *.tmp
19 | *.user
20 | *.userprefs
21 | *.pidb
22 | *.booproj
23 | *.svd
24 | *.pdb
25 |
26 | # Unity3D generated meta files
27 | *.pidb.meta
28 |
29 | # Unity3D Generated File On Crash Reports
30 | sysinfo.txt
31 |
32 | # Builds
33 | *.apk
34 | *.unitypackage
35 |
--------------------------------------------------------------------------------
/Assets/HeadScan_Texture3D.asset.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 64677355665b5684c822c245cb6a495b
3 | timeCreated: 1507629404
4 | licenseType: Pro
5 | NativeFormatImporter:
6 | externalObjects: {}
7 | mainObjectFileID: 0
8 | userData:
9 | assetBundleName:
10 | assetBundleVariant:
11 |
--------------------------------------------------------------------------------
/Assets/Texture3D preview in Inspector.unity:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!29 &1
4 | OcclusionCullingSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | m_OcclusionBakeSettings:
8 | smallestOccluder: 5
9 | smallestHole: 0.25
10 | backfaceThreshold: 100
11 | m_SceneGUID: 00000000000000000000000000000000
12 | m_OcclusionCullingData: {fileID: 0}
13 | --- !u!104 &2
14 | RenderSettings:
15 | m_ObjectHideFlags: 0
16 | serializedVersion: 8
17 | m_Fog: 0
18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
19 | m_FogMode: 3
20 | m_FogDensity: 0.01
21 | m_LinearFogStart: 0
22 | m_LinearFogEnd: 300
23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
26 | m_AmbientIntensity: 1
27 | m_AmbientMode: 0
28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
29 | m_SkyboxMaterial: {fileID: 0}
30 | m_HaloStrength: 0.5
31 | m_FlareStrength: 1
32 | m_FlareFadeSpeed: 3
33 | m_HaloTexture: {fileID: 0}
34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
35 | m_DefaultReflectionMode: 0
36 | m_DefaultReflectionResolution: 128
37 | m_ReflectionBounces: 1
38 | m_ReflectionIntensity: 1
39 | m_CustomReflection: {fileID: 0}
40 | m_Sun: {fileID: 0}
41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
42 | --- !u!157 &3
43 | LightmapSettings:
44 | m_ObjectHideFlags: 0
45 | serializedVersion: 11
46 | m_GIWorkflowMode: 0
47 | m_GISettings:
48 | serializedVersion: 2
49 | m_BounceScale: 1
50 | m_IndirectOutputScale: 1
51 | m_AlbedoBoost: 1
52 | m_TemporalCoherenceThreshold: 1
53 | m_EnvironmentLightingMode: 0
54 | m_EnableBakedLightmaps: 1
55 | m_EnableRealtimeLightmaps: 1
56 | m_LightmapEditorSettings:
57 | serializedVersion: 9
58 | m_Resolution: 2
59 | m_BakeResolution: 40
60 | m_TextureWidth: 1024
61 | m_TextureHeight: 1024
62 | m_AO: 0
63 | m_AOMaxDistance: 1
64 | m_CompAOExponent: 1
65 | m_CompAOExponentDirect: 0
66 | m_Padding: 2
67 | m_LightmapParameters: {fileID: 0}
68 | m_LightmapsBakeMode: 1
69 | m_TextureCompression: 1
70 | m_FinalGather: 0
71 | m_FinalGatherFiltering: 1
72 | m_FinalGatherRayCount: 256
73 | m_ReflectionCompression: 2
74 | m_MixedBakeMode: 2
75 | m_BakeBackend: 0
76 | m_PVRSampling: 1
77 | m_PVRDirectSampleCount: 32
78 | m_PVRSampleCount: 500
79 | m_PVRBounces: 2
80 | m_PVRFilterTypeDirect: 0
81 | m_PVRFilterTypeIndirect: 0
82 | m_PVRFilterTypeAO: 0
83 | m_PVRFilteringMode: 1
84 | m_PVRCulling: 1
85 | m_PVRFilteringGaussRadiusDirect: 1
86 | m_PVRFilteringGaussRadiusIndirect: 5
87 | m_PVRFilteringGaussRadiusAO: 2
88 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5
89 | m_PVRFilteringAtrousPositionSigmaIndirect: 2
90 | m_PVRFilteringAtrousPositionSigmaAO: 1
91 | m_LightingDataAsset: {fileID: 0}
92 | m_UseShadowmask: 1
93 | --- !u!196 &4
94 | NavMeshSettings:
95 | serializedVersion: 2
96 | m_ObjectHideFlags: 0
97 | m_BuildSettings:
98 | serializedVersion: 2
99 | agentTypeID: 0
100 | agentRadius: 0.5
101 | agentHeight: 2
102 | agentSlope: 45
103 | agentClimb: 0.4
104 | ledgeDropHeight: 0
105 | maxJumpAcrossDistance: 0
106 | minRegionArea: 2
107 | manualCellSize: 0
108 | cellSize: 0.16666667
109 | manualTileSize: 0
110 | tileSize: 256
111 | accuratePlacement: 0
112 | debug:
113 | m_Flags: 0
114 | m_NavMeshData: {fileID: 0}
115 | --- !u!1 &1729229721
116 | GameObject:
117 | m_ObjectHideFlags: 0
118 | m_PrefabParentObject: {fileID: 0}
119 | m_PrefabInternal: {fileID: 0}
120 | serializedVersion: 5
121 | m_Component:
122 | - component: {fileID: 1729229723}
123 | - component: {fileID: 1729229722}
124 | m_Layer: 0
125 | m_Name: Texture3D preview in Inspector
126 | m_TagString: Untagged
127 | m_Icon: {fileID: 3936346786652291628, guid: 0000000000000000d000000000000000, type: 0}
128 | m_NavMeshLayer: 0
129 | m_StaticEditorFlags: 0
130 | m_IsActive: 1
131 | --- !u!114 &1729229722
132 | MonoBehaviour:
133 | m_ObjectHideFlags: 0
134 | m_PrefabParentObject: {fileID: 0}
135 | m_PrefabInternal: {fileID: 0}
136 | m_GameObject: {fileID: 1729229721}
137 | m_Enabled: 1
138 | m_EditorHideFlags: 0
139 | m_Script: {fileID: 11500000, guid: 308d5e80d1df35543bd2ec9636edd96a, type: 3}
140 | m_Name:
141 | m_EditorClassIdentifier:
142 | texture3D: {fileID: 11700000, guid: 64677355665b5684c822c245cb6a495b, type: 2}
143 | --- !u!4 &1729229723
144 | Transform:
145 | m_ObjectHideFlags: 0
146 | m_PrefabParentObject: {fileID: 0}
147 | m_PrefabInternal: {fileID: 0}
148 | m_GameObject: {fileID: 1729229721}
149 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
150 | m_LocalPosition: {x: 0, y: 0, z: 0}
151 | m_LocalScale: {x: 1, y: 1, z: 1}
152 | m_Children: []
153 | m_Father: {fileID: 0}
154 | m_RootOrder: 0
155 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
156 |
--------------------------------------------------------------------------------
/Assets/Texture3D preview in Inspector.unity.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: febdae0f126b8174e86af88be2bbfdc2
3 | timeCreated: 1507537286
4 | licenseType: Pro
5 | DefaultImporter:
6 | externalObjects: {}
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d16d2cfdf00294d4eb7065e758b27a24
3 | folderAsset: yes
4 | timeCreated: 1507536992
5 | licenseType: Pro
6 | DefaultImporter:
7 | externalObjects: {}
8 | userData:
9 | assetBundleName:
10 | assetBundleVariant:
11 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Attributes.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 17cf46f2ccde500418af03434fb6629d
3 | folderAsset: yes
4 | timeCreated: 1507549806
5 | licenseType: Pro
6 | DefaultImporter:
7 | externalObjects: {}
8 | userData:
9 | assetBundleName:
10 | assetBundleVariant:
11 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Attributes/Texture3DPreviewAttribute.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | ///
4 | /// Attribute enabling Texture3D preview in a Monobehaviour component in the Inspector
5 | ///
6 | public class Texture3DPreviewAttribute : PropertyAttribute
7 | {
8 | #region Members
9 | ///
10 | /// Allows to show the field (when user drags/drops another Texture3D for example) or not (when Texture3D is changed in code only for example)
11 | ///
12 | public readonly bool showField;
13 | #endregion
14 |
15 | #region Constructor
16 | ///
17 | /// Declare this attribute in front of the Texture3D field to enable previewing in a Monobehaviour component in the Inspector
18 | ///
19 | /// Shows or not the Texture3D field on top of the preview (default = true)
20 | public Texture3DPreviewAttribute(bool showField = true)
21 | {
22 | this.showField = showField;
23 | }
24 | #endregion
25 | }
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Attributes/Texture3DPreviewAttribute.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 655fce24071158842896531956f42d6f
3 | timeCreated: 1507549815
4 | licenseType: Pro
5 | MonoImporter:
6 | externalObjects: {}
7 | serializedVersion: 2
8 | defaultReferences: []
9 | executionOrder: 0
10 | icon: {instanceID: 0}
11 | userData:
12 | assetBundleName:
13 | assetBundleVariant:
14 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5a90d828c78ec4c45af1a8fc441309e8
3 | folderAsset: yes
4 | timeCreated: 1507537066
5 | licenseType: Pro
6 | DefaultImporter:
7 | externalObjects: {}
8 | userData:
9 | assetBundleName:
10 | assetBundleVariant:
11 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Drawers.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7fb0cffe903e81840976ed03aaca4141
3 | folderAsset: yes
4 | timeCreated: 1507550383
5 | licenseType: Pro
6 | DefaultImporter:
7 | externalObjects: {}
8 | userData:
9 | assetBundleName:
10 | assetBundleVariant:
11 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Drawers/Texture3DPreviewDrawer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using UnityEditor;
3 | using UnityEngine;
4 |
5 | ///
6 | /// Custom drawer for Texture3DPreview attribute
7 | ///
8 | [CustomPropertyDrawer(typeof(Texture3DPreviewAttribute))]
9 | internal sealed class Texture3DPreviewDrawer : PropertyDrawer
10 | {
11 | #region Members
12 | ///
13 | /// Maximum preview size in the Inspector
14 | ///
15 | private const int _maxSize = 512;
16 | ///
17 | /// The material which the preview will be rendered with
18 | ///
19 | private static Material _material;
20 | ///
21 | /// String to show if the field is not a Texture3D
22 | ///
23 | private const string _notObjectOrTexture3DString = "Texture3DPreview attribute can only be used with Texture3D fields.";
24 | ///
25 | /// The angle of the camera preview
26 | ///
27 | private Vector2 _cameraAngle = new Vector2(127.5f, -22.5f);
28 | ///
29 | /// The raymarch interations
30 | ///
31 | private int _samplingIterations = 64;
32 | ///
33 | /// The factor of the Texture3D
34 | ///
35 | private float _density = 1;
36 | #endregion
37 |
38 | #region Functions
39 | ///
40 | /// Gets if the Texture3D should be displayed
41 | ///
42 | private bool ShowField
43 | {
44 | get
45 | {
46 | return ((Texture3DPreviewAttribute)attribute).showField;
47 | }
48 | }
49 |
50 | ///
51 | /// Checks if the drawn property is a UnityEngine.Object derived type
52 | ///
53 | /// The drawn object
54 | /// True if the drawn object is a UnityEngine.Object derived type, false otherwise
55 | private bool CheckIfObjectType(SerializedProperty property)
56 | {
57 | return property.propertyType == SerializedPropertyType.ObjectReference;
58 | }
59 |
60 | ///
61 | /// Checks if the drawn property is a Texture3D
62 | ///
63 | /// The drawn object
64 | /// True if the drawn object is a Texture3D, false otherwise
65 | private bool CheckIfTexture3D(SerializedProperty property)
66 | {
67 | return property.objectReferenceValue.GetType() == typeof(Texture3D);
68 | }
69 |
70 | ///
71 | /// Checks if the drawn property is null
72 | ///
73 | /// The drawn object
74 | /// True if the drawn object is null, false otherwise
75 | private bool CheckIfNull(SerializedProperty property)
76 | {
77 | return property.objectReferenceValue == null;
78 | }
79 |
80 | ///
81 | /// Computes the size of the preview accordingly to the Inspector width
82 | ///
83 | /// The margin reserved on the right of the preview
84 | /// The size of the preview
85 | private int ComputePreviewSize(int rightMargin)
86 | {
87 | int size = Mathf.FloorToInt(EditorGUIUtility.currentViewWidth) - rightMargin;
88 | size = Mathf.Min(size, Texture3DPreviewDrawer._maxSize);
89 |
90 | return size;
91 | }
92 |
93 | ///
94 | /// Sets back the camera angle
95 | ///
96 | public void ResetPreviewCameraAngle()
97 | {
98 | _cameraAngle = new Vector2(127.5f, -22.5f);
99 | }
100 | #endregion
101 |
102 | #region Overriden base class functions (https://docs.unity3d.com/ScriptReference/PropertyDrawer.html)
103 | ///
104 | /// Sets the height of the custom drawer
105 | ///
106 | /// The drawn object
107 | /// The "made readable" name of the object (as would be seen in the Insprector)
108 | ///
109 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
110 | {
111 | float size = 0;
112 |
113 | if (CheckIfObjectType(property))
114 | {
115 | if (ShowField)
116 | {
117 | size += EditorGUIUtility.singleLineHeight;
118 | }
119 |
120 | if (!CheckIfNull(property))
121 | {
122 | if (CheckIfTexture3D(property))
123 | {
124 | size += EditorGUIUtility.singleLineHeight;
125 | size += ComputePreviewSize((int)EditorGUIUtility.singleLineHeight);
126 | size += EditorGUIUtility.singleLineHeight;
127 | }
128 | else
129 | {
130 | size += EditorGUIUtility.singleLineHeight;
131 | }
132 | }
133 | else
134 | {
135 | size += EditorGUIUtility.singleLineHeight;
136 | }
137 | }
138 | else
139 | {
140 | size += EditorGUIUtility.singleLineHeight;
141 | }
142 |
143 | return size;
144 | }
145 |
146 | ///
147 | /// Fills drawer area
148 | ///
149 | /// The area of the drawer
150 | /// The drawn object
151 | /// The "made readable" name of the object (as would be seen in the Insprector)
152 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
153 | {
154 | if(CheckIfObjectType(property))
155 | {
156 | if(ShowField)
157 | {
158 | Rect rect = position;
159 | rect.height = EditorGUIUtility.singleLineHeight;
160 | EditorGUI.ObjectField(rect, property, typeof(Texture3D));
161 | position.y += EditorGUIUtility.singleLineHeight;
162 | }
163 |
164 | if(!CheckIfNull(property))
165 | {
166 | if(CheckIfTexture3D(property))
167 | {
168 | if (Event.current.type == EventType.Layout)
169 | {
170 | return;
171 | }
172 |
173 | position.y += EditorGUIUtility.singleLineHeight;
174 |
175 | int size = ComputePreviewSize((int)position.x * 2);
176 | Rect drawArea = position;
177 | drawArea.width = size;
178 | drawArea.height = drawArea.width;
179 | drawArea.x += position.width * 0.5f - drawArea.width * 0.5f;
180 |
181 | _cameraAngle = PreviewRenderUtilityHelpers.DragToAngles(_cameraAngle, drawArea);
182 | if (Event.current.type == EventType.Repaint)
183 | {
184 | GUI.Box(drawArea, ((Texture3D)property.objectReferenceValue).RenderTexture3DPreview(drawArea, _cameraAngle, 6.5f /*TODO : Find distance with fov and boundingsphere, when non uniform size will be supported*/, _samplingIterations, _density));
185 | }
186 |
187 | Rect rect = drawArea;
188 | rect.y += drawArea.height;
189 | rect.height = EditorGUIUtility.singleLineHeight;
190 | rect.width = 100; // TODO : not use magic numbers
191 | if (GUI.Button(rect, "Reset Camera", EditorStyles.miniButton))
192 | {
193 | ResetPreviewCameraAngle();
194 | }
195 | rect.x += rect.width;
196 | rect.width = 60; // TODO : not use magic numbers
197 | EditorGUI.LabelField(rect, "Quality :");
198 | rect.x += rect.width;
199 | _samplingIterations = EditorGUI.IntPopup(rect, _samplingIterations, new string[] { "16", "32", "64", "128", "256", "512" }, new int[] { 16, 32, 64, 128, 256, 512 });
200 | rect.x += rect.width;
201 | rect.width = 60; // TODO : not use magic numbers
202 | EditorGUI.LabelField(rect, "Density :");
203 | rect.x += rect.width;
204 | rect.width = drawArea.width - 280; // TODO : not use magic numbers
205 | _density = EditorGUI.Slider(rect, _density, 0, 5);
206 | }
207 | else
208 | {
209 | EditorGUI.LabelField(position, label.text, _notObjectOrTexture3DString, EditorStyles.boldLabel);
210 | }
211 | }
212 | else
213 | {
214 | EditorGUI.LabelField(position, label.text, "Texture3D field is empty.", EditorStyles.boldLabel);
215 | }
216 | }
217 | else
218 | {
219 | EditorGUI.LabelField(position, label.text, _notObjectOrTexture3DString, EditorStyles.boldLabel);
220 | }
221 | }
222 | #endregion
223 | }
224 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Drawers/Texture3DPreviewDrawer.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 52365bda6b1ad8945b713f96ada31cf3
3 | timeCreated: 1507550391
4 | licenseType: Pro
5 | MonoImporter:
6 | externalObjects: {}
7 | serializedVersion: 2
8 | defaultReferences: []
9 | executionOrder: 0
10 | icon: {instanceID: 0}
11 | userData:
12 | assetBundleName:
13 | assetBundleVariant:
14 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Editors.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: bd30b7eb46077044b84d3daf863dada2
3 | folderAsset: yes
4 | timeCreated: 1507537074
5 | licenseType: Pro
6 | DefaultImporter:
7 | externalObjects: {}
8 | userData:
9 | assetBundleName:
10 | assetBundleVariant:
11 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Editors/Texture3DEditor.cs:
--------------------------------------------------------------------------------
1 | using UnityEditor;
2 | using UnityEngine;
3 |
4 | ///
5 | /// Draws a custom Inspector for Texture3D assets
6 | /// Actually, we will draw the default inspector but use the ability to draw a custom preview and render a custom asset's thumbnail
7 | ///
8 | [CustomEditor(typeof(Texture3D))]
9 | public class Texture3DEditor : Editor
10 | {
11 | #region Members
12 | ///
13 | /// The angle of the camera preview
14 | ///
15 | private Vector2 _cameraAngle = new Vector2(127.5f, -22.5f); // This default value will be used when rendering the asset thumbnail (see RenderStaticPreview)
16 | ///
17 | /// The raymarch interations
18 | ///
19 | private int _samplingIterations = 64;
20 | ///
21 | /// The factor of the Texture3D
22 | ///
23 | private float _density = 1;
24 |
25 | //// TODO : Investigate to access those variables as the default inspector is ugly
26 | //private SerializedProperty wrapModeProperty;
27 | //private SerializedProperty filterModeProperty;
28 | //private SerializedProperty anisotropyLevelProperty;
29 | #endregion
30 |
31 | #region Functions
32 | ///
33 | /// Sets back the camera angle
34 | ///
35 | public void ResetPreviewCameraAngle()
36 | {
37 | _cameraAngle = new Vector2(127.5f, -22.5f);
38 | }
39 | #endregion
40 |
41 | #region Overriden base class functions (https://docs.unity3d.com/ScriptReference/Editor.html)
42 | ///
43 | /// Draws the content of the Inspector
44 | ///
45 | public override void OnInspectorGUI()
46 | {
47 | serializedObject.Update();
48 |
49 | //// Had to disable the default Inspector as it makes preview lag
50 | //DrawDefaultInspector();
51 |
52 | serializedObject.ApplyModifiedProperties();
53 | }
54 |
55 | #region Preview
56 | ///
57 | /// Tells if the Object has a custom preview
58 | ///
59 | public override bool HasPreviewGUI()
60 | {
61 | return true;
62 | }
63 |
64 | ///
65 | /// Draws the toolbar area on top of the preview window
66 | ///
67 | public override void OnPreviewSettings()
68 | {
69 | EditorGUILayout.BeginHorizontal();
70 | if (GUILayout.Button("Reset Camera", EditorStyles.miniButton))
71 | {
72 | ResetPreviewCameraAngle();
73 | }
74 | EditorGUILayout.LabelField("Quality", GUILayout.MaxWidth(50));
75 | _samplingIterations = EditorGUILayout.IntPopup(_samplingIterations, new string[] { "16", "32", "64", "128", "256", "512" }, new int[] { 16, 32, 64, 128, 256, 512 }, GUILayout.MaxWidth(50));
76 | EditorGUILayout.LabelField("Density", GUILayout.MaxWidth(50));
77 | _density = EditorGUILayout.Slider(_density, 0, 5, GUILayout.MaxWidth(200));
78 | EditorGUILayout.EndHorizontal();
79 | }
80 |
81 | ///
82 | /// Draws the preview area
83 | ///
84 | /// The area of the preview window
85 | /// The default GUIStyle used for preview windows
86 | public override void OnPreviewGUI(Rect rect, GUIStyle backgroundStyle)
87 | {
88 | _cameraAngle = PreviewRenderUtilityHelpers.DragToAngles(_cameraAngle, rect);
89 |
90 | if (Event.current.type == EventType.Repaint)
91 | {
92 | GUI.DrawTexture(rect, ((Texture3D)serializedObject.targetObject).RenderTexture3DPreview(rect, _cameraAngle, 6.5f /*TODO : Find distance with fov and boundingsphere, when non uniform size will be supported*/, _samplingIterations, _density), ScaleMode.StretchToFill, true);
93 | }
94 | }
95 |
96 | ///
97 | /// Draws the custom preview thumbnail for the asset in the Project window
98 | ///
99 | /// Path of the asset
100 | /// Array of children assets
101 | /// Width of the rendered thumbnail
102 | /// Height of the rendered thumbnail
103 | ///
104 | public override Texture2D RenderStaticPreview(string assetPath, Object[] subAssets, int width, int height)
105 | {
106 | return ((Texture3D)serializedObject.targetObject).RenderTexture3DStaticPreview(new Rect(0, 0, width, height), _cameraAngle, 6.5f /*TODO : Find distance with fov and boundingsphere, when non uniform size will be supported*/, _samplingIterations, _density);
107 | }
108 |
109 | ///
110 | /// Allows to give a custom title to the preview window
111 | ///
112 | ///
113 | public override GUIContent GetPreviewTitle()
114 | {
115 | return new GUIContent(serializedObject.targetObject.name + " preview");
116 | }
117 | #endregion
118 | #endregion
119 | }
120 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Editors/Texture3DEditor.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b71d02dbf285e334299bd880fb64ed52
3 | timeCreated: 1507537081
4 | licenseType: Pro
5 | MonoImporter:
6 | externalObjects: {}
7 | serializedVersion: 2
8 | defaultReferences: []
9 | executionOrder: 0
10 | icon: {instanceID: 0}
11 | userData:
12 | assetBundleName:
13 | assetBundleVariant:
14 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Extensions.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d07e2e4489933074dbe6743c8bb470f5
3 | folderAsset: yes
4 | timeCreated: 1507540102
5 | licenseType: Pro
6 | DefaultImporter:
7 | externalObjects: {}
8 | userData:
9 | assetBundleName:
10 | assetBundleVariant:
11 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Extensions/Texture3DExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | ///
6 | /// Extensions for Texture3D object so we can just invoke functions on them
7 | ///
8 | public static class Texture3DExtensions
9 | {
10 | #region Members
11 | ///
12 | /// The material used to render the Texture3D
13 | ///
14 | private static Material _previewTexture3dMaterial;
15 | ///
16 | /// The texture that will be used for the background
17 | ///
18 | private static Texture2D _backgroundTexture;
19 | ///
20 | /// The GUIStyle that will be used for the background
21 | ///
22 | private static GUIStyle _backgroundGuiStyle;
23 | #endregion
24 |
25 | #region Functions
26 | ///
27 | /// Accessor to the material used to render the Texture3D
28 | ///
29 | private static Material PreviewTexture3dMaterial
30 | {
31 | get
32 | {
33 | if (_previewTexture3dMaterial == null)
34 | {
35 | _previewTexture3dMaterial = new Material(Shader.Find("Hidden/Texture3DPreview"));
36 | }
37 |
38 | return _previewTexture3dMaterial;
39 | }
40 | }
41 |
42 | ///
43 | /// Accessor to the static background texture
44 | ///
45 | public static Texture2D BackgroundTexture
46 | {
47 | get
48 | {
49 | if (_backgroundTexture == null)
50 | {
51 | _backgroundTexture = new Texture2D(1, 1);
52 | _backgroundTexture.SetPixel(0, 0, Color.gray * 0.5f);
53 | _backgroundTexture.Apply();
54 | }
55 |
56 | return _backgroundTexture;
57 | }
58 | }
59 |
60 | ///
61 | /// Accessor to the static background GUIStyle
62 | ///
63 | public static GUIStyle BackgroundGuiStyle
64 | {
65 | get
66 | {
67 | _backgroundGuiStyle = new GUIStyle();
68 | _backgroundGuiStyle.active.background = BackgroundTexture;
69 | _backgroundGuiStyle.focused.background = BackgroundTexture;
70 | _backgroundGuiStyle.hover.background = BackgroundTexture;
71 | _backgroundGuiStyle.normal.background = BackgroundTexture;
72 |
73 | return _backgroundGuiStyle;
74 | }
75 | }
76 |
77 | ///
78 | /// Sets the parameters to the PreviewRenderUtility and calls the rendering
79 | ///
80 | /// The Texture3D to preview
81 | /// The camera angle
82 | /// The distance of the camera to the preview cube
83 | /// The amount of slices used to raymarch in the Texture3D
84 | /// A linear factor to multiply the Texture3D with
85 | private static void RenderInPreviewRenderUtility(Texture3D texture3D, Vector2 angle, float distance, int samplingIterations, float density)
86 | {
87 | PreviewTexture3dMaterial.SetInt("_SamplingQuality", samplingIterations);
88 | PreviewTexture3dMaterial.SetTexture("_MainTex", texture3D);
89 | PreviewTexture3dMaterial.SetFloat("_Density", density);
90 |
91 | PreviewRenderUtilityHelpers.Instance.DrawMesh(MeshHelpers.Cube, Matrix4x4.identity, PreviewTexture3dMaterial, 0);
92 |
93 | PreviewRenderUtilityHelpers.Instance.camera.transform.position = Vector2.zero;
94 | PreviewRenderUtilityHelpers.Instance.camera.transform.rotation = Quaternion.Euler(new Vector3(-angle.y, -angle.x, 0));
95 | PreviewRenderUtilityHelpers.Instance.camera.transform.position = PreviewRenderUtilityHelpers.Instance.camera.transform.forward * -distance;
96 | PreviewRenderUtilityHelpers.Instance.camera.Render();
97 | }
98 |
99 | ///
100 | /// Renders a preview of the Texture3D
101 | ///
102 | /// The Texture3D to preview
103 | /// The area where the preview is located
104 | /// The camera angle
105 | /// The distance of the camera to the preview cube
106 | /// The amount of slices used to raymarch in the Texture3D
107 | /// A linear factor to multiply the Texture3D with
108 | /// A Texture with the preview
109 | public static Texture RenderTexture3DPreview(this Texture3D texture3D, Rect rect, Vector2 angle, float distance, int samplingIterations, float density)
110 | {
111 | PreviewRenderUtilityHelpers.Instance.BeginPreview(rect, BackgroundGuiStyle);
112 |
113 | RenderInPreviewRenderUtility(texture3D, angle, distance, samplingIterations, density);
114 |
115 | return PreviewRenderUtilityHelpers.Instance.EndPreview();
116 | }
117 |
118 | ///
119 | /// Renders a thumbnail of the Texture3D
120 | ///
121 | /// The Texture3D to preview
122 | /// The area where the preview is located
123 | /// The camera angle
124 | /// The distance of the camera to the preview cube
125 | /// The amount of slices used to raymarch in the Texture3D
126 | /// A linear factor to multiply the Texture3D with
127 | /// A Texture2D with the thumbnail
128 | public static Texture2D RenderTexture3DStaticPreview(this Texture3D texture3D, Rect rect, Vector2 angle, float distance, int samplingIterations, float density)
129 | {
130 | PreviewRenderUtilityHelpers.Instance.BeginStaticPreview(rect);
131 |
132 | RenderInPreviewRenderUtility(texture3D, angle, distance, samplingIterations, density);
133 |
134 | return PreviewRenderUtilityHelpers.Instance.EndStaticPreview();
135 | }
136 | #endregion
137 | }
138 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Extensions/Texture3DExtensions.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ab2bc92cbdc8a1c4db19522e6c7e69ed
3 | timeCreated: 1507540112
4 | licenseType: Pro
5 | MonoImporter:
6 | externalObjects: {}
7 | serializedVersion: 2
8 | defaultReferences: []
9 | executionOrder: 0
10 | icon: {instanceID: 0}
11 | userData:
12 | assetBundleName:
13 | assetBundleVariant:
14 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Helpers.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 166ca2da427c87f4695ac884e6b27357
3 | folderAsset: yes
4 | timeCreated: 1507538041
5 | licenseType: Pro
6 | DefaultImporter:
7 | externalObjects: {}
8 | userData:
9 | assetBundleName:
10 | assetBundleVariant:
11 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Helpers/MeshHelpers.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | ///
6 | /// Collection of function/variables related to the Mesh class
7 | ///
8 | public static class MeshHelpers
9 | {
10 | #region Members
11 | ///
12 | /// Just a Cube
13 | ///
14 | private static Mesh _cube;
15 | #endregion
16 |
17 | #region Functions
18 | ///
19 | /// Accessor to the Cube mesh
20 | ///
21 | public static Mesh Cube
22 | {
23 | get
24 | {
25 | if (_cube == null)
26 | {
27 | _cube = CreateCubeMesh(1, 1, 1);
28 | }
29 |
30 | return _cube;
31 | }
32 | }
33 |
34 | ///
35 | /// Creates a scaled Cube (http://wiki.unity3d.com/index.php/ProceduralPrimitives)
36 | ///
37 | /// Size of the cube along the width
38 | /// Size of the cube along the height
39 | /// Size of the cube along the length
40 | /// A mesh representing the scaled cube
41 | public static Mesh CreateCubeMesh(float width, float height, float length)
42 | {
43 | #region Vertices
44 | Vector3 p0 = new Vector3(-width * .5f, -height * .5f, length * .5f);
45 | Vector3 p1 = new Vector3(width * .5f, -height * .5f, length * .5f);
46 | Vector3 p2 = new Vector3(width * .5f, -height * .5f, -length * .5f);
47 | Vector3 p3 = new Vector3(-width * .5f, -height * .5f, -length * .5f);
48 |
49 | Vector3 p4 = new Vector3(-width * .5f, height * .5f, length * .5f);
50 | Vector3 p5 = new Vector3(width * .5f, height * .5f, length * .5f);
51 | Vector3 p6 = new Vector3(width * .5f, height * .5f, -length * .5f);
52 | Vector3 p7 = new Vector3(-width * .5f, height * .5f, -length * .5f);
53 |
54 | Vector3[] vertices = new Vector3[]
55 | {
56 | // Bottom
57 | p0, p1, p2, p3,
58 | // Left
59 | p7, p4, p0, p3,
60 | // Front
61 | p4, p5, p1, p0,
62 | // Back
63 | p6, p7, p3, p2,
64 | // Right
65 | p5, p6, p2, p1,
66 | // Top
67 | p7, p6, p5, p4
68 | };
69 | #endregion
70 |
71 | #region Normales
72 | Vector3 up = Vector3.up;
73 | Vector3 down = Vector3.down;
74 | Vector3 front = Vector3.forward;
75 | Vector3 back = Vector3.back;
76 | Vector3 left = Vector3.left;
77 | Vector3 right = Vector3.right;
78 |
79 | Vector3[] normales = new Vector3[]
80 | {
81 | // Bottom
82 | down, down, down, down,
83 | // Left
84 | left, left, left, left,
85 | // Front
86 | front, front, front, front,
87 | // Back
88 | back, back, back, back,
89 | // Right
90 | right, right, right, right,
91 | // Top
92 | up, up, up, up
93 | };
94 | #endregion
95 |
96 | #region UVs
97 | Vector2 _00 = new Vector2(0f, 0f);
98 | Vector2 _10 = new Vector2(1f, 0f);
99 | Vector2 _01 = new Vector2(0f, 1f);
100 | Vector2 _11 = new Vector2(1f, 1f);
101 |
102 | Vector2[] uvs = new Vector2[]
103 | {
104 | // Bottom
105 | _11, _01, _00, _10,
106 | // Left
107 | _11, _01, _00, _10,
108 | // Front
109 | _11, _01, _00, _10,
110 | // Back
111 | _11, _01, _00, _10,
112 | // Right
113 | _11, _01, _00, _10,
114 | // Top
115 | _11, _01, _00, _10,
116 | };
117 | #endregion
118 |
119 | #region Triangles
120 | int[] triangles = new int[]
121 | {
122 | // Bottom
123 | 3, 1, 0,
124 | 3, 2, 1,
125 | // Left
126 | 3 + 4 * 1, 1 + 4 * 1, 0 + 4 * 1,
127 | 3 + 4 * 1, 2 + 4 * 1, 1 + 4 * 1,
128 | // Front
129 | 3 + 4 * 2, 1 + 4 * 2, 0 + 4 * 2,
130 | 3 + 4 * 2, 2 + 4 * 2, 1 + 4 * 2,
131 | // Back
132 | 3 + 4 * 3, 1 + 4 * 3, 0 + 4 * 3,
133 | 3 + 4 * 3, 2 + 4 * 3, 1 + 4 * 3,
134 | // Right
135 | 3 + 4 * 4, 1 + 4 * 4, 0 + 4 * 4,
136 | 3 + 4 * 4, 2 + 4 * 4, 1 + 4 * 4,
137 | // Top
138 | 3 + 4 * 5, 1 + 4 * 5, 0 + 4 * 5,
139 | 3 + 4 * 5, 2 + 4 * 5, 1 + 4 * 5,
140 | };
141 | #endregion
142 |
143 | Mesh mesh = new Mesh
144 | {
145 | vertices = vertices,
146 | normals = normales,
147 | uv = uvs,
148 | triangles = triangles
149 | };
150 | mesh.RecalculateBounds();
151 |
152 | return mesh;
153 | }
154 | #endregion
155 | }
156 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Helpers/MeshHelpers.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: e35bd3904b6535e44bb0bd59ea64f34f
3 | timeCreated: 1507538546
4 | licenseType: Pro
5 | MonoImporter:
6 | externalObjects: {}
7 | serializedVersion: 2
8 | defaultReferences: []
9 | executionOrder: 0
10 | icon: {instanceID: 0}
11 | userData:
12 | assetBundleName:
13 | assetBundleVariant:
14 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Helpers/PreviewRenderUtilityHelpers.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 | using UnityEditor;
5 |
6 | ///
7 | /// Collection of function/variables related to the PreviewRenderUtility class
8 | ///
9 | public static class PreviewRenderUtilityHelpers
10 | {
11 | #region Members
12 | ///
13 | /// A static copy of the PreviewRenderUtility class
14 | ///
15 | private static PreviewRenderUtility _instance;
16 | #endregion
17 |
18 | #region Functions
19 | ///
20 | /// Accessor to the PreviewRenderUtility instance
21 | ///
22 | public static PreviewRenderUtility Instance
23 | {
24 | get
25 | {
26 | if(_instance == null)
27 | {
28 | _instance = new PreviewRenderUtility();
29 | }
30 |
31 | return _instance;
32 | }
33 | }
34 |
35 | ///
36 | /// Transforms the drag delta of the mouse on the UI into Euler angles
37 | ///
38 | /// Input angles
39 | /// The area where the mouse will be watched
40 | /// The modified angles
41 | public static Vector2 DragToAngles(Vector2 angles, Rect position)
42 | {
43 | int controlID = GUIUtility.GetControlID("DragToAngles".GetHashCode(), FocusType.Passive);
44 | Event current = Event.current;
45 | switch (current.GetTypeForControl(controlID))
46 | {
47 | case EventType.MouseDown:
48 | if (position.Contains(current.mousePosition))
49 | {
50 | GUIUtility.hotControl = controlID;
51 | current.Use();
52 | EditorGUIUtility.SetWantsMouseJumping(1);
53 | }
54 | break;
55 | case EventType.MouseUp:
56 | if (GUIUtility.hotControl == controlID)
57 | {
58 | GUIUtility.hotControl = 0;
59 | }
60 | EditorGUIUtility.SetWantsMouseJumping(0);
61 | break;
62 | case EventType.MouseDrag:
63 | if (GUIUtility.hotControl == controlID)
64 | {
65 | angles -= current.delta / Mathf.Min(position.width, position.height) * 180;
66 | current.Use();
67 | GUI.changed = true;
68 | }
69 | break;
70 | }
71 | return angles;
72 | }
73 | #endregion
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Helpers/PreviewRenderUtilityHelpers.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d0300ebf5601e3b42b54edeff31038d2
3 | timeCreated: 1507538086
4 | licenseType: Pro
5 | MonoImporter:
6 | externalObjects: {}
7 | serializedVersion: 2
8 | defaultReferences: []
9 | executionOrder: 0
10 | icon: {instanceID: 0}
11 | userData:
12 | assetBundleName:
13 | assetBundleVariant:
14 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Shaders.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 53e29d572e55dff45a7c43459f77ba28
3 | folderAsset: yes
4 | timeCreated: 1507540236
5 | licenseType: Pro
6 | DefaultImporter:
7 | externalObjects: {}
8 | userData:
9 | assetBundleName:
10 | assetBundleVariant:
11 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Shaders/Texture3DPreviewShader.shader:
--------------------------------------------------------------------------------
1 | Shader "Hidden/Texture3DPreview"
2 | {
3 | SubShader
4 | {
5 | Tags
6 | {
7 | "Queue" = "Transparent"
8 | }
9 |
10 | CGINCLUDE
11 | #include "UnityCG.cginc"
12 |
13 | int _SamplingQuality;
14 | sampler3D _MainTex;
15 | float _Density;
16 |
17 | struct v2f
18 | {
19 | float4 pos : SV_POSITION;
20 | float3 localPos : TEXCOORD0;
21 | float4 screenPos : TEXCOORD1;
22 | float3 worldPos : TEXCOORD2;
23 | };
24 |
25 | v2f vert(appdata_base v)
26 | {
27 | v2f OUT;
28 | OUT.pos = UnityObjectToClipPos(v.vertex);
29 | OUT.localPos = v.vertex.xyz;
30 | OUT.screenPos = ComputeScreenPos(OUT.pos);
31 | COMPUTE_EYEDEPTH(OUT.screenPos.z);
32 | OUT.worldPos = mul(unity_ObjectToWorld, v.vertex);
33 | return OUT;
34 | }
35 |
36 | // usual ray/cube intersection algorithm
37 | struct Ray
38 | {
39 | float3 origin;
40 | float3 direction;
41 | };
42 | bool IntersectBox(Ray ray, out float entryPoint, out float exitPoint)
43 | {
44 | float3 invR = 1.0 / ray.direction;
45 | float3 tbot = invR * (float3(-0.5, -0.5, -0.5) - ray.origin);
46 | float3 ttop = invR * (float3(0.5, 0.5, 0.5) - ray.origin);
47 | float3 tmin = min(ttop, tbot);
48 | float3 tmax = max(ttop, tbot);
49 | float2 t = max(tmin.xx, tmin.yz);
50 | entryPoint = max(t.x, t.y);
51 | t = min(tmax.xx, tmax.yz);
52 | exitPoint = min(t.x, t.y);
53 | return entryPoint <= exitPoint;
54 | }
55 |
56 | float4 frag(v2f IN) : COLOR
57 | {
58 | float3 localCameraPosition = UNITY_MATRIX_IT_MV[3].xyz;
59 |
60 | Ray ray;
61 | ray.origin = localCameraPosition;
62 | ray.direction = normalize(IN.localPos - localCameraPosition);
63 |
64 | float entryPoint, exitPoint;
65 | IntersectBox(ray, entryPoint, exitPoint);
66 |
67 | if (entryPoint < 0.0) entryPoint = 0.0;
68 |
69 | float3 rayStart = ray.origin + ray.direction * entryPoint;
70 | float3 rayStop = ray.origin + ray.direction * exitPoint;
71 |
72 | float3 start = rayStop;
73 | float dist = distance(rayStop, rayStart);
74 | float stepSize = dist / float(_SamplingQuality);
75 | float3 ds = normalize(rayStop - rayStart) * stepSize;
76 |
77 | float4 color = float4(0,0,0,0);
78 | for (int i = _SamplingQuality; i >= 0; --i)
79 | {
80 | float3 pos = start.xyz;
81 | pos.xyz = pos.xyz + 0.5f;
82 | float4 mask = tex3D(_MainTex, pos);
83 |
84 | color.xyz += mask.xyz * mask.w;
85 |
86 | start -= ds;
87 | }
88 | color *= _Density / (uint)_SamplingQuality;
89 |
90 | // Weird enough, bruteforce seems quicker (to be investigated)
91 | //const float maxDist = 0.86602540378443864676372317075294f;
92 | //float stepSize = maxDist / (float)_SamplingQuality;
93 | //float dist = distance(rayStop, rayStart);
94 | //int steps = ceil(dist / stepSize);
95 | //float3 ds = normalize(rayStop - rayStart) * stepSize;
96 | //float3 color = float3(0,0,0);
97 | //[unroll(512)]
98 | //for (int i = steps; i >= 0; --i)
99 | //{
100 | // float3 pos = start.xyz;
101 | // pos.xyz = pos.xyz + 0.5f;
102 | // float4 mask = tex3D(_MainTex, pos);
103 | //
104 | // color += mask.xyz * mask.w;
105 | //
106 | // start += ds;
107 | //}
108 | //color *= _Density / steps;
109 |
110 | return color;
111 | }
112 | ENDCG
113 |
114 | Pass
115 | {
116 | Cull front
117 | Blend One One
118 | ZWrite false
119 |
120 | CGPROGRAM
121 | #pragma target 3.0
122 | #pragma vertex vert
123 | #pragma fragment frag
124 | ENDCG
125 |
126 | }
127 | }
128 | }
--------------------------------------------------------------------------------
/Assets/Texture3DPreview/Editor/Shaders/Texture3DPreviewShader.shader.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5433510e20cd33045a8a47556dc6f366
3 | timeCreated: 1507540266
4 | licenseType: Pro
5 | ShaderImporter:
6 | externalObjects: {}
7 | defaultTextures: []
8 | userData:
9 | assetBundleName:
10 | assetBundleVariant:
11 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreviewInInspector.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | public class Texture3DPreviewInInspector : MonoBehaviour
6 | {
7 | [Texture3DPreview]
8 | public Texture3D texture3D;
9 | }
10 |
--------------------------------------------------------------------------------
/Assets/Texture3DPreviewInInspector.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 308d5e80d1df35543bd2ec9636edd96a
3 | timeCreated: 1507629441
4 | licenseType: Pro
5 | MonoImporter:
6 | externalObjects: {}
7 | serializedVersion: 2
8 | defaultReferences:
9 | - texture3D: {fileID: 11700000, guid: 64677355665b5684c822c245cb6a495b, type: 2}
10 | executionOrder: 0
11 | icon: {instanceID: 0}
12 | userData:
13 | assetBundleName:
14 | assetBundleVariant:
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # **[Texture3D](https://docs.unity3d.com/ScriptReference/Texture3D.html) preview for [Unity](https://unity3d.com)**
2 |
3 | ## This package enables interactive previews of [Texture3D](https://docs.unity3d.com/ScriptReference/Texture3D.html) assets in Unity's Inspector window.
4 |
5 | **[You can directly download the Unity package by clicking here or by going in the Release section](https://github.com/raphael-ernaelsten/Texture3DPreview-for-Unity/releases)**
6 |
7 | ----------
8 |
9 | ### Previews and thumbnails of [Texture3D](https://docs.unity3d.com/ScriptReference/Texture3D.html) asset
10 |
11 | When importing the Texture3D asset, Unity will automatically render a preview of the Texture3D to display in the Project window.
12 |
13 | 
14 |
15 | When selecting a Texture3D asset in the Project windows, Unity will display an preview of the Texture3D in the Inspector.
16 |
17 | 
18 |
19 | ----------
20 |
21 | ### Previews of a [Texture3D](https://docs.unity3d.com/ScriptReference/Texture3D.html) field on a GameObject's component
22 |
23 | To enable Texture3D field preview on a GameObject's component, add
24 |
25 | [Texture3DPreview]
26 | in front of the declared field.
27 |
28 | 
29 |
30 | ----------
31 |
32 | ### Requirements
33 |
34 | - Shader model 3 capable graphic card
35 | - Unity 2017.1+
36 |
37 | ----------
38 |
39 | ### TODO
40 |
41 | - Preview non uniform Texture3D in their respective ratio (currently all previews will be cube)
42 | - Add alpha blend mode for rendering previews
43 |
44 | ----------
45 |
46 | ### Know issues / limitations
47 |
48 | - Previews are currently in additive mode
49 | - Previews of multiples Texture3D assets don't work
50 | - Sometimes, the preview of a Texture3D field becomes empty
51 |
52 | ----------
53 |
54 | ### Contact
55 |
56 | Feel free to contact me for any comment or suggestion. Twitter : @raphernaelsten
57 |
58 | ----------
59 |
60 | ### Acknowledgment
61 |
62 | The sample Texture3D asset provided with this package was made using [MRI scans found on this website](https://neil.fraser.name/news/2007/11/19/).
63 |
64 | Here's the process :
65 | - selected [the right-to-left gif](https://neil.fraser.name/news/2007/RL.gif)
66 | - rescaled it to 128x128 and extracted all the frames using [VirtualDub](http://www.virtualdub.org/)
67 | - used [Unity's VFX Toolbox Image Sequencer](https://forum.unity.com/threads/release-thread-vfx-toolbox-image-sequencer.438465/) to resample the frames count and lay them on an images sheet
68 | 
69 | - used a custom tool to build a Texture3D (basically create a Texture3D with the correct size then copy the images from the sheet as slices) from this sheet and save it as an asset
70 |
--------------------------------------------------------------------------------