void UpdateShaders() { if (m_DirtyShaders.Any()) { PropagateNodeSet(m_DirtyShaders); var masterNodes = new List <INode>(); var colorNodes = new List <INode>(); var wireframeNodes = new List <INode>(); foreach (var index in m_DirtyShaders) { var node = m_Graph.GetNodeFromTempId(m_Identifiers[index]) as AbstractMaterialNode; if (node == null) { continue; } var masterNode = node as IMasterNode; if (masterNode != null) { masterNodes.Add(node); } else if (node.previewMode == PreviewMode.Wireframe) { wireframeNodes.Add(node); } else { colorNodes.Add(node); } } var count = Math.Min(colorNodes.Count, 1) + masterNodes.Count; try { var i = 0; EditorUtility.DisplayProgressBar("Shader Graph", string.Format("Compiling preview shaders ({0}/{1})", i, count), 0f); foreach (var node in masterNodes) { UpdateShader(node.tempId); i++; EditorUtility.DisplayProgressBar("Shader Graph", string.Format("Compiling preview shaders ({0}/{1})", i, count), 0f); } if (colorNodes.Count > 0) { var results = m_Graph.GetUberColorShader(); m_OutputIdName = results.outputIdProperty.referenceName; ShaderUtil.UpdateShaderAsset(m_ColorShader, results.shader); var debugOutputPath = DefaultShaderIncludes.GetDebugOutputPath(); if (debugOutputPath != null) { File.WriteAllText(debugOutputPath + "/ColorShader.shader", (results.shader ?? "null").Replace("UnityEngine.MaterialGraph", "Generated")); } bool uberShaderHasError = false; if (MaterialGraphAsset.ShaderHasError(m_ColorShader)) { var errors = MaterialGraphAsset.GetShaderErrors(m_ColorShader); var message = new ShaderStringBuilder(); message.AppendLine(@"Preview shader for graph has {0} error{1}:", errors.Length, errors.Length != 1 ? "s" : ""); foreach (var error in errors) { INode node; try { node = results.sourceMap.FindNode(error.line); message.AppendLine("Shader compilation error in {3} at line {1} (on {2}):\n{0}", error.message, error.line, error.platform, node != null ? string.Format("node {0} ({1})", node.name, node.guid) : "graph"); message.AppendLine(error.messageDetails); message.AppendNewLine(); } catch { message.AppendLine("Shader compilation error in {3} at line {1} (on {2}):\n{0}", error.message, error.line, error.platform, "graph"); } } Debug.LogWarning(message.ToString()); ShaderUtil.ClearShaderErrors(m_ColorShader); ShaderUtil.UpdateShaderAsset(m_ColorShader, k_EmptyShader); uberShaderHasError = true; } foreach (var node in colorNodes) { var renderData = GetRenderData(node.tempId); if (renderData == null) { continue; } var shaderData = renderData.shaderData; shaderData.shader = m_ColorShader; shaderData.hasError = uberShaderHasError; } i++; EditorUtility.DisplayProgressBar("Shader Graph", string.Format("Compiling preview shaders ({0}/{1})", i, count), 0f); } } finally { EditorUtility.ClearProgressBar(); } // Union dirty shaders into dirty previews m_DirtyPreviews.UnionWith(m_DirtyShaders); m_DirtyShaders.Clear(); } }
public void RenderPreviews() { m_NodesWith3DPreview.Clear(); m_NodesWithWireframePreview.Clear(); foreach (var node in m_Graph.GetNodes <AbstractMaterialNode>()) { if (node.previewMode == PreviewMode.Preview3D) { m_NodesWith3DPreview.Add(node.tempId.index); } else if (node.previewMode == PreviewMode.Wireframe) { m_NodesWithWireframePreview.Add(node.tempId.index); } } PropagateNodeSet(m_NodesWith3DPreview); PropagateNodeSet(m_NodesWithWireframePreview); m_NodesWith3DPreview.UnionWith(m_NodesWithWireframePreview); UpdateShaders(); // Union time dependent previews into dirty previews m_DirtyPreviews.UnionWith(m_TimeDependentPreviews); PropagateNodeSet(m_DirtyPreviews); foreach (var index in m_DirtyPreviews) { var renderData = m_RenderDatas[index]; renderData.previewMode = m_NodesWith3DPreview.Contains(renderData.shaderData.node.tempId.index) ? PreviewMode.Preview3D : PreviewMode.Preview2D; } // Find nodes we need properties from m_PropertyNodes.Clear(); m_PropertyNodes.UnionWith(m_DirtyPreviews); PropagateNodeSet(m_PropertyNodes, false); // Fill MaterialPropertyBlock m_PreviewPropertyBlock.Clear(); m_PreviewPropertyBlock.SetFloat(m_OutputIdName, -1); foreach (var index in m_PropertyNodes) { var node = m_Graph.GetNodeFromTempId(m_Identifiers[index]) as AbstractMaterialNode; if (node == null) { continue; } node.CollectPreviewMaterialProperties(m_PreviewProperties); foreach (var prop in m_Graph.properties) { m_PreviewProperties.Add(prop.GetPreviewMaterialProperty()); } foreach (var previewProperty in m_PreviewProperties) { m_PreviewPropertyBlock.SetPreviewProperty(previewProperty); } m_PreviewProperties.Clear(); } foreach (var i in m_DirtyPreviews) { var renderData = m_RenderDatas[i]; if (renderData.shaderData.shader == null) { renderData.texture = null; continue; } if (renderData.shaderData.hasError) { renderData.texture = m_ErrorTexture; continue; } if (renderData.previewMode == PreviewMode.Preview2D) { m_RenderList2D.Add(renderData); } else { m_RenderList3D.Add(renderData); } } m_RenderList3D.Sort((data1, data2) => data1.shaderData.shader.GetInstanceID().CompareTo(data2.shaderData.shader.GetInstanceID())); m_RenderList2D.Sort((data1, data2) => data1.shaderData.shader.GetInstanceID().CompareTo(data2.shaderData.shader.GetInstanceID())); var time = Time.realtimeSinceStartup; EditorUtility.SetCameraAnimateMaterialsTime(m_SceneResources.camera, time); m_SceneResources.light0.enabled = true; m_SceneResources.light0.intensity = 1.0f; m_SceneResources.light0.transform.rotation = Quaternion.Euler(50f, 50f, 0); m_SceneResources.light1.enabled = true; m_SceneResources.light1.intensity = 1.0f; m_SceneResources.camera.clearFlags = CameraClearFlags.Depth; // Render 2D previews m_SceneResources.camera.transform.position = -Vector3.forward * 2; m_SceneResources.camera.transform.rotation = Quaternion.identity; m_SceneResources.camera.orthographicSize = 0.5f; m_SceneResources.camera.orthographic = true; foreach (var renderData in m_RenderList2D) { RenderPreview(renderData, m_SceneResources.quad, Matrix4x4.identity); } // Render 3D previews m_SceneResources.camera.transform.position = -Vector3.forward * 5; m_SceneResources.camera.transform.rotation = Quaternion.identity; m_SceneResources.camera.orthographic = false; foreach (var renderData in m_RenderList3D) { RenderPreview(renderData, m_SceneResources.sphere, Matrix4x4.identity); } var renderMasterPreview = masterRenderData.shaderData != null && m_DirtyPreviews.Contains(masterRenderData.shaderData.node.tempId.index); if (renderMasterPreview) { if (m_NewMasterPreviewSize.HasValue) { if (masterRenderData.renderTexture != null) { Object.DestroyImmediate(masterRenderData.renderTexture, true); } masterRenderData.renderTexture = new RenderTexture((int)m_NewMasterPreviewSize.Value.x, (int)m_NewMasterPreviewSize.Value.y, 16, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default) { hideFlags = HideFlags.HideAndDontSave }; masterRenderData.renderTexture.Create(); masterRenderData.texture = masterRenderData.renderTexture; m_NewMasterPreviewSize = null; } var mesh = m_Graph.previewData.serializedMesh.mesh ? m_Graph.previewData.serializedMesh.mesh : m_SceneResources.sphere; var previewTransform = Matrix4x4.Rotate(m_Graph.previewData.rotation); var scale = m_Graph.previewData.scale; previewTransform *= Matrix4x4.Scale(scale * Vector3.one * (Vector3.one).magnitude / mesh.bounds.size.magnitude); previewTransform *= Matrix4x4.Translate(-mesh.bounds.center); RenderPreview(masterRenderData, mesh, previewTransform); } m_SceneResources.light0.enabled = false; m_SceneResources.light1.enabled = false; foreach (var renderData in m_RenderList2D) { renderData.NotifyPreviewChanged(); } foreach (var renderData in m_RenderList3D) { renderData.NotifyPreviewChanged(); } if (renderMasterPreview) { masterRenderData.NotifyPreviewChanged(); } m_RenderList2D.Clear(); m_RenderList3D.Clear(); m_DirtyPreviews.Clear(); }