public static Texture2D GenerateModelPreviewWithShader(Transform model, Shader shader, string replacementTag, int width = 64, int height = 64, bool shouldCloneModel = false) { if (!model) { return(null); } Texture2D result = null; if (!model.gameObject.scene.IsValid() || !model.gameObject.scene.isLoaded) { shouldCloneModel = true; } Transform previewObject; if (shouldCloneModel) { previewObject = (Transform)Object.Instantiate(model, null, false); previewObject.gameObject.hideFlags = HideFlags.HideAndDontSave; } else { previewObject = model; layersList.Clear(); GetLayerRecursively(previewObject); } bool isStatic = IsStatic(model); bool wasActive = previewObject.gameObject.activeSelf; Vector3 prevPos = previewObject.position; Quaternion prevRot = previewObject.rotation; try { SetupCamera(); SetLayerRecursively(previewObject); if (!isStatic) { previewObject.position = PREVIEW_POSITION; previewObject.rotation = Quaternion.identity; } if (!wasActive) { previewObject.gameObject.SetActive(true); } Vector3 previewDir = previewObject.rotation * m_previewDirection; renderersList.Clear(); previewObject.GetComponentsInChildren(renderersList); Bounds previewBounds = new Bounds(); bool init = false; for (int i = 0; i < renderersList.Count; i++) { if (!renderersList[i].enabled) { continue; } if (!init) { previewBounds = renderersList[i].bounds; init = true; } else { previewBounds.Encapsulate(renderersList[i].bounds); } } if (!init) { return(null); } boundsCenter = previewBounds.center; Vector3 boundsExtents = previewBounds.extents; Vector3 boundsSize = 2f * boundsExtents; aspect = (float)width / height; renderCamera.aspect = aspect; renderCamera.transform.rotation = Quaternion.LookRotation(previewDir, previewObject.up); #if DEBUG_BOUNDS boundsDebugCubes.Clear(); #endif float distance; if (m_orthographicMode) { renderCamera.transform.position = boundsCenter; minX = minY = Mathf.Infinity; maxX = maxY = Mathf.NegativeInfinity; Vector3 point = boundsCenter + boundsExtents; ProjectBoundingBoxMinMax(point); point.x -= boundsSize.x; ProjectBoundingBoxMinMax(point); point.y -= boundsSize.y; ProjectBoundingBoxMinMax(point); point.x += boundsSize.x; ProjectBoundingBoxMinMax(point); point.z -= boundsSize.z; ProjectBoundingBoxMinMax(point); point.x -= boundsSize.x; ProjectBoundingBoxMinMax(point); point.y += boundsSize.y; ProjectBoundingBoxMinMax(point); point.x += boundsSize.x; ProjectBoundingBoxMinMax(point); distance = boundsExtents.magnitude + 1f; renderCamera.orthographicSize = (1f + m_padding * 2f) * Mathf.Max(maxY - minY, (maxX - minX) / aspect) * 0.5f; } else { projectionPlaneHorizontal = new ProjectionPlane(renderCamera.transform.up, boundsCenter); projectionPlaneVertical = new ProjectionPlane(renderCamera.transform.right, boundsCenter); maxDistance = Mathf.NegativeInfinity; Vector3 point = boundsCenter + boundsExtents; CalculateMaxDistance(point); point.x -= boundsSize.x; CalculateMaxDistance(point); point.y -= boundsSize.y; CalculateMaxDistance(point); point.x += boundsSize.x; CalculateMaxDistance(point); point.z -= boundsSize.z; CalculateMaxDistance(point); point.x -= boundsSize.x; CalculateMaxDistance(point); point.y += boundsSize.y; CalculateMaxDistance(point); point.x += boundsSize.x; CalculateMaxDistance(point); distance = (1f + m_padding * 2f) * Mathf.Sqrt(maxDistance); } renderCamera.transform.position = boundsCenter - previewDir * distance; renderCamera.farClipPlane = distance * 4f; RenderTexture temp = RenderTexture.active; RenderTexture renderTex = RenderTexture.GetTemporary(width, height, 16); RenderTexture.active = renderTex; if (m_backgroundColor.a < 1f) { GL.Clear(false, true, m_backgroundColor); } renderCamera.targetTexture = renderTex; if (shader == null) { renderCamera.Render(); } else { renderCamera.RenderWithShader(shader, replacementTag == null ? string.Empty : replacementTag); } renderCamera.targetTexture = null; result = new Texture2D(width, height, m_backgroundColor.a < 1f ? TextureFormat.RGBA32 : TextureFormat.RGB24, false); result.ReadPixels(new Rect(0, 0, width, height), 0, 0, false); result.Apply(false, m_markTextureNonReadable); RenderTexture.active = temp; RenderTexture.ReleaseTemporary(renderTex); } catch (Exception e) { Debug.LogException(e); } finally { #if DEBUG_BOUNDS for (int i = 0; i < boundsDebugCubes.Count; i++) { Object.DestroyImmediate(boundsDebugCubes[i].gameObject); } boundsDebugCubes.Clear(); #endif if (shouldCloneModel) { Object.DestroyImmediate(previewObject.gameObject); } else { if (!wasActive) { previewObject.gameObject.SetActive(false); } if (!isStatic) { previewObject.position = prevPos; previewObject.rotation = prevRot; } int index = 0; SetLayerRecursively(previewObject, ref index); } if (renderCamera == m_previewRenderCamera) { cameraSetup.ApplySetup(renderCamera); } } return(result); }
public static Texture2D GenerateModel(Transform model, int width = 64, int height = 64) { if (model == null || model.Equals(null)) { return(null); } Texture2D result = null; Transform previewObject; previewObject = (Transform)Object.Instantiate(model, null, false); previewObject.gameObject.hideFlags = HideFlags.HideAndDontSave; SceneManager.MoveGameObjectToScene(previewObject.gameObject, m_Scene); previewObject.transform.position = Vector3.zero; bool wasActive = previewObject.gameObject.activeSelf; Vector3 prevPos = previewObject.position; Quaternion prevRot = previewObject.rotation; try { SetupCamera(); SetLayerRecursively(previewObject); if (!wasActive) { previewObject.gameObject.SetActive(true); } Vector3 previewDir = previewObject.rotation * m_previewDirection; renderersList.Clear(); previewObject.GetComponentsInChildren(renderersList); Bounds previewBounds = new Bounds(); bool init = false; for (int i = 0; i < renderersList.Count; i++) { if (!renderersList[i].enabled) { continue; } if (!init) { previewBounds = renderersList[i].bounds; init = true; } else { previewBounds.Encapsulate(renderersList[i].bounds); } } if (!init) { return(null); } boundsCenter = previewBounds.center; Vector3 boundsExtents = previewBounds.extents; Vector3 boundsSize = 2f * boundsExtents; aspect = (float)width / height; renderCamera.aspect = aspect; renderCamera.transform.rotation = Quaternion.LookRotation(previewDir, previewObject.up); float distance; if (OrthographicMode) { renderCamera.transform.position = boundsCenter; minX = minY = Mathf.Infinity; maxX = maxY = Mathf.NegativeInfinity; Vector3 point = boundsCenter + boundsExtents; ProjectBoundingBoxMinMax(point); point.x -= boundsSize.x; ProjectBoundingBoxMinMax(point); point.y -= boundsSize.y; ProjectBoundingBoxMinMax(point); point.x += boundsSize.x; ProjectBoundingBoxMinMax(point); point.z -= boundsSize.z; ProjectBoundingBoxMinMax(point); point.x -= boundsSize.x; ProjectBoundingBoxMinMax(point); point.y += boundsSize.y; ProjectBoundingBoxMinMax(point); point.x += boundsSize.x; ProjectBoundingBoxMinMax(point); distance = boundsExtents.magnitude + 1f; renderCamera.orthographicSize = (1f + m_padding * 2f) * Mathf.Max(maxY - minY, (maxX - minX) / aspect) * 0.5f; } else { projectionPlaneHorizontal = new ProjectionPlane(renderCamera.transform.up, boundsCenter); projectionPlaneVertical = new ProjectionPlane(renderCamera.transform.right, boundsCenter); maxDistance = Mathf.NegativeInfinity; Vector3 point = boundsCenter + boundsExtents; CalculateMaxDistance(point); point.x -= boundsSize.x; CalculateMaxDistance(point); point.y -= boundsSize.y; CalculateMaxDistance(point); point.x += boundsSize.x; CalculateMaxDistance(point); point.z -= boundsSize.z; CalculateMaxDistance(point); point.x -= boundsSize.x; CalculateMaxDistance(point); point.y += boundsSize.y; CalculateMaxDistance(point); point.x += boundsSize.x; CalculateMaxDistance(point); distance = (1f + m_padding * 2f) * Mathf.Sqrt(maxDistance); } renderCamera.transform.position = boundsCenter - previewDir * distance; renderCamera.farClipPlane = distance * 4f; RenderTexture temp = RenderTexture.active; RenderTexture renderTex = RenderTexture.GetTemporary(width, height, 16); RenderTexture.active = renderTex; if (TransparentBackground) { GL.Clear(false, true, BackgroundColor); } renderCamera.targetTexture = renderTex; renderCamera.Render(); renderCamera.targetTexture = null; result = new Texture2D(width, height, TransparentBackground ? TextureFormat.RGBA32 : TextureFormat.RGB24, false); result.ReadPixels(new Rect(0, 0, width, height), 0, 0, false); result.Apply(false, true); RenderTexture.active = temp; RenderTexture.ReleaseTemporary(renderTex); } catch (Exception e) { Debug.LogException(e); } finally { Object.DestroyImmediate(previewObject.gameObject); if (renderCamera == PreviewRenderCamera) { cameraSetup.ApplySetup(renderCamera); } } return(result); }
public static Texture2D GenerateModelPreviewWithShader(Transform model, Shader shader, String replacementTag, Int32 width = 64, Int32 height = 64, Boolean shouldCloneModel = false, Vector3 planetRotation = new Vector3(), Vector2 lightDirection = new Vector2(), Color?lightColor = null) { if (model == null || model.Equals(null)) { return(null); } GameObject lightObject = new GameObject(); Light light = lightObject.AddOrGetComponent <Light>(); lightObject.transform.position = model.position + new Vector3(0, 0, -36); light.intensity = 1.5f; light.shadowBias = 0.047f; light.shadows = LightShadows.Soft; light.type = LightType.Directional; light.color = lightColor ?? Color.white; lightObject.transform.RotateAround(model.position, Vector3.right, lightDirection.x); lightObject.transform.RotateAround(model.position, Vector3.down, lightDirection.y); lightObject.transform.rotation = Quaternion.LookRotation(model.position - lightObject.transform.position, lightObject.transform.up); Texture2D result = null; if (!model.gameObject.scene.IsValid() || !model.gameObject.scene.isLoaded) { shouldCloneModel = true; } Transform previewObject; if (shouldCloneModel) { previewObject = Object.Instantiate(model, null, false); previewObject.gameObject.hideFlags = HideFlags.HideAndDontSave; } else { previewObject = model; layersList.Clear(); GetLayerRecursively(previewObject); } Boolean isStatic = IsStatic(model); Boolean wasActive = previewObject.gameObject.activeSelf; Vector3 prevPos = previewObject.position; Quaternion prevRot = previewObject.rotation; try { SetupCamera(); SetLayerRecursively(previewObject); if (!isStatic) { previewObject.position = PREVIEW_POSITION; previewObject.rotation = Quaternion.identity; } if (!wasActive) { previewObject.gameObject.SetActive(true); } Vector3 previewDir = previewObject.rotation * m_previewDirection; renderersList.Clear(); previewObject.GetComponentsInChildren(renderersList); Bounds previewBounds = new Bounds(); Boolean init = false; for (Int32 i = 0; i < renderersList.Count; i++) { if (!renderersList[i].enabled) { continue; } if (!init) { previewBounds = renderersList[i].bounds; init = true; } else { previewBounds.Encapsulate(renderersList[i].bounds); } } if (!init) { Object.DestroyImmediate(lightObject); return(null); } boundsCenter = previewBounds.center; Vector3 boundsExtents = previewBounds.extents; Vector3 boundsSize = 2f * boundsExtents; Vector3 up = previewObject.up; previewObject.eulerAngles = previewObject.eulerAngles + planetRotation; aspect = (Single)width / height; renderCamera.aspect = aspect; renderCamera.transform.rotation = Quaternion.LookRotation(previewDir, up); Single distance; if (m_orthographicMode) { renderCamera.transform.position = boundsCenter; minX = minY = Mathf.Infinity; maxX = maxY = Mathf.NegativeInfinity; Vector3 point = boundsCenter + boundsExtents; ProjectBoundingBoxMinMax(point); point.x -= boundsSize.x; ProjectBoundingBoxMinMax(point); point.y -= boundsSize.y; ProjectBoundingBoxMinMax(point); point.x += boundsSize.x; ProjectBoundingBoxMinMax(point); point.z -= boundsSize.z; ProjectBoundingBoxMinMax(point); point.x -= boundsSize.x; ProjectBoundingBoxMinMax(point); point.y += boundsSize.y; ProjectBoundingBoxMinMax(point); point.x += boundsSize.x; ProjectBoundingBoxMinMax(point); distance = boundsExtents.magnitude + 1f; renderCamera.orthographicSize = (1f + m_padding * 2f) * Mathf.Max(maxY - minY, (maxX - minX) / aspect) * 0.5f; } else { projectionPlaneHorizontal = new ProjectionPlane(renderCamera.transform.up, boundsCenter); projectionPlaneVertical = new ProjectionPlane(renderCamera.transform.right, boundsCenter); maxDistance = Mathf.NegativeInfinity; Vector3 point = boundsCenter + boundsExtents; CalculateMaxDistance(point); point.x -= boundsSize.x; CalculateMaxDistance(point); point.y -= boundsSize.y; CalculateMaxDistance(point); point.x += boundsSize.x; CalculateMaxDistance(point); point.z -= boundsSize.z; CalculateMaxDistance(point); point.x -= boundsSize.x; CalculateMaxDistance(point); point.y += boundsSize.y; CalculateMaxDistance(point); point.x += boundsSize.x; CalculateMaxDistance(point); distance = (1f + m_padding * 2f) * Mathf.Sqrt(maxDistance); } renderCamera.transform.position = boundsCenter - previewDir * distance; renderCamera.farClipPlane = distance * 4f; RenderTexture temp = RenderTexture.active; RenderTexture renderTex = RenderTexture.GetTemporary(width, height, 16); RenderTexture.active = renderTex; if (m_transparentBackground) { GL.Clear(false, true, Color.clear); } renderCamera.targetTexture = renderTex; if (shader == null) { renderCamera.Render(); } else { renderCamera.RenderWithShader(shader, replacementTag ?? String.Empty); } renderCamera.targetTexture = null; result = new Texture2D(width, height, m_transparentBackground ? TextureFormat.RGBA32 : TextureFormat.RGB24, false); result.ReadPixels(new Rect(0, 0, width, height), 0, 0, false); result.Apply(false, false); RenderTexture.active = temp; RenderTexture.ReleaseTemporary(renderTex); } catch (Exception e) { Debug.LogException(e); } finally { if (shouldCloneModel) { Object.DestroyImmediate(previewObject.gameObject); } else { if (!wasActive) { previewObject.gameObject.SetActive(false); } if (!isStatic) { previewObject.position = prevPos; previewObject.rotation = prevRot; } Int32 index = 0; SetLayerRecursively(previewObject, ref index); } if (renderCamera == m_previewRenderCamera) { cameraSetup.ApplySetup(renderCamera); } } Object.DestroyImmediate(lightObject); return(result); }
public static Texture2D GenerateModelPreviewWithShader(Transform model, Shader shader, string replacementTag, int width = 64, int height = 64, bool shouldCloneModel = false) { if (!model) { return(null); } Texture2D result = null; if (!model.gameObject.scene.IsValid() || !model.gameObject.scene.isLoaded) { shouldCloneModel = true; } Transform previewObject; if (shouldCloneModel) { previewObject = (Transform)Object.Instantiate(model, null, false); previewObject.gameObject.hideFlags = HideFlags.HideAndDontSave; } else { previewObject = model; layersList.Clear(); GetLayerRecursively(previewObject); } bool isStatic = IsStatic(model); bool wasActive = previewObject.gameObject.activeSelf; Vector3 prevPos = previewObject.position; Quaternion prevRot = previewObject.rotation; #if DEBUG_BOUNDS Transform boundsDebugCube = null; #endif try { SetupCamera(); SetLayerRecursively(previewObject); if (!isStatic) { previewObject.position = PREVIEW_POSITION; previewObject.rotation = Quaternion.identity; } if (!wasActive) { previewObject.gameObject.SetActive(true); } Bounds previewBounds = new Bounds(); if (!CalculateBounds(previewObject, out previewBounds)) { return(null); } #if DEBUG_BOUNDS if (!boundsDebugMaterial) { boundsDebugMaterial = new Material(Shader.Find("Sprites/Default")) { hideFlags = HideFlags.HideAndDontSave, color = new Color(0.5f, 0.5f, 0.5f, 0.5f) }; } boundsDebugCube = GameObject.CreatePrimitive(PrimitiveType.Cube).transform; boundsDebugCube.localPosition = previewBounds.center; boundsDebugCube.localScale = previewBounds.size; boundsDebugCube.gameObject.layer = PREVIEW_LAYER; boundsDebugCube.gameObject.hideFlags = HideFlags.HideAndDontSave; boundsDebugCube.GetComponent <Renderer>().sharedMaterial = boundsDebugMaterial; #endif renderCamera.aspect = (float)width / height; renderCamera.transform.rotation = Quaternion.LookRotation(previewObject.rotation * m_previewDirection, previewObject.up); CalculateCameraPosition(renderCamera, previewBounds, m_padding); renderCamera.farClipPlane = (renderCamera.transform.position - previewBounds.center).magnitude + previewBounds.size.magnitude; RenderTexture activeRT = RenderTexture.active; RenderTexture renderTexture = null; try { renderTexture = RenderTexture.GetTemporary(width, height, 16); RenderTexture.active = renderTexture; if (m_backgroundColor.a < 1f) { GL.Clear(true, true, m_backgroundColor); } renderCamera.targetTexture = renderTexture; if (!shader) { renderCamera.Render(); } else { renderCamera.RenderWithShader(shader, replacementTag ?? string.Empty); } renderCamera.targetTexture = null; result = new Texture2D(width, height, m_backgroundColor.a < 1f ? TextureFormat.RGBA32 : TextureFormat.RGB24, false); result.ReadPixels(new Rect(0f, 0f, width, height), 0, 0, false); result.Apply(false, m_markTextureNonReadable); } finally { RenderTexture.active = activeRT; if (renderTexture) { RenderTexture.ReleaseTemporary(renderTexture); } } } catch (Exception e) { Debug.LogException(e); } finally { #if DEBUG_BOUNDS if (boundsDebugCube) { Object.DestroyImmediate(boundsDebugCube.gameObject); } #endif if (shouldCloneModel) { Object.DestroyImmediate(previewObject.gameObject); } else { if (!wasActive) { previewObject.gameObject.SetActive(false); } if (!isStatic) { previewObject.position = prevPos; previewObject.rotation = prevRot; } int index = 0; SetLayerRecursively(previewObject, ref index); } if (renderCamera == m_previewRenderCamera) { cameraSetup.ApplySetup(renderCamera); } } return(result); }
internal static Texture2D GenerateModelPreviewWithShader(Transform model, Shader shader, String replacementTag, Int32 width, Int32 height, double lightLAT = 0, double lightLON = 0, Color?lightColor = null, Boolean shouldCloneModel = false) { if (model == null || model.Equals(null)) { return(null); } // The Light He called Day GameObject lightObject = new GameObject(); Light light = lightObject.AddOrGetComponent <Light>(); lightObject.transform.position = new Vector3(0, 0, -36); lightObject.transform.rotation = new Quaternion(0.1f, 0.1f, -0.7f, -0.7f); light.intensity = 1.5f; light.shadowBias = 0.047f; light.shadows = LightShadows.Soft; light.type = LightType.Directional; light.color = lightColor ?? Color.white; lightObject.transform.RotateAround(model.position, Vector3.right, (float)lightLAT); lightObject.transform.RotateAround(model.position, Vector3.down, (float)lightLON); lightObject.transform.rotation = Quaternion.LookRotation(model.position - lightObject.transform.position, lightObject.transform.up); Texture2D result = null; if (!model.gameObject.scene.IsValid() || !model.gameObject.scene.isLoaded) { shouldCloneModel = true; } Transform previewObject; if (shouldCloneModel) { previewObject = UnityEngine.Object.Instantiate(model, null, false); previewObject.gameObject.hideFlags = HideFlags.HideAndDontSave; } else { previewObject = model; layersList.Clear(); GetLayerRecursively(previewObject); } Boolean wasActive = previewObject.gameObject.activeSelf; Vector3 prevPos = previewObject.position; Quaternion prevRot = previewObject.rotation; try { SetupCamera(); SetLayerRecursively(previewObject); if (!wasActive) { previewObject.gameObject.SetActive(true); } Vector3 previewDir = previewObject.rotation * Vector3.forward; renderersList.Clear(); previewObject.GetComponentsInChildren(renderersList); Bounds previewBounds = new Bounds(); Boolean init = false; for (Int32 i = 0; i < renderersList.Count; i++) { if (!renderersList[i].enabled) { continue; } if (!init) { previewBounds = renderersList[i].bounds; init = true; } else { previewBounds.Encapsulate(renderersList[i].bounds); } } if (!init) { UnityEngine.Object.DestroyImmediate(lightObject); return(null); } boundsCenter = previewBounds.center; Vector3 boundsExtents = previewBounds.extents; Vector3 boundsSize = 2f * boundsExtents; Vector3 up = previewObject.up; previewObject.Rotate(-previewObject.right, (float)LAToffset); previewObject.Rotate(up, (float)LONoffset); aspect = (Single)width / height; renderCamera.aspect = aspect; renderCamera.transform.rotation = Quaternion.LookRotation(previewDir, up); renderCamera.transform.position = boundsCenter; minX = minY = Mathf.Infinity; maxX = maxY = Mathf.NegativeInfinity; Vector3 point = boundsCenter + boundsExtents; ProjectBoundingBoxMinMax(point); point.x -= boundsSize.x; ProjectBoundingBoxMinMax(point); point.y -= boundsSize.y; ProjectBoundingBoxMinMax(point); point.x += boundsSize.x; ProjectBoundingBoxMinMax(point); point.z -= boundsSize.z; ProjectBoundingBoxMinMax(point); point.x -= boundsSize.x; ProjectBoundingBoxMinMax(point); point.y += boundsSize.y; ProjectBoundingBoxMinMax(point); point.x += boundsSize.x; ProjectBoundingBoxMinMax(point); Single distance = boundsExtents.magnitude + 1f; renderCamera.orthographicSize = Mathf.Max(maxY - minY, (maxX - minX) / aspect) * 0.5f; renderCamera.transform.position = boundsCenter - previewDir * distance; renderCamera.farClipPlane = distance * 4f; RenderTexture temp = RenderTexture.active; RenderTexture renderTex = RenderTexture.GetTemporary(width, height, 16); RenderTexture.active = renderTex; if (BackgroundColor.a < 1) { GL.Clear(false, true, BackgroundColor); } renderCamera.targetTexture = renderTex; if (shader == null) { renderCamera.Render(); } else { renderCamera.RenderWithShader(shader, replacementTag ?? String.Empty); } renderCamera.targetTexture = null; result = new Texture2D(width, height, BackgroundColor.a < 1 ? TextureFormat.RGBA32 : TextureFormat.RGB24, false); result.ReadPixels(new Rect(0, 0, width, height), 0, 0, false); result.Apply(false, false); RenderTexture.active = temp; RenderTexture.ReleaseTemporary(renderTex); } catch (Exception e) { Debug.Log(e.ToString()); } finally { if (shouldCloneModel) { UnityEngine.Object.DestroyImmediate(previewObject.gameObject); } else { if (!wasActive) { previewObject.gameObject.SetActive(false); } Int32 index = 0; SetLayerRecursively(previewObject, ref index); } if (renderCamera == m_previewRenderCamera) { cameraSetup.ApplySetup(renderCamera); } } // And the Darkness He called Night UnityEngine.Object.DestroyImmediate(lightObject); return(result); }