A game about forced loneliness, made by TACStudios
1using System;
2using UnityEditor.SceneManagement;
3using UnityEngine;
4using UnityEngine.Rendering;
5using UnityEngine.SceneManagement;
6
7namespace UnityEditor.ShaderGraph.Drawing
8{
9 class MaterialGraphPreviewGenerator : IDisposable
10 {
11 private readonly Scene m_Scene;
12 static Mesh s_Quad;
13 private Camera m_Camera;
14 private Light Light0 { get; set; }
15 private Light Light1 { get; set; }
16
17 private Material m_CheckerboardMaterial;
18
19 private static readonly Mesh[] s_Meshes = { null, null, null, null, null };
20 private static readonly GUIContent[] s_MeshIcons = { null, null, null, null, null };
21 private static readonly GUIContent[] s_LightIcons = { null, null };
22 private static readonly GUIContent[] s_TimeIcons = { null, null };
23
24 protected static GameObject CreateLight()
25 {
26 GameObject lightGO = EditorUtility.CreateGameObjectWithHideFlags("PreRenderLight", HideFlags.HideAndDontSave, typeof(Light));
27 var light = lightGO.GetComponent<Light>();
28 light.type = LightType.Directional;
29 light.intensity = 1.0f;
30 light.enabled = false;
31 return lightGO;
32 }
33
34 public MaterialGraphPreviewGenerator()
35 {
36 m_Scene = EditorSceneManager.NewPreviewScene();
37 var camGO = EditorUtility.CreateGameObjectWithHideFlags("Preview Scene Camera", HideFlags.HideAndDontSave, typeof(Camera));
38 SceneManager.MoveGameObjectToScene(camGO, m_Scene);
39
40 m_Camera = camGO.GetComponent<Camera>();
41 EditorUtility.SetCameraAnimateMaterials(m_Camera, true);
42
43 m_Camera.cameraType = CameraType.Preview;
44 m_Camera.enabled = false;
45 m_Camera.clearFlags = CameraClearFlags.Depth;
46 m_Camera.fieldOfView = 15;
47 m_Camera.farClipPlane = 10.0f;
48 m_Camera.nearClipPlane = 2.0f;
49 m_Camera.backgroundColor = new Color(49.0f / 255.0f, 49.0f / 255.0f, 49.0f / 255.0f, 1.0f);
50
51 // Explicitly use forward rendering for all previews
52 // (deferred fails when generating some static previews at editor launch; and we never want
53 // vertex lit previews if that is chosen in the player settings)
54 m_Camera.renderingPath = RenderingPath.Forward;
55 m_Camera.useOcclusionCulling = false;
56 m_Camera.scene = m_Scene;
57
58 var l0 = CreateLight();
59 SceneManager.MoveGameObjectToScene(l0, m_Scene);
60
61 //previewScene.AddGameObject(l0);
62 Light0 = l0.GetComponent<Light>();
63
64 var l1 = CreateLight();
65 SceneManager.MoveGameObjectToScene(l1, m_Scene);
66
67 //previewScene.AddGameObject(l1);
68 Light1 = l1.GetComponent<Light>();
69
70 Light0.color = new Color(0.769f, 0.769f, 0.769f, 1); // SceneView.kSceneViewFrontLight
71 Light1.transform.rotation = Quaternion.Euler(340, 218, 177);
72 Light1.color = new Color(.4f, .4f, .45f, 0f) * .7f;
73
74 m_CheckerboardMaterial = new Material(Shader.Find("Hidden/Checkerboard"));
75 m_CheckerboardMaterial.shader.hideFlags = HideFlags.HideAndDontSave;
76 m_CheckerboardMaterial.hideFlags = HideFlags.HideAndDontSave;
77
78 if (s_Meshes[0] == null)
79 {
80 var handleGo = (GameObject)EditorGUIUtility.LoadRequired("Previews/PreviewMaterials.fbx");
81
82 // @TODO: temp workaround to make it not render in the scene
83 handleGo.SetActive(false);
84 foreach (Transform t in handleGo.transform)
85 {
86 var meshFilter = t.GetComponent<MeshFilter>();
87 switch (t.name)
88 {
89 case "sphere":
90 s_Meshes[0] = meshFilter.sharedMesh;
91 break;
92 case "cube":
93 s_Meshes[1] = meshFilter.sharedMesh;
94 break;
95 case "cylinder":
96 s_Meshes[2] = meshFilter.sharedMesh;
97 break;
98 case "torus":
99 s_Meshes[3] = meshFilter.sharedMesh;
100 break;
101 default:
102 Debug.LogWarning("Something is wrong, weird object found: " + t.name);
103 break;
104 }
105 }
106
107 s_MeshIcons[0] = EditorGUIUtility.IconContent("PreMatSphere");
108 s_MeshIcons[1] = EditorGUIUtility.IconContent("PreMatCube");
109 s_MeshIcons[2] = EditorGUIUtility.IconContent("PreMatCylinder");
110 s_MeshIcons[3] = EditorGUIUtility.IconContent("PreMatTorus");
111 s_MeshIcons[4] = EditorGUIUtility.IconContent("PreMatQuad");
112
113 s_LightIcons[0] = EditorGUIUtility.IconContent("PreMatLight0");
114 s_LightIcons[1] = EditorGUIUtility.IconContent("PreMatLight1");
115
116 s_TimeIcons[0] = EditorGUIUtility.IconContent("PlayButton");
117 s_TimeIcons[1] = EditorGUIUtility.IconContent("PauseButton");
118
119 Mesh quadMesh = Resources.GetBuiltinResource(typeof(Mesh), "Quad.fbx") as Mesh;
120 s_Meshes[4] = quadMesh;
121 }
122 }
123
124 public static Mesh quad
125 {
126 get
127 {
128 if (s_Quad != null)
129 return s_Quad;
130
131 var vertices = new[]
132 {
133 new Vector3(-1f, -1f, 0f),
134 new Vector3(1f, 1f, 0f),
135 new Vector3(1f, -1f, 0f),
136 new Vector3(-1f, 1f, 0f)
137 };
138
139 var uvs = new[]
140 {
141 new Vector2(0f, 0f),
142 new Vector2(1f, 1f),
143 new Vector2(1f, 0f),
144 new Vector2(0f, 1f)
145 };
146
147 var indices = new[] { 0, 1, 2, 1, 0, 3 };
148
149 s_Quad = new Mesh
150 {
151 vertices = vertices,
152 uv = uvs,
153 triangles = indices
154 };
155 s_Quad.RecalculateNormals();
156 s_Quad.RecalculateBounds();
157
158 return s_Quad;
159 }
160 }
161
162 public void DoRenderPreview(RenderTexture renderTexture, Material mat, Mesh mesh, PreviewMode mode, bool allowSRP, float time, MaterialPropertyBlock properties = null)
163 {
164 if (mat == null || mat.shader == null)
165 return;
166
167 m_Camera.targetTexture = renderTexture;
168 if (mode == PreviewMode.Preview3D)
169 {
170 m_Camera.transform.position = -Vector3.forward * 5;
171 m_Camera.transform.rotation = Quaternion.identity;
172 m_Camera.orthographic = false;
173 }
174 else
175 {
176 m_Camera.transform.position = -Vector3.forward * 2;
177 m_Camera.transform.rotation = Quaternion.identity;
178 m_Camera.orthographicSize = 1;
179 m_Camera.orthographic = true;
180 }
181
182 m_Camera.targetTexture = renderTexture;
183 var previousRenderTexure = RenderTexture.active;
184 RenderTexture.active = renderTexture;
185 GL.Clear(true, true, Color.black);
186 Graphics.Blit(Texture2D.whiteTexture, renderTexture, m_CheckerboardMaterial);
187
188 EditorUtility.SetCameraAnimateMaterialsTime(m_Camera, time);
189 Light0.enabled = true;
190 Light0.intensity = 1.0f;
191 Light0.transform.rotation = Quaternion.Euler(50f, 50f, 0);
192 Light1.enabled = true;
193 Light1.intensity = 1.0f;
194 m_Camera.clearFlags = CameraClearFlags.Depth;
195
196 Mesh previewMesh = mesh == null ? s_Meshes[0] : mesh;
197
198 Graphics.DrawMesh(
199 mode == PreviewMode.Preview3D ? previewMesh : quad,
200 mode == PreviewMode.Preview3D ? Matrix4x4.TRS(-previewMesh.bounds.center, Quaternion.identity, Vector3.one) : Matrix4x4.identity,
201 mat,
202 1,
203 m_Camera,
204 0,
205 properties,
206 ShadowCastingMode.Off,
207 false,
208 null,
209 false);
210
211 var oldAllowPipes = Unsupported.useScriptableRenderPipeline;
212 Unsupported.useScriptableRenderPipeline = allowSRP;
213 m_Camera.Render();
214 Unsupported.useScriptableRenderPipeline = oldAllowPipes;
215
216 RenderTexture.active = previousRenderTexure;
217
218 Light0.enabled = false;
219 Light1.enabled = false;
220 }
221
222 public void Dispose()
223 {
224 if (Light0 != null)
225 {
226 UnityEngine.Object.DestroyImmediate(Light0.gameObject);
227 Light0 = null;
228 }
229
230 if (Light1 != null)
231 {
232 UnityEngine.Object.DestroyImmediate(Light1.gameObject);
233 Light1 = null;
234 }
235
236 if (m_Camera != null)
237 {
238 UnityEngine.Object.DestroyImmediate(m_Camera.gameObject);
239 m_Camera = null;
240 }
241
242 if (m_CheckerboardMaterial != null)
243 {
244 UnityEngine.Object.DestroyImmediate(m_CheckerboardMaterial);
245 m_CheckerboardMaterial = null;
246 }
247
248 EditorSceneManager.ClosePreviewScene(m_Scene);
249 }
250 }
251}