@@ -118,6 +118,7 @@ public void BindBuffers(Material mat)
118118 ShadowRenderPass m_ShadowPass ;
119119
120120
121+ public const int k_MaxDirectionalLightsOnSCreen = 2 ;
121122 public const int k_MaxPunctualLightsOnSCreen = 512 ;
122123 public const int k_MaxAreaLightsOnSCreen = 128 ;
123124 public const int k_MaxEnvLightsOnSCreen = 64 ;
@@ -141,8 +142,9 @@ public void BindBuffers(Material mat)
141142
142143 public class LightList
143144 {
144- public List < PunctualLightData > punctualLights ;
145- public List < AreaLightData > areaLights ;
145+ public List < DirectionalLightData > directionalLights ;
146+ public List < LightData > punctualLights ;
147+ public List < LightData > areaLights ;
146148 public List < EnvLightData > envLights ;
147149 public List < PunctualShadowData > punctualShadows ;
148150 }
@@ -668,8 +670,9 @@ void ConvertLightForGPU(CullResults cullResults, ref ShadowOutput shadowOutput,
668670 {
669671 // Init light list
670672 lightList = new LightList ( ) ;
671- lightList . punctualLights = new List < PunctualLightData > ( ) ;
672- lightList . areaLights = new List < AreaLightData > ( ) ;
673+ lightList . directionalLights = new List < DirectionalLightData > ( ) ;
674+ lightList . punctualLights = new List < LightData > ( ) ;
675+ lightList . areaLights = new List < LightData > ( ) ;
673676 lightList . envLights = new List < EnvLightData > ( ) ;
674677 lightList . punctualShadows = new List < PunctualShadowData > ( ) ;
675678
@@ -686,146 +689,141 @@ void ConvertLightForGPU(CullResults cullResults, ref ShadowOutput shadowOutput,
686689 continue ;
687690 }
688691
689- // Note: LightType.Area is offline only, use for baking, no need to test it
690-
691692 // Linear intensity calculation (different Unity 5.5)
692693 var lightColorR = light . light . intensity * Mathf . GammaToLinearSpace ( light . light . color . r ) ;
693694 var lightColorG = light . light . intensity * Mathf . GammaToLinearSpace ( light . light . color . g ) ;
694695 var lightColorB = light . light . intensity * Mathf . GammaToLinearSpace ( light . light . color . b ) ;
695696
696- // Test whether we should treat this punctual light as an area light.
697- // It's a temporary hack until the proper UI support is added.
698- if ( additionalData . treatAsAreaLight )
697+ if ( light . lightType == LightType . Directional )
699698 {
700- if ( lightList . areaLights . Count >= k_MaxAreaLightsOnSCreen )
699+ if ( lightList . areaLights . Count >= k_MaxDirectionalLightsOnSCreen )
701700 continue ;
702701
703- var lightData = new AreaLightData ( ) ;
702+ var directionalLightData = new DirectionalLightData ( ) ;
703+ // Light direction for directional and is opposite to the forward direction
704+ directionalLightData . direction = - light . light . transform . forward ;
705+ directionalLightData . color = new Vector3 ( lightColorR , lightColorG , lightColorB ) ;
706+ directionalLightData . diffuseScale = additionalData . affectDiffuse ? 1.0f : 0.0f ;
707+ directionalLightData . specularScale = additionalData . affectSpecular ? 1.0f : 0.0f ;
708+ directionalLightData . cosAngle = 0.0f ;
709+ directionalLightData . sinAngle = 0.0f ;
710+ directionalLightData . shadowIndex = - 1 ;
704711
705- // TODO: add AreaShapeType.Line support for small widths.
706- lightData . shapeType = AreaShapeType . Rectangle ;
707- lightData . size = new Vector2 ( additionalData . areaLightLength , additionalData . areaLightWidth ) ;
708- lightData . twoSided = additionalData . isDoubleSided ;
712+ // TODO: shadow
709713
710- lightData . positionWS = light . light . transform . position ;
711- lightData . forward = light . light . transform . forward ; // Note: Light direction is oriented backward (-Z)
712- lightData . up = light . light . transform . up ;
713- lightData . right = light . light . transform . right ;
714+ lightList . directionalLights . Add ( directionalLightData ) ;
714715
715- lightData . color = new Vector3 ( lightColorR , lightColorG , lightColorB ) ;
716- lightData . diffuseScale = additionalData . affectDiffuse ? 1.0f : 0.0f ;
717- lightData . specularScale = additionalData . affectSpecular ? 1.0f : 0.0f ;
718- lightData . shadowDimmer = additionalData . shadowDimmer ;
716+ continue ;
717+ }
719718
720- lightData . invSqrAttenuationRadius = 1.0f / ( light . range * light . range ) ;
719+ // Note: LightType.Area is offline only, use for baking, no need to test it
720+ var lightData = new LightData ( ) ;
721721
722- lightList . areaLights . Add ( lightData ) ;
722+ // Early out if we reach the maximum
723+ // Test whether we should treat this punctual light as an area light.
724+ // It's a temporary hack until the proper UI support is added.
725+ if ( additionalData . treatAsAreaLight )
726+ {
727+ if ( lightList . areaLights . Count >= k_MaxAreaLightsOnSCreen )
728+ continue ;
723729
724- // TODO: shadows.
730+ lightData . lightType = GPULightType . Rectangle ;
725731 }
726732 else
727733 {
728734 if ( lightList . punctualLights . Count >= k_MaxPunctualLightsOnSCreen )
729735 continue ;
730736
731- var punctualLightData = new PunctualLightData ( ) ;
732-
733- if ( light . lightType == LightType . Directional )
737+ switch ( light . lightType )
734738 {
735- punctualLightData . useDistanceAttenuation = 0.0f ;
736- // positionWS store Light direction for directional and is opposite to the forward direction
737- punctualLightData . positionWS = - light . light . transform . forward ;
738- punctualLightData . invSqrAttenuationRadius = 0.0f ;
739- }
740- else
741- {
742- punctualLightData . useDistanceAttenuation = 1.0f ;
743- punctualLightData . positionWS = light . light . transform . position ;
744- punctualLightData . invSqrAttenuationRadius = 1.0f / ( light . range * light . range ) ;
739+ case LightType . Directional : lightData . lightType = GPULightType . Directional ; break ;
740+ case LightType . Spot : lightData . lightType = GPULightType . Spot ; break ;
741+ case LightType . Point : lightData . lightType = GPULightType . Point ; break ;
745742 }
743+ }
746744
747- punctualLightData . color = new Vector3 ( lightColorR , lightColorG , lightColorB ) ;
745+ lightData . positionWS = light . light . transform . position ;
746+ lightData . invSqrAttenuationRadius = 1.0f / ( light . range * light . range ) ;
748747
749- punctualLightData . forward = light . light . transform . forward ; // Note: Light direction is oriented backward (-Z)
750- punctualLightData . up = light . light . transform . up ;
751- punctualLightData . right = light . light . transform . right ;
748+ lightData . color = new Vector3 ( lightColorR , lightColorG , lightColorB ) ;
749+
750+ lightData . forward = light . light . transform . forward ; // Note: Light direction is oriented backward (-Z)
751+ lightData . up = light . light . transform . up ;
752+ lightData . right = light . light . transform . right ;
752753
753- if ( light . lightType == LightType . Spot )
754- {
755- var spotAngle = light . spotAngle ;
754+ if ( lightData . lightType == GPULightType . Spot )
755+ {
756+ var spotAngle = light . spotAngle ;
756757
757- var innerConePercent = additionalData . GetInnerSpotPercent01 ( ) ;
758- var cosSpotOuterHalfAngle = Mathf . Clamp ( Mathf . Cos ( spotAngle * 0.5f * Mathf . Deg2Rad ) , 0.0f , 1.0f ) ;
759- var cosSpotInnerHalfAngle = Mathf . Clamp ( Mathf . Cos ( spotAngle * 0.5f * innerConePercent * Mathf . Deg2Rad ) , 0.0f , 1.0f ) ; // inner cone
758+ var innerConePercent = additionalData . GetInnerSpotPercent01 ( ) ;
759+ var cosSpotOuterHalfAngle = Mathf . Clamp ( Mathf . Cos ( spotAngle * 0.5f * Mathf . Deg2Rad ) , 0.0f , 1.0f ) ;
760+ var cosSpotInnerHalfAngle = Mathf . Clamp ( Mathf . Cos ( spotAngle * 0.5f * innerConePercent * Mathf . Deg2Rad ) , 0.0f , 1.0f ) ; // inner cone
760761
761- var val = Mathf . Max ( 0.001f , ( cosSpotInnerHalfAngle - cosSpotOuterHalfAngle ) ) ;
762- punctualLightData . angleScale = 1.0f / val ;
763- punctualLightData . angleOffset = - cosSpotOuterHalfAngle * punctualLightData . angleScale ;
762+ var val = Mathf . Max ( 0.001f , ( cosSpotInnerHalfAngle - cosSpotOuterHalfAngle ) ) ;
763+ lightData . angleScale = 1.0f / val ;
764+ lightData . angleOffset = - cosSpotOuterHalfAngle * lightData . angleScale ;
765+ }
766+ else
767+ {
768+ // 1.0f, 2.0f are neutral value allowing GetAngleAnttenuation in shader code to return 1.0
769+ lightData . angleScale = 1.0f ;
770+ lightData . angleOffset = 2.0f ;
771+ }
772+
773+ lightData . diffuseScale = additionalData . affectDiffuse ? 1.0f : 0.0f ;
774+ lightData . specularScale = additionalData . affectSpecular ? 1.0f : 0.0f ;
775+ lightData . shadowDimmer = additionalData . shadowDimmer ;
776+
777+ lightData . IESIndex = - 1 ;
778+ lightData . cookieIndex = - 1 ;
779+ lightData . shadowIndex = - 1 ;
780+
781+ bool hasCookie = light . light . cookie != null ;
782+ if ( hasCookie )
783+ {
784+ if ( light . lightType == LightType . Point )
785+ {
786+ lightData . cookieIndex = m_CubeCookieTexArray . FetchSlice ( light . light . cookie ) ;
764787 }
765- else
788+ else if ( light . lightType == LightType . Spot )
766789 {
767- // 1.0f, 2.0f are neutral value allowing GetAngleAnttenuation in shader code to return 1.0
768- punctualLightData . angleScale = 1.0f ;
769- punctualLightData . angleOffset = 2.0f ;
790+ lightData . cookieIndex = m_CookieTexArray . FetchSlice ( light . light . cookie ) ;
770791 }
792+ }
771793
772- punctualLightData . diffuseScale = additionalData . affectDiffuse ? 1.0f : 0.0f ;
773- punctualLightData . specularScale = additionalData . affectSpecular ? 1.0f : 0.0f ;
774- punctualLightData . shadowDimmer = additionalData . shadowDimmer ;
794+ // Setup shadow data arrays
795+ bool hasShadows = light . light . shadows != LightShadows . None && shadowOutput . GetShadowSliceCountLightIndex ( lightIndex ) != 0 ;
796+ bool hasNotReachMaxLimit = lightList . punctualShadows . Count + ( lightData . lightType == GPULightType . Point ? 6 : 1 ) <= k_MaxShadowOnScreen ;
775797
776- punctualLightData . IESIndex = - 1 ;
777- punctualLightData . cookieIndex = - 1 ;
778- punctualLightData . shadowIndex = - 1 ;
798+ if ( hasShadows && hasNotReachMaxLimit ) // Note < MaxShadows should be check at shadowOutput creation
799+ {
800+ // When we have a point light, we assumed that there is 6 consecutive PunctualShadowData
801+ lightData . shadowIndex = lightList . punctualShadows . Count ;
779802
780- bool hasCookie = light . light . cookie != null ;
781- if ( hasCookie )
803+ for ( int sliceIndex = 0 ; sliceIndex < shadowOutput . GetShadowSliceCountLightIndex ( lightIndex ) ; ++ sliceIndex )
782804 {
783- if ( light . lightType == LightType . Point )
784- {
785- punctualLightData . cookieIndex = m_CubeCookieTexArray . FetchSlice ( light . light . cookie ) ;
786- }
787- else if ( light . lightType == LightType . Spot )
788- {
789- punctualLightData . cookieIndex = m_CookieTexArray . FetchSlice ( light . light . cookie ) ;
790- }
791- }
805+ PunctualShadowData punctualShadowData = new PunctualShadowData ( ) ;
792806
793- // Setup shadow data arrays
794- bool hasShadows = light . light . shadows != LightShadows . None && shadowOutput . GetShadowSliceCountLightIndex ( lightIndex ) != 0 ;
795- bool hasNotReachMaxLimit = lightList . punctualShadows . Count + ( light . lightType == LightType . Point ? 6 : 1 ) <= k_MaxShadowOnScreen ;
807+ int shadowSliceIndex = shadowOutput . GetShadowSliceIndex ( lightIndex , sliceIndex ) ;
808+ punctualShadowData . worldToShadow = shadowOutput . shadowSlices [ shadowSliceIndex ] . shadowTransform . transpose ; // Transpose for hlsl reading ?
809+ punctualShadowData . lightType = lightData . lightType ;
796810
797- if ( hasShadows && hasNotReachMaxLimit ) // Note < MaxShadows should be check at shadowOutput creation
798- {
799- // When we have a point light, we assumed that there is 6 consecutive PunctualShadowData
800- punctualLightData . shadowIndex = lightList . punctualShadows . Count ;
801-
802- for ( int sliceIndex = 0 ; sliceIndex < shadowOutput . GetShadowSliceCountLightIndex ( lightIndex ) ; ++ sliceIndex )
803- {
804- PunctualShadowData punctualShadowData = new PunctualShadowData ( ) ;
805-
806- int shadowSliceIndex = shadowOutput . GetShadowSliceIndex ( lightIndex , sliceIndex ) ;
807- punctualShadowData . worldToShadow = shadowOutput . shadowSlices [ shadowSliceIndex ] . shadowTransform . transpose ; // Transpose for hlsl reading ?
808-
809- if ( light . lightType == LightType . Spot )
810- {
811- punctualShadowData . shadowType = ShadowType . Spot ;
812- }
813- else if ( light . lightType == LightType . Point )
814- {
815- punctualShadowData . shadowType = ShadowType . Point ;
816- }
817- else
818- {
819- punctualShadowData . shadowType = ShadowType . Directional ;
820- }
821-
822- punctualShadowData . bias = light . light . shadowBias ;
823-
824- lightList . punctualShadows . Add ( punctualShadowData ) ;
825- }
811+ punctualShadowData . bias = light . light . shadowBias ;
812+
813+ lightList . punctualShadows . Add ( punctualShadowData ) ;
826814 }
815+ }
816+
817+ lightData . size = new Vector2 ( additionalData . areaLightLength , additionalData . areaLightWidth ) ;
818+ lightData . twoSided = additionalData . isDoubleSided ;
827819
828- lightList . punctualLights . Add ( punctualLightData ) ;
820+ if ( additionalData . treatAsAreaLight )
821+ {
822+ lightList . areaLights . Add ( lightData ) ;
823+ }
824+ else
825+ {
826+ lightList . punctualLights . Add ( lightData ) ;
829827 }
830828 }
831829
0 commit comments