using UnityEditor; using UnityEngine; namespace EditorTools { public class SubsurfaceLookupTextureIntegratorWindow : EditorWindow { [MenuItem("Tools/Subsurface LUT Integrator", false, 1000)] static void ShowIntegratorWindow() { GetWindow(typeof(SubsurfaceLookupTextureIntegratorWindow), false, "Subsurface LUT Integrator"); } private Color FalloffColor = new Color(1.0f, 0.3f, 0.2f); private float Radius = 4; private bool KeepDirectBounce = false; [SerializeField] private ComputeShader IntegratorShader; private RenderTexture IntegratedLUT = null; private int resolution = 512; private void OnEnable() { //IntegratorShader = AssetDatabase.LoadAssetAtPath("Assets/Scripts/Tools/Editor/SSS/SubsurfaceLookupTextureIntegrator.compute"); } private void OnDestroy() { if (IntegratedLUT != null) { RenderTexture.ReleaseTemporary(IntegratedLUT); } } void OnGUI() { GUILayout.Label("Base Settings", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); FalloffColor = EditorGUILayout.ColorField("Fallof Color", FalloffColor); Radius = EditorGUILayout.Slider("Radius", Radius, 0, 20); KeepDirectBounce = EditorGUILayout.Toggle("Keep Direct Bounce", KeepDirectBounce); resolution = EditorGUILayout.IntField("Resolution", resolution); if (EditorGUI.EndChangeCheck()) { Bake(); } EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Bake") && IntegratorShader != null) { Bake(); } if (GUILayout.Button("Save") && IntegratedLUT != null) { IntegratorShader.SetFloat("_Resoultion", (float)resolution); RenderTexture rt = RenderTexture.GetTemporary(resolution, resolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); Graphics.Blit(IntegratedLUT, rt); RenderTexture.active = rt; Texture2D tex = new Texture2D(resolution, resolution, TextureFormat.ARGB32, false, true); tex.ReadPixels(new Rect(0, 0, resolution, resolution), 0, 0); RenderTexture.active = null; RenderTexture.ReleaseTemporary(rt); string path = EditorUtility.SaveFilePanel("Export Texture", Application.dataPath, "SSS_Lut", "png"); if (path == null) return; System.IO.File.WriteAllBytes(path, tex.EncodeToPNG()); AssetDatabase.Refresh(); IntegratorShader.SetFloat("_Resoultion", (float)resolution); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); float width = position.width - 100; float height = position.height - 189; float sacle = width > height ? height / resolution : width / resolution; Rect rect = new Rect(50, 150, resolution * sacle, resolution * sacle); if (IntegratedLUT != null) { EditorGUI.DrawPreviewTexture(rect, IntegratedLUT); } else { EditorGUI.DrawRect(rect, Color.black); } } private void Bake() { if (IntegratedLUT != null) { RenderTexture.ReleaseTemporary(IntegratedLUT); } IntegratedLUT = RenderTexture.GetTemporary(resolution, resolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); IntegratedLUT.enableRandomWrite = true; if (KeepDirectBounce) { IntegratorShader.EnableKeyword("KEEP_DIRECT_BOUNCE"); } else { IntegratorShader.DisableKeyword("KEEP_DIRECT_BOUNCE"); } IntegratorShader.SetTexture(0, "_IntegratedLUT", IntegratedLUT); IntegratorShader.SetVector("_FalloffColor", FalloffColor); IntegratorShader.SetFloat("_Radius", Radius); IntegratorShader.SetFloat("_Resoultion", (float)resolution); IntegratorShader.Dispatch(0, resolution / 8, resolution / 8, 1); } } }