void SetLightIntensity(float intensity)
        {
            displayLightIntensity = intensity;

            if (lightUnit == LightUnit.Lumen)
            {
                if (lightTypeExtent == LightTypeExtent.Punctual)
                {
                    SetLightIntensityPunctual(intensity);
                }
                else
                {
                    m_Light.intensity = LightUtils.ConvertAreaLightLumenToLuminance(lightTypeExtent, intensity, shapeWidth, shapeHeight);
                }
            }
            else if (lightUnit == LightUnit.Ev100)
            {
                m_Light.intensity = LightUtils.ConvertEvToLuminance(intensity);
            }
            else if ((m_Light.type == LightType.Spot || m_Light.type == LightType.Point) && lightUnit == LightUnit.Lux)
            {
                // Box are local directional light with lux unity without at distance
                if ((m_Light.type == LightType.Spot) && (spotLightShape == SpotLightShape.Box))
                {
                    m_Light.intensity = intensity;
                }
                else
                {
                    m_Light.intensity = LightUtils.ConvertLuxToCandela(intensity, luxAtDistance);
                }
            }
            else
            {
                m_Light.intensity = intensity;
            }

#if UNITY_EDITOR
            m_Light.SetLightDirty(); // Should be apply only to parameter that's affect GI, but make the code cleaner
#endif
        }
        void SetLightIntensity(float intensity)
        {
            displayLightIntensity = intensity;

            if (lightUnit == LightUnit.Lumen)
            {
                if (lightTypeExtent == LightTypeExtent.Punctual)
                    SetLightIntensityPunctual(intensity);
                else
                    m_Light.intensity = LightUtils.ConvertAreaLightLumenToLuminance(lightTypeExtent, intensity, shapeWidth, shapeHeight);
            }
            else if (lightUnit == LightUnit.Ev100)
            {
                m_Light.intensity = LightUtils.ConvertEvToLuminance(intensity);
            }
            else
                m_Light.intensity = intensity;

#if UNITY_EDITOR
            m_Light.SetLightDirty(); // Should be apply only to parameter that's affect GI, but make the code cleaner
#endif
        }
