コード例 #1
0
        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();
            }
        }
コード例 #2
0
        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();
        }