public static void UpdateAllRaymarchScenes() { if (Application.isPlaying) { Debug.LogError("Cannot update all raymarch scenes while playing!"); } Debug.Log("Updating all raymarch scenes"); string[] guids = AssetDatabase.FindAssets($"t:{nameof(SceneAsset)}", null); List <string> scenePaths = new List <string>(guids.Length); scenePaths.AddRange(guids.Select(AssetDatabase.GUIDToAssetPath)); Scene currentScene = SceneManager.GetActiveScene(); string currentScenePath = string.Empty; foreach (var path in scenePaths) { // NOTE(WSWhitehouse): Ignore scenes that are located in the packages if (path.StartsWith("Packages/")) { continue; } Scene openScene = EditorSceneManager.OpenScene(path); if (openScene.name == currentScene.name) { currentScenePath = path; } if (RaymarchScene.Get() == null) { continue; } RaymarchShaderGen.GenerateRaymarchShader(); } if (!string.IsNullOrEmpty(currentScenePath)) { EditorSceneManager.OpenScene(currentScenePath); } }
public static void CreateRaymarchScene() { var rmScene = RaymarchScene.Get(); if (rmScene != null) { Debug.LogError($"There is already an RM Scene in this scene ({SceneManager.GetActiveScene().name})"); EditorGUIUtility.PingObject(rmScene); Selection.SetActiveObjectWithContext(rmScene.gameObject, rmScene.gameObject); return; } var obj = new GameObject("RM Scene"); rmScene = obj.AddComponent <RaymarchScene>(); Selection.SetActiveObjectWithContext(obj, obj); }
public static void GenerateRaymarchShader() { Debug.Log($"Generating Raymarch Shader in '{SceneManager.GetActiveScene().name}'"); if (Application.isPlaying) { Debug.LogError($"{nameof(GenerateRaymarchShader)} called during runtime"); return; } RaymarchScene rmScene = RaymarchScene.Get(); // Raymarch Scene Sanity Checks if (rmScene == null) { Debug.LogError($"{nameof(RaymarchShaderGen)}: There is no {nameof(RaymarchScene)} in the active scene"); return; } if (rmScene.templateShader == null) { Debug.LogError($"{nameof(RaymarchShaderGen)}: There is no template shader in the {nameof(RaymarchScene)}"); return; } Scene activeScene = rmScene.gameObject.scene; var raymarchBases = GenerateRaymarchSceneHierarchy(activeScene); string currentDir = Directory.GetCurrentDirectory(); // Finding path of template string templatePath = string.Concat(currentDir, "/", AssetDatabase.GetAssetPath(rmScene.templateShader)); // Find/Create path for Generated Shader string scenePath = string.Concat(currentDir, "/", activeScene.path); string sceneName = Path.GetFileNameWithoutExtension(scenePath); scenePath = string.Concat(Path.GetDirectoryName(scenePath), "/"); string shaderName = string.Concat(sceneName, "_RaymarchShader"); string filePath = string.Concat(scenePath, sceneName); Directory.CreateDirectory(filePath); filePath = string.Concat(filePath, "/", shaderName, ".shader"); if (File.Exists(filePath)) { File.Delete(filePath); } // NOTE(WSWhitehouse): Creating strings to hold shader code that will be inserted into the shader int capacity = StringCapacityPerObject * raymarchBases.Count; StringBuilder raymarchVars = new StringBuilder(capacity); StringBuilder raymarchDistance = new StringBuilder(capacity); StringBuilder raymarchLight = new StringBuilder(capacity); raymarchVars.AppendLine("// Raymarch Variables"); foreach (RaymarchBase raymarchBase in raymarchBases) { raymarchVars.AppendLine(raymarchBase.GetShaderVariables()); } List <RaymarchOperation> operations = new List <RaymarchOperation>(); for (int i = 0; i < raymarchBases.Count; i++) { string guid = raymarchBases[i].GUID.ToShaderSafeString(); if (raymarchBases[i] is RaymarchOperation rmOperation) { operations.Add(rmOperation); var opGuid = rmOperation.GUID.ToShaderSafeString(); raymarchDistance.AppendLine($"// Operation Start {rmOperation.operation.ShaderFeatureAsset.FunctionName} {opGuid}"); raymarchDistance.AppendLine($"float distance{opGuid} = _RenderDistance;"); raymarchDistance.AppendLine($"float4 colour{opGuid} = float4(1,1,1,1);"); raymarchDistance.AppendLine(); } if (raymarchBases[i] is RaymarchObject rmObject) { string positionName = $"_{nameof(rmObject.Position)}{guid}"; string rotationName = $"_{nameof(rmObject.RotationRotor3D)}{guid}"; string rotation4DName = $"_{nameof(rmObject.Rotation4D)}{guid}"; string scaleName = $"_{nameof(rmObject.Scale)}{guid}"; string transform4DEnabledName = $"_{nameof(rmObject.Transform4DEnabled)}{guid}"; string localDistName = $"distance{guid}"; string localPosName = $"position{guid}"; raymarchDistance.AppendLine( $"float4 {localPosName} = (rayPos4D - {positionName}) / {scaleName};"); raymarchDistance.AppendLine( $"{localPosName} = float4(Rotate3D({localPosName}.xyz, {rotationName}), {localPosName}.w);"); // raymarchDistance.AppendLine($"if ({transform4DEnabledName} > 0)"); // raymarchDistance.AppendLine("{"); // raymarchDistance.AppendLine($"{localPosName} = Rotate4D({localPosName}, {rotation4DName});"); // raymarchDistance.AppendLine("}"); raymarchDistance.AppendLine($"int result{transform4DEnabledName} = {transform4DEnabledName} > 0;"); raymarchDistance.AppendLine($"{localPosName} = Rotate4D({localPosName}, {rotation4DName}) * result{transform4DEnabledName} + " + $"{localPosName} * !result{transform4DEnabledName};"); raymarchDistance.AppendLine(); raymarchDistance.AppendLine($"float {localDistName} = _RenderDistance;"); raymarchDistance.Append(RaymarchObjectDistanceShaderCode(rmObject)); raymarchDistance.AppendLine(); if (operations.Count > 0) { var operation = operations[^ 1];