@@ -23,9 +23,7 @@ public partial class AreaLight : BaseLight, IComparable<AreaLight>
2323 private const int lutMatrixDim = 3 ;
2424 private static readonly Matrix4x4 rotation180Up = Matrix4x4 . Rotate ( Quaternion . AngleAxis ( 180.0f , Vector3 . up ) ) ;
2525
26- private static Texture2D transformInvTextureSpecular ;
27- private static Texture2D transformInvTextureDiffuse ;
28- private static Texture2D ampDiffAmpSpecFresnel ;
26+ private static Texture2D areaLightLUTAtlas ;
2927
3028 private static int lastAreaLightUpdate = - 1 ;
3129 private static List < AreaLight > activeAreaLights = new ( maxAreaLights ) ;
@@ -258,10 +256,16 @@ protected override void Initialize()
258256 areaLightCookiesIDs [ i ] = Shader . PropertyToID ( $ "_AreaLightCookie{ i } ") ;
259257 }
260258
261- facingID = Shader . PropertyToID ( "_facing" ) ;
262- uvStartsAtTopID = Shader . PropertyToID ( "_uvStartsAtTop" ) ;
259+ facingID = Shader . PropertyToID ( "_Facing" ) ;
260+ uvStartsAtTopID = Shader . PropertyToID ( "_UVStartsAtTop" ) ;
261+
262+ if ( areaLightLUTAtlas == null )
263+ {
264+ areaLightLUTAtlas = CreateLUTAtlas ( ) ;
265+ }
266+
267+ Shader . SetGlobalTexture ( "_AreaLightLUTAtlas" , areaLightLUTAtlas ) ;
263268
264- CreateLUTs ( ) ;
265269 UpdateLightSourceVisual ( ) ;
266270
267271 // Only create a culling group when playing since we can't consistently dispose of them in edit mode.
@@ -522,28 +526,6 @@ private static Vector3 TransformVertex(int index, Vector2 size, Matrix4x4 localT
522526 return localToWorld . MultiplyPoint ( vertex ) ;
523527 }
524528
525- private static void CreateLUTs ( )
526- {
527- if ( transformInvTextureDiffuse == null )
528- {
529- transformInvTextureDiffuse = LoadLUT ( LUTType . TransformInv_DisneyDiffuse ) ;
530- }
531-
532- if ( transformInvTextureSpecular == null )
533- {
534- transformInvTextureSpecular = LoadLUT ( LUTType . TransformInv_GGX ) ;
535- }
536-
537- if ( ampDiffAmpSpecFresnel == null )
538- {
539- ampDiffAmpSpecFresnel = LoadLUT ( LUTType . AmpDiffAmpSpecFresnel ) ;
540- }
541-
542- Shader . SetGlobalTexture ( "_TransformInvDiffuse" , transformInvTextureDiffuse ) ;
543- Shader . SetGlobalTexture ( "_TransformInvSpecular" , transformInvTextureSpecular ) ;
544- Shader . SetGlobalTexture ( "_AmpDiffAmpSpecFresnel" , ampDiffAmpSpecFresnel ) ;
545- }
546-
547529 private void UpdateLightSourceVisual ( )
548530 {
549531 if ( drawLightSource && enabled )
@@ -598,46 +580,44 @@ private void DestroyLightVisual(bool destroyMaterial = true)
598580 }
599581 }
600582
601- private enum LUTType
583+ private static Texture2D CreateLUTAtlas ( )
602584 {
603- TransformInv_DisneyDiffuse ,
604- TransformInv_GGX ,
605- AmpDiffAmpSpecFresnel
606- }
585+ var diffusePixels = LoadLUT ( s_LUTTransformInv_DisneyDiffuse ) ;
586+ var specularPixels = LoadLUT ( s_LUTTransformInv_GGX ) ;
587+ var fresnelPixels = LoadLUT ( s_LUTAmplitude_DisneyDiffuse , s_LUTAmplitude_GGX , s_LUTFresnel_GGX ) ;
607588
608- private static Texture2D LoadLUT ( LUTType type )
609- {
610- switch ( type )
589+ // Combine all three LUTs into a single texture. Each LUT side by side.
590+ // Diffuse Specular Fresnel
591+ // +----------+----------+----------+
592+ // | | | |
593+ // | XX | XX | XX |
594+ // | | | |
595+ // +----------+----------+----------+
596+ int combinedWidth = lutResolution * 3 ;
597+ int combinedHeight = lutResolution ;
598+ Texture2D combinedLUT = new Texture2D ( combinedWidth , combinedHeight , TextureFormat . RGBAHalf , false , true ) ;
599+ combinedLUT . hideFlags = HideFlags . HideAndDontSave ;
600+ combinedLUT . wrapMode = TextureWrapMode . Clamp ;
601+
602+ var combinedPixels = new Color [ combinedWidth * combinedHeight ] ;
603+
604+ for ( int y = 0 ; y < lutResolution ; y ++ )
611605 {
612- case LUTType . TransformInv_DisneyDiffuse :
613- {
614- return LoadLUT ( s_LUTTransformInv_DisneyDiffuse ) ;
615- }
616- case LUTType . TransformInv_GGX :
617- {
618- return LoadLUT ( s_LUTTransformInv_GGX ) ;
619- }
620- case LUTType . AmpDiffAmpSpecFresnel :
621- {
622- return LoadLUT ( s_LUTAmplitude_DisneyDiffuse , s_LUTAmplitude_GGX , s_LUTFresnel_GGX ) ;
623- }
606+ for ( int x = 0 ; x < lutResolution ; x ++ )
607+ {
608+ combinedPixels [ y * combinedWidth + x ] = diffusePixels [ y * lutResolution + x ] ;
609+ combinedPixels [ y * combinedWidth + x + lutResolution ] = specularPixels [ y * lutResolution + x ] ;
610+ combinedPixels [ y * combinedWidth + x + 2 * lutResolution ] = fresnelPixels [ y * lutResolution + x ] ;
611+ }
624612 }
625613
626- return null ;
627- }
628-
629- private static Texture2D CreateLUT ( TextureFormat format , Color [ ] pixels )
630- {
631- var texture = new Texture2D ( lutResolution , lutResolution , format , false /*mipmap*/ , true /*linear*/ ) ;
632- texture . hideFlags = HideFlags . HideAndDontSave ;
633- texture . wrapMode = TextureWrapMode . Clamp ;
634- texture . SetPixels ( pixels ) ;
635- texture . Apply ( ) ;
614+ combinedLUT . SetPixels ( combinedPixels ) ;
615+ combinedLUT . Apply ( ) ;
636616
637- return texture ;
617+ return combinedLUT ;
638618 }
639619
640- private static Texture2D LoadLUT ( double [ , ] LUTTransformInv )
620+ private static Color [ ] LoadLUT ( double [ , ] LUTTransformInv )
641621 {
642622 const int count = lutResolution * lutResolution ;
643623 Color [ ] pixels = new Color [ count ] ;
@@ -651,10 +631,10 @@ private static Texture2D LoadLUT(double[,] LUTTransformInv)
651631 ( float ) LUTTransformInv [ i , 6 ] ) ;
652632 }
653633
654- return CreateLUT ( TextureFormat . RGBAHalf , pixels ) ;
634+ return pixels ;
655635 }
656636
657- private static Texture2D LoadLUT ( float [ ] LUTScalar0 , float [ ] LUTScalar1 , float [ ] LUTScalar2 )
637+ private static Color [ ] LoadLUT ( float [ ] LUTScalar0 , float [ ] LUTScalar1 , float [ ] LUTScalar2 )
658638 {
659639 const int count = lutResolution * lutResolution ;
660640 Color [ ] pixels = new Color [ count ] ;
@@ -665,7 +645,7 @@ private static Texture2D LoadLUT(float[] LUTScalar0, float[] LUTScalar1, float[]
665645 pixels [ i ] = new Color ( LUTScalar0 [ i ] , LUTScalar1 [ i ] , LUTScalar2 [ i ] , 0 ) ;
666646 }
667647
668- return CreateLUT ( TextureFormat . RGBAHalf , pixels ) ;
648+ return pixels ;
669649 }
670650 }
671651}
0 commit comments