Ejemplo n.º 3
0
        public static float ConvertPunctualLightCandelaToLumen(LightType lightType, SpotLightShape spotLigthShape, float candela, bool enableSpotReflector, float spotAngle, float aspectRatio)
        {
            if (lightType == LightType.Spot && enableSpotReflector)
            {
                // We just need to multiply candela by solid angle in this case
                if (spotLigthShape == SpotLightShape.Cone)
                {
                    return(LightUtils.ConvertSpotLightCandelaToLumen(candela, spotAngle * Mathf.Deg2Rad, true));
                }
                else if (spotLigthShape == SpotLightShape.Pyramid)
                {
                    float angleA, angleB;
                    LightUtils.CalculateAnglesForPyramid(aspectRatio, spotAngle * Mathf.Deg2Rad, out angleA, out angleB);

                    return(LightUtils.ConvertFrustrumLightCandelaToLumen(candela, angleA, angleB));
                }
                else // Box
                {
                    return(LightUtils.ConvertPointLightCandelaToLumen(candela));
                }
            }

            return(LightUtils.ConvertPointLightCandelaToLumen(candela));
        }
        // Return true if the light must be added to the baking
        public static bool LightDataGIExtract(Light l, ref LightDataGI ld)
        {
            var add = l.GetComponent <HDAdditionalLightData>();

            if (add == null)
            {
                add = HDUtils.s_DefaultHDAdditionalLightData;
            }

            // TODO: Currently color temperature is not handled at runtime, need to expose useColorTemperature publicly
            Color cct = new Color(1.0f, 1.0f, 1.0f);

#if UNITY_EDITOR
            if (add.useColorTemperature)
            {
                cct = LightUtils.CorrelatedColorTemperatureToRGB(l.colorTemperature);
            }
#endif

            // TODO: Only take into account the light dimmer when we have real time GI.
            ld.instanceID           = l.GetInstanceID();
            ld.color                = add.affectDiffuse ? LinearColor.Convert(l.color, l.intensity) : LinearColor.Black();
            ld.color.red           *= cct.r;
            ld.color.green         *= cct.g;
            ld.color.blue          *= cct.b;
            ld.indirectColor        = add.affectDiffuse ? LightmapperUtils.ExtractIndirect(l) : LinearColor.Black();
            ld.indirectColor.red   *= cct.r;
            ld.indirectColor.green *= cct.g;
            ld.indirectColor.blue  *= cct.b;

            // Note that the HDRI is correctly integrated in the GlobalIllumination system, we don't need to do anything regarding it.

            // The difference is that `l.lightmapBakeType` is the intent, e.g.you want a mixed light with shadowmask. But then the overlap test might detect more than 4 overlapping volumes and force a light to fallback to baked.
            // In that case `l.bakingOutput.lightmapBakeType` would be baked, instead of mixed, whereas `l.lightmapBakeType` would still be mixed. But this difference is only relevant in editor builds
#if UNITY_EDITOR
            ld.mode = LightmapperUtils.Extract(l.lightmapBakeType);
#else
            ld.mode = LightmapperUtils.Extract(l.bakingOutput.lightmapBakeType);
#endif

            ld.shadow = (byte)(l.shadows != LightShadows.None ? 1 : 0);

            if (add.lightTypeExtent == LightTypeExtent.Punctual)
            {
                // For HDRP we need to divide the analytic light color by PI (HDRP do explicit PI division for Lambert, but built in Unity and the GI don't for punctual lights)
                // We apply it on both direct and indirect are they are separated, seems that direct is no used if we used mixed mode with indirect or shadowmask bake.
                ld.color.intensity         /= Mathf.PI;
                ld.indirectColor.intensity /= Mathf.PI;

                switch (l.type)
                {
                case LightType.Directional:
                    ld.orientation.SetLookRotation(l.transform.forward, Vector3.up);
                    ld.position       = Vector3.zero;
                    ld.range          = 0.0f;
                    ld.coneAngle      = 0.0f;
                    ld.innerConeAngle = 0.0f;
#if UNITY_EDITOR
                    ld.shape0 = l.shadows != LightShadows.None ? (Mathf.Deg2Rad * l.shadowAngle) : 0.0f;
#else
                    ld.shape0 = 0.0f;
#endif
                    ld.shape1  = 0.0f;
                    ld.type    = UnityEngine.Experimental.GlobalIllumination.LightType.Directional;
                    ld.falloff = FalloffType.Undefined;
                    break;

                case LightType.Spot:

                    ld.orientation    = l.transform.rotation;
                    ld.position       = l.transform.position;
                    ld.range          = l.range;
                    ld.coneAngle      = l.spotAngle * Mathf.Deg2Rad; // coneAngle is the full angle
                    ld.innerConeAngle = l.spotAngle * Mathf.Deg2Rad * add.GetInnerSpotPercent01();
#if UNITY_EDITOR
                    ld.shape0 = l.shadows != LightShadows.None ? l.shadowRadius : 0.0f;
#else
                    ld.shape0 = 0.0f;
#endif
                    ld.shape1  = 0.0f;
                    ld.type    = UnityEngine.Experimental.GlobalIllumination.LightType.Spot;
                    ld.falloff = add.applyRangeAttenuation ? FalloffType.InverseSquared : FalloffType.InverseSquaredNoRangeAttenuation;

                    /*
                     * switch (add.spotLightShape)
                     * {
                     *  case SpotLightShape.Cone:
                     *      break;
                     *  case SpotLightShape.Pyramid:
                     *      break;
                     *  case SpotLightShape.Box:
                     *      break;
                     *  default:
                     *      Debug.Assert(false, "Encountered an unknown SpotLightShape.");
                     *      break;
                     * }
                     */
                    break;

                case LightType.Point:
                    ld.orientation    = Quaternion.identity;
                    ld.position       = l.transform.position;
                    ld.range          = l.range;
                    ld.coneAngle      = 0.0f;
                    ld.innerConeAngle = 0.0f;

#if UNITY_EDITOR
                    ld.shape0 = l.shadows != LightShadows.None ? l.shadowRadius : 0.0f;
#else
                    ld.shape0 = 0.0f;
#endif
                    ld.shape1  = 0.0f;
                    ld.type    = UnityEngine.Experimental.GlobalIllumination.LightType.Point;
                    ld.falloff = add.applyRangeAttenuation ? FalloffType.InverseSquared : FalloffType.InverseSquaredNoRangeAttenuation;
                    break;

                // Note: We don't support this type in HDRP, but ini just in case
                case LightType.Area:
                    ld.orientation    = l.transform.rotation;
                    ld.position       = l.transform.position;
                    ld.range          = l.range;
                    ld.coneAngle      = 0.0f;
                    ld.innerConeAngle = 0.0f;
#if UNITY_EDITOR
                    ld.shape0 = l.areaSize.x;
                    ld.shape1 = l.areaSize.y;
#else
                    ld.shape0 = 0.0f;
                    ld.shape1 = 0.0f;
#endif
                    ld.type    = UnityEngine.Experimental.GlobalIllumination.LightType.Rectangle;
                    ld.falloff = FalloffType.Undefined;
                    break;

                default:
                    Debug.Assert(false, "Encountered an unknown LightType.");
                    break;
                }
            }
            else if (add.lightTypeExtent == LightTypeExtent.Rectangle)
            {
                ld.orientation    = l.transform.rotation;
                ld.position       = l.transform.position;
                ld.range          = l.range;
                ld.coneAngle      = 0.0f;
                ld.innerConeAngle = 0.0f;
#if UNITY_EDITOR
                ld.shape0 = l.areaSize.x;
                ld.shape1 = l.areaSize.y;
#else
                ld.shape0 = 0.0f;
                ld.shape1 = 0.0f;
#endif
                // TEMP: for now, if we bake a rectangle type this will disable the light for runtime, need to speak with GI team about it!
                ld.type    = UnityEngine.Experimental.GlobalIllumination.LightType.Rectangle;
                ld.falloff = add.applyRangeAttenuation ? FalloffType.InverseSquared : FalloffType.InverseSquaredNoRangeAttenuation;
            }
            else if (add.lightTypeExtent == LightTypeExtent.Line)
            {
                ld.InitNoBake(ld.instanceID);
            }
            else
            {
                Debug.Assert(false, "Encountered an unknown LightType.");
            }

            return(true);
        }
        public void UpdateAreaLightEmissiveMesh()
        {
            MeshRenderer emissiveMeshRenderer = GetComponent <MeshRenderer>();
            MeshFilter   emissiveMeshFilter   = GetComponent <MeshFilter>();

            bool displayEmissiveMesh = IsAreaLight(lightTypeExtent) && lightTypeExtent != LightTypeExtent.Tube && displayAreaLightEmissiveMesh;

            // Ensure that the emissive mesh components are here
            if (displayEmissiveMesh)
            {
                if (emissiveMeshRenderer == null)
                {
                    emissiveMeshRenderer = gameObject.AddComponent <MeshRenderer>();
                }
                if (emissiveMeshFilter == null)
                {
                    emissiveMeshFilter = gameObject.AddComponent <MeshFilter>();
                }
            }
            else // Or remove them if the option is disabled
            {
                if (emissiveMeshRenderer != null)
                {
                    DestroyImmediate(emissiveMeshRenderer);
                }
                if (emissiveMeshFilter != null)
                {
                    DestroyImmediate(emissiveMeshFilter);
                }

                // We don't have anything to do left if the dislay emissive mesh option is disabled
                return;
            }

            Vector3 lightSize;

            // Update light area size from GameObject transform scale if the transform have changed
            // else we update the light size from the shape fields
            if (timelineWorkaround.oldLocalScale != transform.localScale)
            {
                lightSize = transform.localScale;
            }
            else
            {
                lightSize = new Vector3(shapeWidth, shapeHeight, transform.localScale.z);
            }

            lightSize = Vector3.Max(Vector3.one * k_MinAreaWidth, lightSize);
            m_Light.transform.localScale = lightSize;
            m_Light.areaSize             = lightSize;

            switch (lightTypeExtent)
            {
            case LightTypeExtent.Rectangle:
                shapeWidth  = lightSize.x;
                shapeHeight = lightSize.y;
                break;

            default:
                break;
            }

            if (emissiveMeshRenderer.sharedMaterial == null)
            {
                emissiveMeshRenderer.material = new Material(Shader.Find("HDRenderPipeline/Unlit"));
            }

            // Update Mesh emissive properties
            emissiveMeshRenderer.sharedMaterial.SetColor("_UnlitColor", Color.black);

            // m_Light.intensity is in luminance which is the value we need for emissive color
            Color value = m_Light.color.linear * m_Light.intensity;

            if (useColorTemperature)
            {
                value *= LightUtils.CorrelatedColorTemperatureToRGB(m_Light.colorTemperature);
            }
            value.r = Mathf.Clamp01(value.r);
            value.g = Mathf.Clamp01(value.g);
            value.b = Mathf.Clamp01(value.b);
            value.a = Mathf.Clamp01(value.a);

            value *= lightDimmer;

            emissiveMeshRenderer.sharedMaterial.SetColor("_EmissiveColor", value);
        }