1+ /*
2+ * Copyright (c) 2020 AoiKamishiro
3+ *
4+ * This code is provided under the MIT license.
5+ *
6+ */
7+
8+ using System . Linq ;
9+ using UnityEditor ;
10+ using UnityEditor . SceneManagement ;
11+ using UnityEngine ;
12+ using UnityEngine . SceneManagement ;
13+ using UnityEngine . Rendering ;
14+
15+ namespace Kamishiro
16+ {
17+ public class AKBakery : EditorWindow
18+ {
19+ [ MenuItem ( "Tools/Kamishiro/BakeryAutoSetup" , priority = 150 ) ]
20+ private static void OnEnable ( )
21+ {
22+ AKBakery window = GetWindow < AKBakery > ( "BakeryAutoSetup" ) ;
23+ window . minSize = new Vector2 ( 320 , 400 ) ;
24+ window . Show ( ) ;
25+ }
26+ private void OnGUI ( )
27+ {
28+ if ( GUILayout . Button ( "Press" ) )
29+ {
30+ SetupScenes ( ) ;
31+ }
32+ }
33+
34+ private void SetupScenes ( )
35+ {
36+ Light [ ] pointLights = new Light [ ] { } ;
37+ Light [ ] areaLights = new Light [ ] { } ;
38+ Light [ ] directionalLights = new Light [ ] { } ;
39+ BakerySkyLight [ ] skyLights = new BakerySkyLight [ ] { } ;
40+
41+ Scene scene = SceneManager . GetActiveScene ( ) ;
42+ GameObject [ ] rootObjects = scene . GetRootGameObjects ( ) ;
43+ Transform [ ] transforms = new Transform [ ] { } ;
44+
45+ foreach ( GameObject gameObject in rootObjects )
46+ {
47+ transforms = transforms . Concat ( new Transform [ ] { } ) . Concat ( gameObject . GetComponentsInChildren < Transform > ( ) ) . ToArray ( ) ;
48+ }
49+
50+ foreach ( Transform transform in transforms )
51+ {
52+ Light light = transform . GetComponent < Light > ( ) ;
53+ if ( light != null && light . enabled && light . lightmapBakeType == LightmapBakeType . Baked && light . gameObject . activeInHierarchy )
54+ {
55+ if ( light . type == LightType . Point || light . type == LightType . Spot )
56+ {
57+ pointLights = pointLights . Concat ( new Light [ ] { light } ) . ToArray ( ) ;
58+ }
59+ if ( light . type == LightType . Area )
60+ {
61+ areaLights = areaLights . Concat ( new Light [ ] { light } ) . ToArray ( ) ;
62+ }
63+ if ( light . type == LightType . Directional )
64+ {
65+ directionalLights = directionalLights . Concat ( new Light [ ] { light } ) . ToArray ( ) ;
66+ }
67+ }
68+ BakerySkyLight bakerySkyLight = transform . GetComponent < BakerySkyLight > ( ) ;
69+ if ( bakerySkyLight != null )
70+ {
71+ skyLights = skyLights . Concat ( new BakerySkyLight [ ] { bakerySkyLight } ) . ToArray ( ) ;
72+ }
73+ }
74+ foreach ( Light pointLight in pointLights )
75+ {
76+ SetupPointLight ( pointLight ) ;
77+ pointLight . enabled = false ;
78+ pointLight . tag = "EditorOnly" ;
79+ }
80+ foreach ( Light areaLight in areaLights )
81+ {
82+ SetupAreaLight ( areaLight ) ;
83+ areaLight . enabled = false ;
84+ }
85+ foreach ( Light directionalLight in directionalLights )
86+ {
87+ SetupDirectionalLight ( directionalLight ) ;
88+ directionalLight . enabled = false ;
89+ directionalLight . tag = "EditorOnly" ;
90+ }
91+ if ( skyLights . Length == 0 )
92+ {
93+ SetupSkyKight ( ) ;
94+ }
95+ EditorSceneManager . MarkSceneDirty ( scene ) ;
96+ }
97+ private void SetupPointLight ( Light light )
98+ {
99+ BakeryPointLight bakeryPointLight = light . GetComponent < BakeryPointLight > ( ) ;
100+ if ( bakeryPointLight == null ) { bakeryPointLight = light . gameObject . AddComponent < BakeryPointLight > ( ) ; }
101+ //bakeryPointLight.color = light.color;
102+ //bakeryPointLight.intensity = light.intensity;
103+ if ( PlayerSettings . colorSpace != ColorSpace . Linear )
104+ {
105+ bakeryPointLight . color = light . color ;
106+ bakeryPointLight . intensity = light . intensity ;
107+ }
108+ else if ( ! GraphicsSettings . lightsUseLinearIntensity )
109+ {
110+ float lightR , lightG , lightB , lightInt ;
111+ GetLinearLightParameters ( light , out lightR , out lightG , out lightB , out lightInt ) ;
112+ bakeryPointLight . color = new Color ( lightR , lightG , lightB ) ;
113+ bakeryPointLight . intensity = lightInt ;
114+ }
115+ else
116+ {
117+ bakeryPointLight . color = light . color ;
118+ bakeryPointLight . intensity = light . intensity ;
119+ }
120+ bakeryPointLight . shadowSpread = 0.05f ;
121+ bakeryPointLight . realisticFalloff = false ;
122+ bakeryPointLight . falloffMinRadius = 1f ;
123+ bakeryPointLight . cutoff = light . range ;
124+ bakeryPointLight . samples = 8 ;
125+ bakeryPointLight . projMode = light . type == LightType . Point ? BakeryPointLight . ftLightProjectionMode . Omni : BakeryPointLight . ftLightProjectionMode . Cookie ;
126+ bakeryPointLight . cookie = light . type == LightType . Point ? null : AssetDatabase . LoadAssetAtPath ( ftLightmaps . GetRuntimePath ( ) + "ftUnitySpotTexture.bmp" , typeof ( Texture2D ) ) as Texture2D ;
127+ bakeryPointLight . angle = light . spotAngle ;
128+ bakeryPointLight . bitmask = 1 ;
129+ bakeryPointLight . indirectIntensity = light . bounceIntensity ;
130+ }
131+ private void SetupAreaLight ( Light light )
132+ {
133+ GameObject quad = GameObject . CreatePrimitive ( PrimitiveType . Quad ) ;
134+ MeshFilter meshFilter = light . GetComponent < MeshFilter > ( ) ;
135+ MeshRenderer meshRenderer = light . GetComponent < MeshRenderer > ( ) ;
136+ BakeryLightMesh bakeryLightMesh = light . GetComponent < BakeryLightMesh > ( ) ;
137+ if ( meshFilter == null ) { meshFilter = light . gameObject . AddComponent < MeshFilter > ( ) ; }
138+ if ( meshRenderer == null ) { meshRenderer = light . gameObject . AddComponent < MeshRenderer > ( ) ; }
139+ if ( bakeryLightMesh == null ) { bakeryLightMesh = light . gameObject . AddComponent < BakeryLightMesh > ( ) ; }
140+ light . transform . localScale = Vector3 . one ;
141+ meshFilter . mesh = quad . GetComponent < MeshFilter > ( ) . mesh = quad . GetComponent < MeshFilter > ( ) . sharedMesh ;
142+ meshRenderer . material = AssetDatabase . LoadAssetAtPath ( ftLightmaps . GetRuntimePath ( ) + "ftDefaultAreaLightMat.mat" , typeof ( Material ) ) as Material ;
143+
144+ float scale = light . transform . lossyScale . z ;
145+ light . transform . localScale = new Vector3 ( light . areaSize . x / scale , light . areaSize . y / scale , 1 ) ;
146+ if ( PlayerSettings . colorSpace != ColorSpace . Linear )
147+ {
148+ bakeryLightMesh . color = light . color ;
149+ bakeryLightMesh . intensity = light . intensity ;
150+ }
151+ else if ( ! GraphicsSettings . lightsUseLinearIntensity )
152+ {
153+ float lightR , lightG , lightB , lightInt ;
154+ GetLinearLightParameters ( light , out lightR , out lightG , out lightB , out lightInt ) ;
155+ bakeryLightMesh . color = new Color ( lightR , lightG , lightB ) ;
156+ bakeryLightMesh . intensity = lightInt ;
157+ }
158+ else
159+ {
160+ bakeryLightMesh . color = light . color ;
161+ bakeryLightMesh . intensity = light . intensity ;
162+ }
163+ bakeryLightMesh . cutoff = light . range * 1.5f ;
164+ bakeryLightMesh . selfShadow = false ;
165+ bakeryLightMesh . indirectIntensity = light . bounceIntensity ;
166+
167+ light . tag = "EditorOnly" ;
168+ light . gameObject . isStatic = false ;
169+ DestroyImmediate ( quad ) ;
170+ }
171+ private void SetupDirectionalLight ( Light light )
172+ {
173+ BakeryDirectLight bakeryDirectLight = light . GetComponent < BakeryDirectLight > ( ) ;
174+ if ( bakeryDirectLight == null ) { bakeryDirectLight = light . gameObject . AddComponent < BakeryDirectLight > ( ) ; }
175+ if ( PlayerSettings . colorSpace != ColorSpace . Linear )
176+ {
177+ bakeryDirectLight . color = light . color ;
178+ bakeryDirectLight . intensity = light . intensity ;
179+ }
180+ else if ( ! GraphicsSettings . lightsUseLinearIntensity )
181+ {
182+ float lightR , lightG , lightB , lightInt ;
183+ GetLinearLightParameters ( light , out lightR , out lightG , out lightB , out lightInt ) ;
184+ bakeryDirectLight . color = new Color ( lightR , lightG , lightB ) ;
185+ bakeryDirectLight . intensity = lightInt ;
186+ }
187+ else
188+ {
189+ bakeryDirectLight . color = light . color ;
190+ bakeryDirectLight . intensity = light . intensity ;
191+ }
192+ bakeryDirectLight . indirectIntensity = light . bounceIntensity ;
193+ bakeryDirectLight . shadowSpread = 0.01f ;
194+ bakeryDirectLight . samples = 16 ;
195+ bakeryDirectLight . bitmask = 1 ;
196+ }
197+ private void SetupSkyKight ( )
198+ {
199+ Material skyMat = RenderSettings . skybox ;
200+
201+ GameObject skyKight = new GameObject ( ) ;
202+ BakerySkyLight bakerySkyLight = skyKight . AddComponent < BakerySkyLight > ( ) ;
203+ skyKight . name = "Skylight" ;
204+
205+ if ( skyMat . HasProperty ( "_Tex" ) && skyMat . HasProperty ( "_Exposure" ) && skyMat . HasProperty ( "_Tint" ) )
206+ {
207+ bakerySkyLight . cubemap = skyMat . GetTexture ( "_Tex" ) as Cubemap ;
208+ float exposure = skyMat . GetFloat ( "_Exposure" ) ;
209+ bool exposureSRGB = skyMat . shader . name == "Skybox/Cubemap" ;
210+ if ( exposureSRGB )
211+ {
212+ exposure = Mathf . Pow ( exposure , 2.2f ) ; // can't detect [Gamma] keyword...
213+ exposure *= PlayerSettings . colorSpace == ColorSpace . Linear ? 4.59f : 2 ; // weird unity constant
214+ }
215+ bakerySkyLight . intensity = exposure ;
216+ bakerySkyLight . color = skyMat . GetColor ( "_Tint" ) ;
217+
218+ float matAngle = 0 ;
219+ if ( skyMat . HasProperty ( "_Rotation" ) ) matAngle = skyMat . GetFloat ( "_Rotation" ) ;
220+ var matQuat = Quaternion . Euler ( 0 , matAngle , 0 ) ;
221+ bakerySkyLight . transform . rotation = matQuat ;
222+ }
223+ skyKight . tag = "EditorOnly" ;
224+ }
225+ public string GetPath ( Transform self )
226+ {
227+ string path = self . gameObject . name ;
228+
229+ Transform parent = self . parent ;
230+
231+ while ( parent != null )
232+ {
233+ path = parent . name + "/" + path ;
234+ parent = parent . parent ;
235+ }
236+
237+ return path ;
238+ }
239+ void GetLinearLightParameters ( Light light , out float lightR , out float lightG , out float lightB , out float lightInt )
240+ {
241+ if ( PlayerSettings . colorSpace != ColorSpace . Linear )
242+ {
243+ lightInt = light . intensity ;
244+ lightR = light . color . r ;
245+ lightG = light . color . g ;
246+ lightB = light . color . b ;
247+ return ;
248+ }
249+
250+ if ( ! GraphicsSettings . lightsUseLinearIntensity )
251+ {
252+ lightR = Mathf . Pow ( light . color . r * light . intensity , 2.2f ) ;
253+ lightG = Mathf . Pow ( light . color . g * light . intensity , 2.2f ) ;
254+ lightB = Mathf . Pow ( light . color . b * light . intensity , 2.2f ) ;
255+ lightInt = Mathf . Max ( Mathf . Max ( lightR , lightG ) , lightB ) ;
256+ lightR /= lightInt ;
257+ lightG /= lightInt ;
258+ lightB /= lightInt ;
259+ }
260+ else
261+ {
262+ lightInt = light . intensity ;
263+ lightR = light . color . linear . r ;
264+ lightG = light . color . linear . g ;
265+ lightB = light . color . linear . b ;
266+ }
267+ }
268+ }
269+ }
0 commit comments