static string[] OnWillSaveAssets(string[] assetPaths) { //find all TextureRecipe assets, then check if any are being saved List <string> recipeAssetPaths = new List <string>(); var recipeGUIDs = AssetDatabase.FindAssets("t:TextureRecipe"); foreach (var recipeID in recipeGUIDs) { recipeAssetPaths.Add(AssetDatabase.GUIDToAssetPath(recipeID)); } foreach (string assetPath in assetPaths) { if (recipeAssetPaths.Contains(assetPath)) { //We are saving this recipe so generate any other assets that it requires TextureRecipe recipe = AssetDatabase.LoadAssetAtPath <TextureRecipe>(assetPath); GeneratorFactory.createMappings(); var builtSubAssetPaths = bakeSubAssets(recipe); var oldAssetPaths = new List <string>(assetPaths); oldAssetPaths.AddRange(builtSubAssetPaths); assetPaths = oldAssetPaths.ToArray(); } } return(assetPaths); }
static void bakeShaderLayerSubAssets(ShaderLayer shaderLayer, TextureRecipe recipe, List <string> subAssetPaths) { var shader = ShaderGenerator.bakeShader(shaderLayer, recipe); if (null == shader) { UnityEngine.Debug.LogError("Failed to load shader " + shaderLayer.name); return; } subAssetPaths.Add(shader.name); foreach (var node in shaderLayer.nodes) { if (!node.assetsDirty) { continue; } var nodeAssetGenerator = GeneratorFactory.getAssetGenerator(node); if (null != nodeAssetGenerator) { var newAssetPaths = nodeAssetGenerator.generateAssets(node); if (newAssetPaths.Count > 0) { subAssetPaths.AddRange(newAssetPaths); } node.assetsDirty = false; } } }
public string getCallStr(BaseNode.NodeInput nodeInput, Dictionary <string, string> outputVariableNames) { var node = nodeInput.inputNode; int numInputs = node.inputs.Count; string callStr = ""; //pre evaluation callStr += getPreEvaluation(nodeInput); for (int i = 0; i < numInputs; i++) { var input = node.inputs[i]; if (null != input.inputNode) { callStr += GeneratorFactory.getShaderGenerator(input.inputNode).getCallStr(input, outputVariableNames); } } string outputVariableName = "out" + node.GetType().Name + node.getNodeID() + "_" + nodeInput.outputIndex; bool declareOutputVariable = !outputVariableNames.ContainsKey(outputVariableName); if (declareOutputVariable) { outputVariableNames.Add(outputVariableName, outputVariableName); callStr += "fixed4 "; } callStr += outputVariableName + "= " + getFunctionName(nodeInput) + "( uv,0,0"; for (int i = 0; i < numInputs; i++) { callStr += ", "; var input = node.inputs[i]; if (null != input.inputNode) { callStr += "out" + input.inputNode.GetType().Name + input.inputNode.getNodeID() + "_" + input.outputIndex; } else { callStr += "float4(0,0,0,0)"; } } callStr += " );\n"; //post-evaluation callStr += getPostEvaluation(nodeInput); return(callStr); }
static void buildModifiedShaders() { if (!EditorApplication.isPlaying && EditorApplication.isPlayingOrWillChangePlaymode) { //TODO: is there a way to figure out which shaders need building? var recipeGUIDs = AssetDatabase.FindAssets("t:TextureRecipe"); foreach (var recipeID in recipeGUIDs) { string assetPath = AssetDatabase.GUIDToAssetPath(recipeID); TextureRecipe recipe = AssetDatabase.LoadAssetAtPath <TextureRecipe>(assetPath); GeneratorFactory.createMappings(); bakeSubAssets(recipe); } } }
private static string getCalls(ShaderLayer shaderLayer) { Dictionary <string, string> outputVariableNames = new Dictionary <string, string>(); string nodeCalls = ""; var rootInput = shaderLayer.getRoot().inputs[0]; if (rootInput.inputNode != null) { nodeCalls += GeneratorFactory.getShaderGenerator(rootInput.inputNode).getCallStr(rootInput, outputVariableNames); nodeCalls += "col = out" + rootInput.inputNode.GetType().Name + rootInput.inputNode.getNodeID() + "_" + rootInput.outputIndex + ";"; } return(nodeCalls); }
void UpdatePreviewTexture(TextureRecipe targetRecipe, Texture2D previewTex) { if (!refreshPreviewTexture) { return; } refreshPreviewTexture = false; GeneratorFactory.createMappings(); RecipeBuildPreProcess.bakeSubAssets(targetRecipe); TextureRecipeRenderer renderer = new TextureRecipeRenderer(targetRecipe); renderer.renderSetup(previewTex); renderer.renderRecipeInternal(); previewTex.ReadPixels(new Rect(0, 0, previewTex.width, previewTex.height), 0, 0); previewTex.Apply(); RenderTexture.active = null; renderer.renderTeardown(); }
public override void OnInspectorGUI() { serializedObject.Update(); TextureRecipe targetRecipe = (TextureRecipe)target; var texWidthProp = serializedObject.FindProperty("TextureWidth"); var texHeightProp = serializedObject.FindProperty("TextureHeight"); texWidthProp.intValue = EditorGUILayout.IntField("Width", texWidthProp.intValue); texHeightProp.intValue = EditorGUILayout.IntField("Height", texHeightProp.intValue); serializedObject.ApplyModifiedProperties(); if (GUILayout.Button("Bake")) { GeneratorFactory.createMappings(); RecipeBuildPreProcess.bakeSubAssets(targetRecipe); TextureRecipeRenderer renderer = new TextureRecipeRenderer(targetRecipe); renderer.renderSetup(); renderer.renderRecipeInternal(); TextureWriter.WriteRenderBufferToTextureFile(targetRecipe.TextureWidth, targetRecipe.TextureHeight, targetRecipe); RenderTexture.active = null; renderer.renderTeardown(); } reorderableList.DoLayoutList(); int listIndex = reorderableList.index; var layerList = serializedObject.FindProperty("layerList"); if (listIndex >= 0 && listIndex < layerList.arraySize) { var listItem = layerList.GetArrayElementAtIndex(listIndex); if (null != listItem.objectReferenceValue) { if (subEditorType != listItem.objectReferenceValue.GetType()) { subEditor = null; } EditorGUI.BeginChangeCheck(); ShaderLayerEditor.recipe = (TextureRecipe)target; CreateCachedEditor(listItem.objectReferenceValue, null, ref subEditor); subEditorType = listItem.objectReferenceValue.GetType(); subEditor.serializedObject.Update(); subEditor.OnInspectorGUI(); subEditor.serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties(); if (EditorGUI.EndChangeCheck() && targetRecipe.autoRefresh) { //do we need this if we set dirty on the target every frame? EditorUtility.SetDirty(listItem.objectReferenceValue); refreshPreviewTexture = true; } if (ShaderLayerEditor.nodeEditor && ShaderLayerEditor.nodeEditor.refreshShader && targetRecipe.autoRefresh) { refreshPreviewTexture = true; ShaderLayerEditor.nodeEditor.refreshShader = false; } } } //We have to do this every frame otherwise changes to the child objects aren't reflected in the inspector when we Undo them //there is perhaps an issue with the order of operations EditorUtility.SetDirty(target); }
private static string getNodeInputStr(BaseNode.NodeInput nodeInput) { return(GeneratorFactory.getShaderGenerator(nodeInput.inputNode).getInputs(nodeInput)); }
private static string getNodePropertyStr(BaseNode.NodeInput nodeInput) { var node = nodeInput.inputNode; return(GeneratorFactory.getShaderGenerator(node).getProperties(nodeInput)); }
private static string getNodeFunctionStr(BaseNode.NodeInput nodeInput) { var node = nodeInput.inputNode; return(GeneratorFactory.getShaderGenerator(node).getFunctionSignature(nodeInput) + GeneratorFactory.getShaderGenerator(node).getFunctionBody(nodeInput) + "}\n"); }