public override void OnImportAsset(AssetImportContext ctx) { var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath); if (oldShader != null) { ShaderUtil.ClearShaderErrors(oldShader); } List <PropertyCollector.TextureInfo> configuredTextures; var text = GetShaderText(ctx.assetPath, out configuredTextures); var shader = ShaderUtil.CreateShaderAsset(text); EditorMaterialUtility.SetShaderDefaults( shader, configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); EditorMaterialUtility.SetShaderNonModifiableDefaults( shader, configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); ctx.AddObjectToAsset("MainAsset", shader); ctx.SetMainObject(shader); }
public override void OnImportAsset(AssetImportContext ctx) { var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath); if (oldShader != null) { ShaderUtil.ClearShaderMessages(oldShader); } List <PropertyCollector.TextureInfo> configuredTextures; string path = ctx.assetPath; var sourceAssetDependencyPaths = new List <string>(); var text = GetShaderText(path, out configuredTextures, sourceAssetDependencyPaths); var shader = ShaderUtil.CreateShaderAsset(text); EditorMaterialUtility.SetShaderDefaults( shader, configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); EditorMaterialUtility.SetShaderNonModifiableDefaults( shader, configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); ctx.AddObjectToAsset("MainAsset", shader); ctx.SetMainObject(shader); foreach (var sourceAssetDependencyPath in sourceAssetDependencyPaths.Distinct()) { ctx.DependsOnSourceAsset(sourceAssetDependencyPath); } }
public PreviewManager(AbstractMaterialGraph graph) { m_Graph = graph; m_PreviewMaterial = new Material(Shader.Find("Unlit/Color")) { hideFlags = HideFlags.HideInHierarchy }; m_PreviewMaterial.hideFlags = HideFlags.HideAndDontSave; m_PreviewPropertyBlock = new MaterialPropertyBlock(); m_ErrorTexture = new Texture2D(2, 2); m_ErrorTexture.SetPixel(0, 0, Color.magenta); m_ErrorTexture.SetPixel(0, 1, Color.black); m_ErrorTexture.SetPixel(1, 0, Color.black); m_ErrorTexture.SetPixel(1, 1, Color.magenta); m_ErrorTexture.filterMode = FilterMode.Point; m_ErrorTexture.Apply(); m_SceneResources = new PreviewSceneResources(); m_UberShader = ShaderUtil.CreateShaderAsset(k_EmptyShader); m_UberShader.hideFlags = HideFlags.HideAndDontSave; m_MasterRenderData = new PreviewRenderData { renderTexture = new RenderTexture(400, 400, 16, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default) { hideFlags = HideFlags.HideAndDontSave } }; m_MasterRenderData.renderTexture.Create(); foreach (var node in m_Graph.GetNodes <INode>()) { AddPreview(node); } }
static Material SetupMaterial(MicroSplatKeywords kwds, Material mat, MicroSplatBaseFeatures.DebugOutput debugOutput, bool useDebugTopo) { MicroSplatShaderGUI.MicroSplatCompiler comp = new MicroSplatShaderGUI.MicroSplatCompiler(); List <string> keywords = new List <string>(kwds.keywords); RemoveKeyword(keywords, "_SNOW"); RemoveKeyword(keywords, "_TESSDISTANCE"); RemoveKeyword(keywords, "_WINDPARTICULATE"); RemoveKeyword(keywords, "_SNOWPARTICULATE"); RemoveKeyword(keywords, "_GLITTER"); RemoveKeyword(keywords, "_SNOWGLITTER"); keywords.Add(FeatureFromOutput(debugOutput).ToString()); if (useDebugTopo) { keywords.Add("_DEBUG_USE_TOPOLOGY"); } string shader = comp.Compile(keywords.ToArray(), "RenderBake_" + debugOutput.ToString()); Shader s = ShaderUtil.CreateShaderAsset(shader); Material renderMat = new Material(mat); renderMat.shader = s; return(renderMat); }
private Texture RenderIcon(Color color) { if (iconMat == null || iconMat.shader == null) { iconMat = new Material(ShaderUtil.CreateShaderAsset(iconShader)); } iconMat.SetColor("_Color", color); var prevSRGB = GL.sRGBWrite; GL.sRGBWrite = true; RenderTexture prev = RenderTexture.active; var rt = RenderTexture.GetTemporary(this.width, this.height, 0); RenderTexture.active = rt; GL.Clear(false, true, new Color(1, 1, 1, 0)); Graphics.Blit(this.Raw, rt, iconMat); Texture2D texture = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, false, true); texture.filterMode = FilterMode.Bilinear; texture.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0); texture.alphaIsTransparency = true; texture.Apply(); RenderTexture.ReleaseTemporary(rt); RenderTexture.active = prev; GL.sRGBWrite = prevSRGB; return(texture); }
/// <summary> /// Generates a texture containing the given graph's noise output. /// If this is being called very often, create a permanent render target and material and /// use the other version of this method instead for much better performance. /// If an error occurred, outputs to the Unity debug console and returns "null". /// </summary> /// <param name="outputComponents"> /// The texture output. /// For example, pass "rgb" or "xyz" to output the noise into the red, green, and blue channels /// but not the alpha channel. /// </param> /// <param name="defaultColor"> /// The color (generally 0-1) of the color components which aren't set by the noise. /// </param> /// <param name="uvZ">The Z coordinate of the UVs, in case the graph uses it for 3D noise.</param> /// <param name="leaveReadable"> /// Whether the texture's pixel data can still be read from the CPU after this operation. /// </param> public static Texture2D GenerateToTexture(Graph g, GraphParamCollection c, int width, int height, float uvZ, string outputComponents, float defaultColor, TextureFormat format = TextureFormat.RGBAFloat, bool leaveReadable = false) { //Generate a shader/material from the graph. Shader shader = ShaderUtil.CreateShaderAsset(g.GenerateShader("TempGPUNoiseShader", outputComponents, defaultColor)); if (shader == null) { return(null); } Material mat = new Material(shader); c.SetParams(mat); mat.SetFloat(GraphUtils.Param_UVz, uvZ); //Render the shader's output into a render texture and copy the data to a Texture2D. RenderTexture target = RenderTexture.GetTemporary(width, height, 16, RenderTextureFormat.ARGBFloat); Texture2D resultTex = new Texture2D(width, height, format, false, true); //Generate. GraphUtils.GenerateToTexture(target, mat, resultTex, leaveReadable); //Clean up. RenderTexture.ReleaseTemporary(target); return(resultTex); }
public override void OnImportAsset(AssetImportContext ctx) { var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath); if (oldShader != null) { ShaderUtil.ClearShaderErrors(oldShader); } List <PropertyCollector.TextureInfo> configuredTextures; string path = ctx.assetPath; string shaderString = null; var sourceAssetDependencyPaths = new List <string>(); var shaderName = Path.GetFileNameWithoutExtension(path); try { var textGraph = File.ReadAllText(path, Encoding.UTF8); var graph = JsonUtility.FromJson <MaterialGraph>(textGraph); graph.LoadedFromDisk(); if (!string.IsNullOrEmpty(graph.path)) { shaderName = graph.path + "/" + shaderName; } shaderString = graph.GetShader(shaderName, GenerationMode.ForReals, out configuredTextures, sourceAssetDependencyPaths); foreach (var node in graph.GetNodes <AbstractMaterialNode>()) { node.GetSourceAssetDependencies(sourceAssetDependencyPaths); } } catch (Exception) { configuredTextures = new List <PropertyCollector.TextureInfo>(); // ignored } var text = shaderString ?? k_ErrorShader.Replace("Hidden/GraphErrorShader2", shaderName); var shader = ShaderUtil.CreateShaderAsset(text); EditorMaterialUtility.SetShaderDefaults( shader, configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); EditorMaterialUtility.SetShaderNonModifiableDefaults( shader, configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); ctx.AddObjectToAsset("MainAsset", shader); ctx.SetMainObject(shader); foreach (var sourceAssetDependencyPath in sourceAssetDependencyPaths.Distinct()) { ctx.DependsOnSourceAsset(sourceAssetDependencyPath); } }
/// <summary> /// Generates a 3D texture containing the given graph's noise output. /// </summary> /// <param name="outputComponents"> /// The texture output. /// For example, pass "rgb" or "xyz" to output the noise into the red, green, and blue channels /// but not the alpha channel. /// </param> /// <param name="defaultColor"> /// The color (generally 0-1) of the color components which aren't set by the noise. /// </param> /// <param name="useMipmaps">Whether the 3D texture object uses mipmapping.</param> /// <param name="leaveTextureReadable"> /// Whether to let the texture keep a CPU copy of its data on hand for later reading. /// </param> public static Texture3D GenerateToTexture(Graph g, GraphParamCollection c, int width, int height, int depth, string outputComponents, float defaultColor, bool useMipmaps, bool leaveTextureReadable, TextureFormat format = TextureFormat.RGBA32) { //Generate a shader/material from the graph. Shader shader = ShaderUtil.CreateShaderAsset(g.GenerateShader("TempGPUNoiseShader", outputComponents, defaultColor)); if (shader == null) { return(null); } Material mat = new Material(shader); c.SetParams(mat); //For every Z layer in the texture, generate a 2D texture representing that layer. Color32[] finalPixels = new Color32[width * height * depth]; RenderTexture target = RenderTexture.GetTemporary(width, height, 16, RenderTextureFormat.ARGBFloat); Texture2D resultTex = new Texture2D(width, height, TextureFormat.RGBAFloat, false, true); for (int depthI = 0; depthI < depth; ++depthI) { //Get the UV.z coordinate. float uvZ = (float)depthI / depth; mat.SetFloat(GraphUtils.Param_UVz, uvZ); GraphUtils.GenerateToTexture(target, mat, resultTex, true); //Copy the resulting data into part of the 3D texture. Color32[] layerPixels = resultTex.GetPixels32(); int pixelOffset = depthI * (width * height); for (int pixelI = 0; pixelI < (width * height); ++pixelI) { finalPixels[pixelI + pixelOffset] = layerPixels[pixelI]; } } //Create the actual texture object. Texture3D finalTex = new Texture3D(width, height, depth, format, useMipmaps); finalTex.SetPixels32(finalPixels); finalTex.Apply(useMipmaps, !leaveTextureReadable); //Clean up. RenderTexture.ReleaseTemporary(target); return(finalTex); }
public override void OnImportAsset(AssetImportContext ctx) { var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath); if (oldShader != null) { ShaderUtil.ClearShaderMessages(oldShader); } List <PropertyCollector.TextureInfo> configuredTextures; string path = ctx.assetPath; var sourceAssetDependencyPaths = new List <string>(); var text = GetShaderText(path, out configuredTextures, sourceAssetDependencyPaths, out var graph); var shader = ShaderUtil.CreateShaderAsset(text, false); if (graph != null && graph.messageManager.nodeMessagesChanged) { foreach (var pair in graph.messageManager.GetNodeMessages()) { var node = graph.GetNodeFromTempId(pair.Key); MessageManager.Log(node, path, pair.Value.First(), shader); } } EditorMaterialUtility.SetShaderDefaults( shader, configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); EditorMaterialUtility.SetShaderNonModifiableDefaults( shader, configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); Texture2D texture = Resources.Load <Texture2D>("Icons/sg_graph_icon@64"); ctx.AddObjectToAsset("MainAsset", shader, texture); ctx.SetMainObject(shader); var metadata = ScriptableObject.CreateInstance <ShaderGraphMetadata>(); metadata.hideFlags = HideFlags.HideInHierarchy; if (graph != null) { metadata.outputNodeTypeName = graph.outputNode.GetType().FullName; } ctx.AddObjectToAsset("Metadata", metadata); foreach (var sourceAssetDependencyPath in sourceAssetDependencyPaths.Distinct()) { // Ensure that dependency path is relative to project if (!sourceAssetDependencyPath.StartsWith("Packages/") && !sourceAssetDependencyPath.StartsWith("Assets/")) { Debug.LogWarning($"Invalid dependency path: {sourceAssetDependencyPath}", shader); continue; } ctx.DependsOnSourceAsset(sourceAssetDependencyPath); } }
public override void OnImportAsset(AssetImportContext ctx) { string fileContent = File.ReadAllText(ctx.assetPath); var package = ObjectFactory.CreateInstance <ShaderPackage>(); if (!string.IsNullOrEmpty(fileContent)) { EditorJsonUtility.FromJsonOverwrite(fileContent, package); } if (package.entries == null) { package.entries = new List <ShaderPackage.Entry>(); } #if __BETTERSHADERS__ if (package.betterShader != null) { package.betterShaderPath = AssetDatabase.GetAssetPath(package.betterShader); } #endif package.Pack(false); #if __BETTERSHADERS__ if (package.betterShader != null) { ctx.DependsOnSourceAsset(package.betterShaderPath); } #endif foreach (var e in package.entries) { if (e.shader != null) { ctx.DependsOnSourceAsset(AssetDatabase.GetAssetPath(e.shader)); } } string shaderSrc = package.GetShaderSrc(); if (shaderSrc == null) { Debug.LogError("No Shader for this platform and SRP provided"); // maybe make an error shader here? return; } Shader shader = ShaderUtil.CreateShaderAsset(ctx, shaderSrc, false); ctx.AddObjectToAsset("MainAsset", shader); ctx.SetMainObject(shader); }
void CompileNodeShader(AbstractMaterialNode node, GenerationMode mode, string nodeName) { var generator = new Generator(m_Graph, node, mode, nodeName, null); var shader = ShaderUtil.CreateShaderAsset(generator.generatedShader, true); shader.hideFlags = HideFlags.HideAndDontSave; var mat = new Material(shader) { hideFlags = HideFlags.HideAndDontSave }; ShaderUtil.CompilePass(mat, 0, true); }
public override void OnImportAsset(AssetImportContext ctx) { Shader shader = null; #if UNITY_2020_2_OR_NEWER //2020.2 or later supports shader dependencies registration shader = ShaderUtil.CreateShaderAsset(ctx, File.ReadAllText(ctx.assetPath), false); #else //Versions of older unity don't support asset system context shader dependencies registration shader = ShaderUtil.CreateShaderAsset(File.ReadAllText(ctx.assetPath), false); #endif ctx.AddObjectToAsset("MainAsset", shader); ctx.SetMainObject(shader); }
void AddPreview(AbstractMaterialNode node) { var renderData = new PreviewRenderData { renderTexture = new RenderTexture(200, 200, 16, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default) { hideFlags = HideFlags.HideAndDontSave } }; if (masterRenderData == null && (node is IMasterNode || node is SubGraphOutputNode)) { m_MasterRenderData = renderData; renderData.renderTexture.width = renderData.renderTexture.height = 400; } renderData.renderTexture.Create(); var shaderData = new PreviewShaderData { node = node, isCompiling = false, hasError = false, shader = ShaderUtil.CreateShaderAsset(k_EmptyShader, false) }; shaderData.shader.hideFlags = HideFlags.HideAndDontSave; shaderData.mat = new Material(shaderData.shader) { hideFlags = HideFlags.HideAndDontSave }; renderData.shaderData = shaderData; Set(m_Identifiers, node.tempId, node.tempId); Set(m_RenderDatas, node.tempId, renderData); node.RegisterCallback(OnNodeModified); if (node.RequiresTime()) { m_RefreshTimedNodes = true; } if (m_MasterRenderData == renderData && onPrimaryMasterChanged != null) { onPrimaryMasterChanged(); } m_NodesToUpdate.Add(node); }
internal static Shader BuildShaderGraph(GraphData graph, string name, bool hide = true) { var generator = new Generator(graph, graph.outputNode, GenerationMode.ForReals, "TransformGraph", null); string shaderString = generator.generatedShader; var shader = ShaderUtil.CreateShaderAsset(shaderString, false); if (hide) { shader.hideFlags = HideFlags.HideAndDontSave; } return(shader); }
public override void OnImportAsset(AssetImportContext ctx) { var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath); if (oldShader != null) { ShaderUtil.ClearShaderMessages(oldShader); } List <PropertyCollector.TextureInfo> configuredTextures; string path = ctx.assetPath; var sourceAssetDependencyPaths = new List <string>(); var text = GetShaderText(path, out configuredTextures, sourceAssetDependencyPaths, out var graph); var shader = ShaderUtil.CreateShaderAsset(text); if (graph.messageManager.nodeMessagesChanged) { foreach (var pair in graph.messageManager.GetNodeMessages()) { var node = graph.GetNodeFromTempId(pair.Key); var errorString = $"Error in Shader Graph at {path} in node {node.name}: {pair.Value.First().message}"; Debug.LogError(errorString, shader); } } EditorMaterialUtility.SetShaderDefaults( shader, configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); EditorMaterialUtility.SetShaderNonModifiableDefaults( shader, configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); ctx.AddObjectToAsset("MainAsset", shader); ctx.SetMainObject(shader); foreach (var sourceAssetDependencyPath in sourceAssetDependencyPaths.Distinct()) { // Ensure that dependency path is relative to project if (!sourceAssetDependencyPath.StartsWith("Packages/") && !sourceAssetDependencyPath.StartsWith("Assets/")) { Debug.LogWarning($"Invalid dependency path: {sourceAssetDependencyPath}", shader); continue; } ctx.DependsOnSourceAsset(sourceAssetDependencyPath); } }
/// <summary> /// Generates a texture containing the given graph's noise output. /// If this is being called very often, create a permanent render target and material and /// use the other version of this method instead for much better performance. /// If an error occurred, outputs to the Unity debug console and returns "null". /// </summary> /// <param name="gradientRampName">The name of the gradient ramp texture param.</param> /// <param name="uvZ">The Z coordinate of the UVs, in case the graph uses it for 3D noise.</param> /// <param name="leaveReadable"> /// Whether to leave the texture data readable on the CPU after the operation. /// </param> public static Texture2D GenerateToTexture(Graph g, GraphParamCollection c, int width, int height, float uvZ, Gradient gradientRamp, TextureFormat format = TextureFormat.RGBAFloat, bool leaveReadable = false) { //Generate a shader/material from the graph. Shader shader = ShaderUtil.CreateShaderAsset(g.GenerateShader("TempGPUNoiseShader", "_MyGradientRamp14123")); if (shader == null) { return(null); } Material mat = new Material(shader); c.SetParams(mat); mat.SetFloat(GraphUtils.Param_UVz, uvZ); //Generate a texture from the gradient. Texture2D myRamp = new Texture2D(1024, 1, TextureFormat.RGBA32, false); Color[] cols = new Color[myRamp.width]; for (int i = 0; i < cols.Length; ++i) { cols[i] = gradientRamp.Evaluate((float)i / (float)(cols.Length - 1)); } myRamp.SetPixels(cols); myRamp.Apply(false, true); mat.SetTexture("_MyGradientRamp14123", myRamp); //Render the shader's output into a render texture and copy the data to a Texture2D. RenderTexture target = RenderTexture.GetTemporary(width, height, 16, RenderTextureFormat.ARGBFloat); Texture2D resultTex = new Texture2D(width, height, format, false, true); //Generate. GraphUtils.GenerateToTexture(target, mat, resultTex, leaveReadable); //Clean up. RenderTexture.ReleaseTemporary(target); return(resultTex); }
/// <summary> /// Properly updates the preview texture for this window. /// Returns it in case anybody wants it (returns null if there was a problem loading the graph). /// </summary> public Texture2D GetPreview(bool regenerateShader) { //Regenerate shader. if (regenerateShader || previewMat == null) { //Render the gradient ramp to a texture. Gradient gradient = MakeGradient(); Texture2D myRamp = new Texture2D(1024, 1, TextureFormat.RGBA32, false); myRamp.wrapMode = TextureWrapMode.Clamp; Color[] cols = new Color[myRamp.width]; for (int i = 0; i < cols.Length; ++i) { cols[i] = gradient.Evaluate((float)i / (float)(cols.Length - 1)); } myRamp.SetPixels(cols); myRamp.Apply(false, true); Graph graph = new Graph(graphPaths[SelectedGraphIndex]); string errMsg = graph.Load(); if (errMsg.Length > 0) { Debug.LogError("Error loading graph " + graphPaths[SelectedGraphIndex] + ": " + errMsg); return(null); } Shader shader = ShaderUtil.CreateShaderAsset(graph.GenerateShader( "Graph editor temp shader", "_textureGeneratorWindowGradient")); previewMat = new Material(shader); previewMat.SetTexture("_textureGeneratorWindowGradient", myRamp); } //Set parameters. gParams.SetParams(previewMat); previewMat.SetFloat(GraphUtils.Param_UVz, previewUVz); //Generate. GeneratePreview(ref previewTex, previewMat); return(previewTex); }
/// <summary> /// Converts a Sprite to a Texture2D. /// </summary> /// <param name="sprite"></param> /// <returns></returns> public static Texture2D ConvertSpriteToTexture(Sprite sprite) { var rect = sprite.rect; if (extractSpriteMaterial == null || extractSpriteMaterial.shader == null) { extractSpriteMaterial = new Material(ShaderUtil.CreateShaderAsset(extractSpriteShader)); } extractSpriteMaterial.SetVector("_TexelSize", new Vector2(1f / sprite.texture.width, 1f / sprite.texture.height)); extractSpriteMaterial.SetVector("_Rect", new Vector4( rect.x / sprite.texture.width, rect.y / sprite.texture.height, rect.width / sprite.texture.width, rect.height / sprite.texture.height )); var prevSRGB = GL.sRGBWrite; GL.sRGBWrite = true; RenderTexture prev = RenderTexture.active; var rt = RenderTexture.GetTemporary((int)rect.width, (int)rect.height, 0); RenderTexture.active = rt; GL.Clear(false, true, new Color(1, 1, 1, 0)); Graphics.Blit(sprite.texture, rt, extractSpriteMaterial); Texture2D texture = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, false, true); texture.filterMode = FilterMode.Bilinear; texture.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0); texture.alphaIsTransparency = true; texture.Apply(); RenderTexture.ReleaseTemporary(rt); RenderTexture.active = prev; GL.sRGBWrite = prevSRGB; return(texture); }
void UpdateMasterNodeShader() { var shaderData = masterRenderData?.shaderData; var masterNode = shaderData?.node as IMasterNode; if (masterNode == null) { return; } List <PropertyCollector.TextureInfo> configuredTextures; shaderData.shaderString = masterNode.GetShader(GenerationMode.Preview, shaderData.node.name, out configuredTextures); if (string.IsNullOrEmpty(shaderData.shaderString)) { if (shaderData.shader != null) { ShaderUtil.ClearShaderMessages(shaderData.shader); Object.DestroyImmediate(shaderData.shader, true); shaderData.shader = null; } return; } if (shaderData.shader == null) { shaderData.shader = ShaderUtil.CreateShaderAsset(shaderData.shaderString, false); shaderData.shader.hideFlags = HideFlags.HideAndDontSave; } else { ShaderUtil.ClearCachedData(shaderData.shader); } BeginCompile(masterRenderData, shaderData.shaderString, masterNode.GetActiveSubShader()?.GetPreviewPassIndex() ?? 0); }
void UpdateMasterNodeShader() { var shaderData = masterRenderData?.shaderData; var masterNode = shaderData?.node as IMasterNode; if (masterNode == null) { return; } var generator = new Generator(m_Graph, shaderData?.node, GenerationMode.Preview, shaderData?.node.name); shaderData.shaderString = generator.generatedShader; if (string.IsNullOrEmpty(shaderData.shaderString)) { if (shaderData.shader != null) { ShaderUtil.ClearShaderMessages(shaderData.shader); Object.DestroyImmediate(shaderData.shader, true); shaderData.shader = null; } return; } if (shaderData.shader == null) { shaderData.shader = ShaderUtil.CreateShaderAsset(shaderData.shaderString, false); shaderData.shader.hideFlags = HideFlags.HideAndDontSave; } else { ShaderUtil.ClearCachedData(shaderData.shader); } BeginCompile(masterRenderData, shaderData.shaderString); }
void BeginCompile(PreviewRenderData renderData, string shaderStr) { using (BeginCompileMarker.Auto()) { var shaderData = renderData.shaderData; // want to ensure this so we don't get confused with multiple compile versions in flight Assert.IsTrue(shaderData.passesCompiling == 0); if (shaderData.shader == null) { shaderData.shader = ShaderUtil.CreateShaderAsset(shaderStr, false); shaderData.shader.hideFlags = HideFlags.HideAndDontSave; } else { ShaderUtil.ClearCachedData(shaderData.shader); ShaderUtil.UpdateShaderAsset(shaderData.shader, shaderStr, false); } if (shaderData.mat == null) { shaderData.mat = new Material(shaderData.shader) { hideFlags = HideFlags.HideAndDontSave }; } shaderData.passesCompiling = shaderData.mat.passCount; for (var i = 0; i < shaderData.mat.passCount; i++) { ShaderUtil.CompilePass(shaderData.mat, i); } m_NodesCompiling.Add(shaderData.node); } }
/// <summary> /// Draws the icon in a square rect, with a custom shader that makes the icon look better when down-scaled. /// This also handles mouseover effects, and linier color spacing. /// </summary> public void Draw(Rect rect, Texture texture) { if (Event.current.type != EventType.Repaint) { return; } if (!GUIClipInfo.VisibleRect.Contains(rect.center)) { return; } if (blurWhenDownscalingMaterial == null || blurWhenDownscalingMaterial.shader == null) { blurWhenDownscalingMaterial = new Material(ShaderUtil.CreateShaderAsset(blurWhenDownscalingShader)); } // The smaller the image, the bigger the texel size. float texelSize = Mathf.Pow(Mathf.Max((1f - rect.width / this.Active.width) * 1.866f, 0), 1.46f) / this.Active.width; blurWhenDownscalingMaterial.SetFloat("_TexelSize", texelSize); blurWhenDownscalingMaterial.SetColor("_TintColor", GUI.color); Graphics.DrawTexture(rect, texture, blurWhenDownscalingMaterial); }
static Material SetupMaterial(MicroSplatKeywords kwds, Material mat, MicroSplatBaseFeatures.DebugOutput debugOutput, bool useDebugTopo) { MicroSplatShaderGUI.MicroSplatCompiler comp = new MicroSplatShaderGUI.MicroSplatCompiler(); List <string> keywords = new List <string>(kwds.keywords); RemoveKeyword(keywords, "_SNOW"); RemoveKeyword(keywords, "_TESSDISTANCE"); RemoveKeyword(keywords, "_WINDPARTICULATE"); RemoveKeyword(keywords, "_SNOWPARTICULATE"); RemoveKeyword(keywords, "_GLITTER"); RemoveKeyword(keywords, "_SNOWGLITTER"); RemoveKeyword(keywords, "_SPECULARFROMMETALLIC"); RemoveKeyword(keywords, "_USESPECULARWORKFLOW"); RemoveKeyword(keywords, "_BDRFLAMBERT"); RemoveKeyword(keywords, "_BDRF1"); RemoveKeyword(keywords, "_BDRF2"); RemoveKeyword(keywords, "_BDRF3"); keywords.Add(FeatureFromOutput(debugOutput).ToString()); if (useDebugTopo) { keywords.Add("_DEBUG_USE_TOPOLOGY"); } keywords.Add("_RENDERBAKE"); string shader = comp.Compile(keywords.ToArray(), "RenderBake_" + debugOutput.ToString()); Shader s = ShaderUtil.CreateShaderAsset(shader); Material renderMat = new Material(mat); renderMat.shader = s; renderMat.CopyPropertiesFromMaterial(mat); // because the constructor doesn't do it right in URP renderMat.enableInstancing = false; // for some reason instance drawing breaks in URP return(renderMat); }
internal void OnBakeTexture() { var graph = owner as GraphData; if (graph == null) { Debug.LogError("BakeTextureNode's owner isn't a AbstractMaterialGraph, how is it possible ?"); } // from https://github.com/Unity-Technologies/ScriptableRenderPipeline/commit/3b28421204badded8c0d14315f10c256de3345a0#diff-52bd31870846010ea070163214aac090 graph.GetShader(this, GenerationMode.Preview, "hidden/preview"); BakeShaderData shaderData = new BakeShaderData(); shaderData.ShaderString = graph.GetPreviewShader(this).shader; shaderData.Shader = ShaderUtil.CreateShaderAsset(shaderData.ShaderString); shaderData.Node = this; shaderData.Graph = graph; shaderData.HasError = false; // TODO handle shader errors shaderData.OutputIdName = "Out"; BakeTextureManager.BakeShaderIntoTexture(shaderData); }
public override void OnImportAsset(AssetImportContext ctx) { var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath); if (oldShader != null) { ShaderUtil.ClearShaderErrors(oldShader); } List <PropertyCollector.TextureInfo> configuredTextures; var text = GetShaderText <MaterialGraph>(ctx.assetPath, out configuredTextures); if (text == null) { text = errorShader; } var name = Path.GetFileNameWithoutExtension(ctx.assetPath); string shaderName = string.Format("graphs/{0}", name); text = text.Replace("Hidden/GraphErrorShader2", shaderName); var shader = ShaderUtil.CreateShaderAsset(text); EditorMaterialUtility.SetShaderDefaults( shader, configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); EditorMaterialUtility.SetShaderNonModifiableDefaults( shader, configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); ctx.AddObjectToAsset("MainAsset", shader); ctx.SetMainObject(shader); }
void UpdateShader(Identifier nodeId) { var node = m_Graph.GetNodeFromTempId(nodeId) as AbstractMaterialNode; if (node == null) { return; } var renderData = Get(m_RenderDatas, nodeId); if (renderData == null || renderData.shaderData == null) { return; } var shaderData = renderData.shaderData; if (!(node is IMasterNode) && !node.hasPreview) { shaderData.shaderString = null; } else { var masterNode = node as IMasterNode; if (masterNode != null) { List <PropertyCollector.TextureInfo> configuredTextures; shaderData.shaderString = masterNode.GetShader(GenerationMode.Preview, node.name, out configuredTextures); } else { shaderData.shaderString = m_Graph.GetPreviewShader(node).shader; } } var debugOutputPath = DefaultShaderIncludes.GetDebugOutputPath(); if (debugOutputPath != null) { File.WriteAllText(debugOutputPath + "/GeneratedShader.shader", (shaderData.shaderString ?? "null").Replace("UnityEngine.MaterialGraph", "Generated")); } if (string.IsNullOrEmpty(shaderData.shaderString)) { if (shaderData.shader != null) { ShaderUtil.ClearShaderErrors(shaderData.shader); Object.DestroyImmediate(shaderData.shader, true); shaderData.shader = null; } return; } if (shaderData.shader == null) { shaderData.shader = ShaderUtil.CreateShaderAsset(shaderData.shaderString); shaderData.shader.hideFlags = HideFlags.HideAndDontSave; } else { ShaderUtil.ClearShaderErrors(shaderData.shader); ShaderUtil.UpdateShaderAsset(shaderData.shader, shaderData.shaderString); } // Debug output if (MaterialGraphAsset.ShaderHasError(shaderData.shader)) { var errors = MaterialGraphAsset.GetShaderErrors(shaderData.shader); foreach (var error in errors) { Debug.LogFormat("Compilation error in {3} at line {1} (on {2}):\n{0}", error.message, error.line, error.platform, "graph"); } shaderData.hasError = true; if (debugOutputPath != null) { var message = "RecreateShader: " + node.GetVariableNameForNode() + Environment.NewLine + shaderData.shaderString; Debug.LogWarning(message); } ShaderUtil.ClearShaderErrors(shaderData.shader); Object.DestroyImmediate(shaderData.shader, true); shaderData.shader = null; } else { shaderData.hasError = false; } }
public static Shader CreataShader(string shader) { return(ShaderUtil.CreateShaderAsset(shader)); }
void UpdateShader(Identifier nodeId) { var node = m_Graph.GetNodeFromTempId(nodeId) as AbstractMaterialNode; if (node == null) { return; } var renderData = Get(m_RenderDatas, nodeId); if (renderData == null || renderData.shaderData == null) { return; } var shaderData = renderData.shaderData; if (!(node is IMasterNode) && (!node.hasPreview || NodeUtils.FindEffectiveShaderStage(node, true) == ShaderStage.Vertex)) { shaderData.shaderString = null; } else { var masterNode = node as IMasterNode; if (masterNode != null) { List <PropertyCollector.TextureInfo> configuredTextures; shaderData.shaderString = masterNode.GetShader(GenerationMode.Preview, node.name, out configuredTextures); } else { shaderData.shaderString = m_Graph.GetPreviewShader(node).shader; } } #if UNITY_SHADER_GRAPH_DEVMODE File.WriteAllText(Application.dataPath + "/../GeneratedShader.shader", (shaderData.shaderString ?? "null").Replace("UnityEngine.MaterialGraph", "Generated")); #endif if (string.IsNullOrEmpty(shaderData.shaderString)) { if (shaderData.shader != null) { ShaderUtil.ClearShaderErrors(shaderData.shader); Object.DestroyImmediate(shaderData.shader, true); shaderData.shader = null; } return; } if (shaderData.shader == null) { shaderData.shader = ShaderUtil.CreateShaderAsset(shaderData.shaderString); shaderData.shader.hideFlags = HideFlags.HideAndDontSave; } else { ShaderUtil.ClearShaderErrors(shaderData.shader); ShaderUtil.UpdateShaderAsset(shaderData.shader, shaderData.shaderString); } // Debug output #if UNITY_SHADER_GRAPH_DEVMODE var message = "RecreateShader: " + node.GetVariableNameForNode() + Environment.NewLine + shaderData.shaderString; #endif if (MaterialGraphAsset.ShaderHasError(shaderData.shader)) { shaderData.hasError = true; Debug.LogWarning(message); ShaderUtil.ClearShaderErrors(shaderData.shader); Object.DestroyImmediate(shaderData.shader, true); shaderData.shader = null; } else { shaderData.hasError = false; } }
public override void OnImportAsset(AssetImportContext ctx) { var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath); if (oldShader != null) { ShaderUtil.ClearShaderMessages(oldShader); } List <PropertyCollector.TextureInfo> configuredTextures; string path = ctx.assetPath; AssetCollection assetCollection = new AssetCollection(); MinimalGraphData.GatherMinimalDependenciesFromFile(assetPath, assetCollection); var textGraph = File.ReadAllText(path, Encoding.UTF8); var graph = new GraphData { messageManager = new MessageManager(), assetGuid = AssetDatabase.AssetPathToGUID(path) }; MultiJson.Deserialize(graph, textGraph); graph.OnEnable(); graph.ValidateGraph(); Shader shader = null; #if VFX_GRAPH_10_0_0_OR_NEWER if (!graph.isOnlyVFXTarget) #endif { // build the shader text // this will also add Target dependencies into the asset collection var text = GetShaderText(path, out configuredTextures, assetCollection, graph); #if UNITY_2021_1_OR_NEWER // 2021.1 or later is guaranteed to have the new version of this function shader = ShaderUtil.CreateShaderAsset(ctx, text, false); #else // earlier builds of Unity may or may not have it // here we try to invoke the new version via reflection var createShaderAssetMethod = typeof(ShaderUtil).GetMethod( "CreateShaderAsset", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.ExactBinding, null, new Type[] { typeof(AssetImportContext), typeof(string), typeof(bool) }, null); if (createShaderAssetMethod != null) { shader = createShaderAssetMethod.Invoke(null, new Object[] { ctx, text, false }) as Shader; } else { // method doesn't exist in this version of Unity, call old version // this doesn't create dependencies properly, but is the best that we can do shader = ShaderUtil.CreateShaderAsset(text, false); } #endif if (graph.messageManager.nodeMessagesChanged) { foreach (var pair in graph.messageManager.GetNodeMessages()) { var node = graph.GetNodeFromId(pair.Key); MessageManager.Log(node, path, pair.Value.First(), shader); } } EditorMaterialUtility.SetShaderDefaults( shader, configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); EditorMaterialUtility.SetShaderNonModifiableDefaults( shader, configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); } UnityEngine.Object mainObject = shader; #if VFX_GRAPH_10_0_0_OR_NEWER ShaderGraphVfxAsset vfxAsset = null; if (graph.hasVFXTarget) { vfxAsset = GenerateVfxShaderGraphAsset(graph); if (mainObject == null) { mainObject = vfxAsset; } else { //Correct main object if we have a shader and ShaderGraphVfxAsset : save as sub asset vfxAsset.name = Path.GetFileNameWithoutExtension(path); ctx.AddObjectToAsset("VFXShaderGraph", vfxAsset); } } #endif Texture2D texture = Resources.Load <Texture2D>("Icons/sg_graph_icon"); ctx.AddObjectToAsset("MainAsset", mainObject, texture); ctx.SetMainObject(mainObject); foreach (var target in graph.activeTargets) { if (target is IHasMetadata iHasMetadata) { var metadata = iHasMetadata.GetMetadataObject(); if (metadata == null) { continue; } metadata.hideFlags = HideFlags.HideInHierarchy; ctx.AddObjectToAsset($"{iHasMetadata.identifier}:Metadata", metadata); } } var sgMetadata = ScriptableObject.CreateInstance <ShaderGraphMetadata>(); sgMetadata.hideFlags = HideFlags.HideInHierarchy; sgMetadata.assetDependencies = new List <UnityEngine.Object>(); foreach (var asset in assetCollection.assets) { if (asset.Value.HasFlag(AssetCollection.Flags.IncludeInExportPackage)) { // this sucks that we have to fully load these assets just to set the reference, // which then gets serialized as the GUID that we already have here. :P var dependencyPath = AssetDatabase.GUIDToAssetPath(asset.Key); if (!string.IsNullOrEmpty(dependencyPath)) { sgMetadata.assetDependencies.Add( AssetDatabase.LoadAssetAtPath(dependencyPath, typeof(UnityEngine.Object))); } } } ctx.AddObjectToAsset("SGInternal:Metadata", sgMetadata); // declare dependencies foreach (var asset in assetCollection.assets) { if (asset.Value.HasFlag(AssetCollection.Flags.SourceDependency)) { ctx.DependsOnSourceAsset(asset.Key); // I'm not sure if this warning below is actually used or not, keeping it to be safe var assetPath = AssetDatabase.GUIDToAssetPath(asset.Key); // Ensure that dependency path is relative to project if (!string.IsNullOrEmpty(assetPath) && !assetPath.StartsWith("Packages/") && !assetPath.StartsWith("Assets/")) { Debug.LogWarning($"Invalid dependency path: {assetPath}", mainObject); } } // NOTE: dependencies declared by GatherDependenciesFromSourceFile are automatically registered as artifact dependencies // HOWEVER: that path ONLY grabs dependencies via MinimalGraphData, and will fail to register dependencies // on GUIDs that don't exist in the project. For both of those reasons, we re-declare the dependencies here. if (asset.Value.HasFlag(AssetCollection.Flags.ArtifactDependency)) { ctx.DependsOnArtifact(asset.Key); } } }
public override void OnImportAsset(AssetImportContext ctx) { var oldShader = AssetDatabase.LoadAssetAtPath <Shader>(ctx.assetPath); if (oldShader != null) { ShaderUtil.ClearShaderMessages(oldShader); } List <PropertyCollector.TextureInfo> configuredTextures; string path = ctx.assetPath; var sourceAssetDependencyPaths = new List <string>(); var textGraph = File.ReadAllText(path, Encoding.UTF8); var graph = new GraphData { messageManager = new MessageManager(), assetGuid = AssetDatabase.AssetPathToGUID(path) }; MultiJson.Deserialize(graph, textGraph); graph.OnEnable(); graph.ValidateGraph(); Shader shader = null; #if VFX_GRAPH_10_0_0_OR_NEWER if (!graph.isOnlyVFXTarget) #endif { var text = GetShaderText(path, out configuredTextures, sourceAssetDependencyPaths, graph); #if UNITY_2021_1_OR_NEWER // 2021.1 or later is guaranteed to have the new version of this function shader = ShaderUtil.CreateShaderAsset(ctx, text, false); #else // earlier builds of Unity may or may not have it // here we try to invoke the new version via reflection var createShaderAssetMethod = typeof(ShaderUtil).GetMethod( "CreateShaderAsset", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.ExactBinding, null, new Type[] { typeof(AssetImportContext), typeof(string), typeof(bool) }, null); if (createShaderAssetMethod != null) { shader = createShaderAssetMethod.Invoke(null, new Object[] { ctx, text, false }) as Shader; } else { // method doesn't exist in this version of Unity, call old version // this doesn't create dependencies properly, but is the best that we can do shader = ShaderUtil.CreateShaderAsset(text, false); } #endif if (graph.messageManager.nodeMessagesChanged) { foreach (var pair in graph.messageManager.GetNodeMessages()) { var node = graph.GetNodeFromId(pair.Key); MessageManager.Log(node, path, pair.Value.First(), shader); } } EditorMaterialUtility.SetShaderDefaults( shader, configuredTextures.Where(x => x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); EditorMaterialUtility.SetShaderNonModifiableDefaults( shader, configuredTextures.Where(x => !x.modifiable).Select(x => x.name).ToArray(), configuredTextures.Where(x => !x.modifiable).Select(x => EditorUtility.InstanceIDToObject(x.textureId) as Texture).ToArray()); } UnityEngine.Object mainObject = shader; #if VFX_GRAPH_10_0_0_OR_NEWER ShaderGraphVfxAsset vfxAsset = null; if (graph.hasVFXTarget) { vfxAsset = GenerateVfxShaderGraphAsset(graph); if (mainObject == null) { mainObject = vfxAsset; } else { //Correct main object if we have a shader and ShaderGraphVfxAsset : save as sub asset vfxAsset.name = Path.GetFileNameWithoutExtension(path); ctx.AddObjectToAsset("VFXShaderGraph", vfxAsset); } } #endif Texture2D texture = Resources.Load <Texture2D>("Icons/sg_graph_icon@64"); ctx.AddObjectToAsset("MainAsset", mainObject, texture); ctx.SetMainObject(mainObject); foreach (var target in graph.activeTargets) { if (target is IHasMetadata iHasMetadata) { var metadata = iHasMetadata.GetMetadataObject(); if (metadata == null) { continue; } metadata.hideFlags = HideFlags.HideInHierarchy; ctx.AddObjectToAsset($"{iHasMetadata.identifier}:Metadata", metadata); } } var sgMetadata = ScriptableObject.CreateInstance <ShaderGraphMetadata>(); sgMetadata.hideFlags = HideFlags.HideInHierarchy; sgMetadata.assetDependencies = new List <UnityEngine.Object>(); var deps = GatherDependenciesFromSourceFile(ctx.assetPath); foreach (string dependency in deps) { sgMetadata.assetDependencies.Add(AssetDatabase.LoadAssetAtPath(dependency, typeof(UnityEngine.Object))); } ctx.AddObjectToAsset("SGInternal:Metadata", sgMetadata); foreach (var sourceAssetDependencyPath in sourceAssetDependencyPaths.Distinct()) { // Ensure that dependency path is relative to project if (!sourceAssetDependencyPath.StartsWith("Packages/") && !sourceAssetDependencyPath.StartsWith("Assets/")) { Debug.LogWarning($"Invalid dependency path: {sourceAssetDependencyPath}", mainObject); continue; } ctx.DependsOnSourceAsset(sourceAssetDependencyPath); } }