private static Texture2D CreateKelvinGradientTexture(string name, int width, int height, float minKelvin, float maxKelvin) { Texture2D texture2D = new Texture2D(width, height, TextureFormat.ARGB32, false); texture2D.name = name; texture2D.hideFlags = HideFlags.HideAndDontSave; Color32[] array = new Color32[width * height]; float num = Mathf.Pow(maxKelvin, 0.5f); float num2 = Mathf.Pow(minKelvin, 0.5f); for (int i = 0; i < width; i++) { float num3 = (float)i / (float)(width - 1); float f = (num - num2) * num3 + num2; float kelvin = Mathf.Pow(f, 2f); Color color = Mathf.CorrelatedColorTemperatureToRGB(kelvin); for (int j = 0; j < height; j++) { array[j * width + i] = color.gamma; } } texture2D.SetPixels32(array); texture2D.wrapMode = TextureWrapMode.Clamp; texture2D.Apply(); return(texture2D); }
private void GenerateStars() { IEnumerable <Star> starsEnum = Cluster.Generate(new System.Random(Seed)); int starSeed = Seed; foreach (Star star in starsEnum) { GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube); Destroy(obj.GetComponent <BoxCollider>()); obj.name = "Star: " + star.Name; obj.transform.parent = transform; obj.transform.localPosition = new Vector3(star.Position.X * Galaxy.Distance * 10000, star.Position.Y * Galaxy.Distance * 10000, star.Position.Z * Galaxy.Distance * 10000); float sizeObj = star.Size * Galaxy.Scale; obj.transform.localScale = new Vector3(sizeObj, sizeObj, sizeObj); Color color = Mathf.CorrelatedColorTemperatureToRGB(star.Temperature); obj.GetComponent <MeshRenderer>().material = Galaxy.starMaterial; obj.GetComponent <MeshRenderer>().material.SetColor("_TintColor", color); obj.GetComponent <MeshRenderer>().material.SetFloat("_Scale", obj.transform.localScale.x); obj.AddComponent <StarBehaviour>().Scale = sizeObj * 10; obj.GetComponent <StarBehaviour>().Temperature = star.Temperature; obj.GetComponent <StarBehaviour>().Name = star.Name; obj.GetComponent <StarBehaviour>().Mass = star.Mass; obj.GetComponent <StarBehaviour>().Seed = starSeed; obj.GetComponent <StarBehaviour>().Sector = this; obj.AddComponent <StarSystem>(); stars.Add(obj); starSeed++; } }
void FrameChanged(ARCameraFrameEventArgs args) { float brightness = initialAmbientBrightness; Color colorTempRGB = Color.white; // WARNING: colorCorrection only exists on Android. if (matchColorTemperature && args.lightEstimation.colorCorrection.HasValue) { Debug.LogWarning("Color correction for ARCore has not been implemented, yet."); } if (matchBrightness && args.lightEstimation.averageBrightness.HasValue) { float deltaBrightness = (args.lightEstimation.averageBrightness.Value - 0.5f) * brightnessMatchingStrength; brightness = Mathf.Clamp(initialAmbientBrightness + deltaBrightness, 0, 1); } // WARNING: averageColorTemperature only exists on iOS. if (matchColorTemperature && args.lightEstimation.averageColorTemperature.HasValue) { float colorTemperature = args.lightEstimation.averageColorTemperature.Value; colorTempRGB = Mathf.CorrelatedColorTemperatureToRGB(colorTemperature); } Color colorOffset = Color.white * (1f - colorCorrectionStrength); ambientColor = (colorTempRGB * colorCorrectionStrength + colorOffset) * brightness; }
static Texture2D CreateKelvinGradientTexture(string name, int width, int height, float minKelvin, float maxKelvin) { var texture = new Texture2D(width, height, TextureFormat.ARGB32, false); texture.name = name; texture.hideFlags = HideFlags.HideAndDontSave; var pixels = new Color32[width * height]; float mappedMax = Mathf.Pow(maxKelvin, 1f / kSliderPower); float mappedMin = Mathf.Pow(minKelvin, 1f / kSliderPower); for (int i = 0; i < width; i++) { float pixelfrac = i / (float)(width - 1); float mappedValue = (mappedMax - mappedMin) * pixelfrac + mappedMin; float kelvin = Mathf.Pow(mappedValue, kSliderPower); Color kelvinColor = Mathf.CorrelatedColorTemperatureToRGB(kelvin); for (int j = 0; j < height; j++) { pixels[j * width + i] = kelvinColor.gamma; } } texture.SetPixels32(pixels); texture.wrapMode = TextureWrapMode.Clamp; texture.Apply(); return(texture); }
private LoopListViewItem2 OnGetItem1(LoopListView2 loopList, int index) { if (index < 0 || index >= dataNum) { return(null); } var data = new Item1Data() { HeadColor = Mathf.CorrelatedColorTemperatureToRGB(40000 * index / 20f), Desc = $"#R这是第{index}个Item的描述,表情啊#{index},哈哈哈哈哈#{index}#{index}#{index}#{index}" }; var item = loopList.NewListViewItem("Item1"); if (!item.IsInitHandlerCalled) { var script = item.GetComponent <Item1Script>(); item.UserObjectData = script; script.Init(); } var item1Script = (Item1Script)item.UserObjectData; item1Script.SetData(data); return(item); }
private void Start() { _prevVelocity = Vector3.zero; _prevAngularVelocity = Vector3.zero; _weight = 0; refs.indicatorImage.color = Mathf.CorrelatedColorTemperatureToRGB(Mathf.Lerp(40000, 1000, _weight)); }
private void Update() { _UpdateDisplay(); if (_tracker == null || _tracker.transform == null) { return; } var t = sh_akira.OVRTracking.OpenVRWrapper.Instance.GetTransform(_tracker.deviceIndex); if (t == null) { return; } var weight = Smooth(minVelocityChangeRate, maxVelocityChangeRate, (_prevVelocity - t.velocity).magnitude + (_prevAngularVelocity - t.angularVelocity).magnitude * 0.2f); _weight = Mathf.Lerp(_weight, weight, Time.deltaTime * indicatorSpeed); refs.indicatorImage.color = Mathf.CorrelatedColorTemperatureToRGB(Mathf.Lerp(40000, 1000, _weight)); _prevVelocity = t.velocity; _prevAngularVelocity = t.angularVelocity; _UpdateBattery(); }
private void Update() { //Checks if the TimeMax is set. if (TimeMax != 0f) { TimePassed += Time.deltaTime; //make sure that the TimeLeftRatio doesn't drop under 0. Because we don't divide by zero. if ((1 - (TimePassed / TimeMax)) > 0f) { TimeLeftRatio = 1 - (TimePassed / TimeMax); } //make sure that the TimeLeftRatio ends at 0. else { TimeLeftRatio = 0f; } blackbodyValue = ((blackbodyMaxValue - blackbodyMinValue) * TimeLeftRatio) + blackbodyMinValue; //this shouldn't go under 500. psr_Explosion.material.SetColor("_EmissionColor", Mathf.CorrelatedColorTemperatureToRGB(blackbodyValue) * EmissiveStrength); //Just sets the emissive color based on the temperature of the explosion. psr_Sparks.material.SetColor("_EmissionColor", Mathf.CorrelatedColorTemperatureToRGB(blackbodyValue) * EmissiveStrength); } else { print("You need to set the Time Max variable in " + gameObject.transform.name); //just easy debug if someone messes up. } }
void SendLightData() { if (m_light.type == LightType.Directional) { var colTemp = Mathf.CorrelatedColorTemperatureToRGB(m_light.colorTemperature); Shader.SetGlobalColor("_LightColor", colTemp * m_light.color); Shader.SetGlobalFloat("_LightIntensity", m_light.intensity); } }
static int CorrelatedColorTemperatureToRGB(IntPtr L) { LuaScriptMgr.CheckArgsCount(L, 1); float arg0 = (float)LuaScriptMgr.GetNumber(L, 1); Color o = Mathf.CorrelatedColorTemperatureToRGB(arg0); LuaScriptMgr.Push(L, o); return(1); }
private static Color ExtractColorTemperature(Light l) { Color cct = new Color(1.0f, 1.0f, 1.0f); if (l.useColorTemperature && GraphicsSettings.lightsUseLinearIntensity) { cct = Mathf.CorrelatedColorTemperatureToRGB(l.colorTemperature); } return(cct); }
internal static Color EvaluateLightColor(Light light, HDAdditionalLightData hdLight) { Color finalColor = light.color.linear * light.intensity; if (hdLight.useColorTemperature) { finalColor *= Mathf.CorrelatedColorTemperatureToRGB(light.colorTemperature); } return(finalColor); }
private static Color ExtractColorTemperature(Light l) { Color result = new Color(1f, 1f, 1f); bool flag = l.useColorTemperature && GraphicsSettings.lightsUseLinearIntensity; if (flag) { result = Mathf.CorrelatedColorTemperatureToRGB(l.colorTemperature); } return(result); }
private void CreateStarModel() { //3dModel model = new GameObject("StarModel: " + name); model.transform.parent = transform; model.transform.position = transform.position; model.transform.localScale = transform.localScale / Scale; model.AddComponent <MeshFilter>().mesh = (Mesh)Resources.Load("Primitives/CubeSphere", typeof(Mesh)); model.AddComponent <MeshRenderer>(); model.GetComponent <Renderer>().material = (Material)Resources.Load("Stars/StarModelMaterial", typeof(Material)); Color color = Mathf.CorrelatedColorTemperatureToRGB(Temperature); model.GetComponent <Renderer>().material.SetColor("Color_976DB11", color); }
// Use this for initialization void Start() { m_numberOfPlanets = (uint)Random.Range(m_numberOfPlanetMin, m_numberOfPlanetMax); m_sunSize = Random.Range(m_sunSizeMin, m_sunSizeMax); m_sunTemperature = Random.Range(m_sunTemperatureMin, m_sunTemperatureMax); m_sunColor = Mathf.CorrelatedColorTemperatureToRGB(m_sunTemperature); m_animator = GetComponentInChildren <Animator>(); m_sunRenderer.color = m_sunColor; m_auraRenderer.color = FactionHelper.GetFactionColor(GetMainFaction()); }
public float TimeMax; //Couldn't find an variable in the Particle System to get the duration of the particle emitter. Only duration I found was the one spawning the particles not their life time. void Start() { //Albedo color might not really be important or even visible as the emissive most likely absorbs the albedo color. But, in case we want to remove the emissive texture I added this in. //Maybe have a null or false check on emissive to see if this should be set? var main = ps_Explosion.main; var colorLifeTime = ps_Explosion.colorOverLifetime; main.startColor = Mathf.CorrelatedColorTemperatureToRGB(blackbodyValue); colorLifeTime.enabled = true; //This is to set the albedo color over lifetime. Should start at a bright white then turn quickly yellow and end with a dark red. Todo?? make the different temperature values variables? grad.SetKeys(new GradientColorKey[] { new GradientColorKey(Mathf.CorrelatedColorTemperatureToRGB(blackbodyMaxValue), 0.0f), new GradientColorKey(Mathf.CorrelatedColorTemperatureToRGB(blackbodyMaxValue / 2), 0.5f), new GradientColorKey(Mathf.CorrelatedColorTemperatureToRGB(blackbodyMinValue), 1f) }, new GradientAlphaKey[] { new GradientAlphaKey(1.0f, 0.0f), new GradientAlphaKey(0.0f, 1.0f) }); colorLifeTime.color = grad; }
ParticleSystem.Particle get_particle_from_star(star st) { float lum = Mathf.Exp(-st.absmag / 5 * Mathf.Log(100)); lum = Mathf.Pow(lum, 1f / 4); /* Ballesteros' formula (from Wikipedia) */ double T = 4600 * (1 / (0.92 * st.ci + 1.7) + 1 / (0.92 * st.ci + 0.62)); Color temp = Mathf.CorrelatedColorTemperatureToRGB((float)T); return(new ParticleSystem.Particle { position = star_to_position_in_particle_reference_frame(st), startLifetime = Mathf.Infinity, startSize = Mathf.Max(st.part_of_group? 0.001f: 0.003f, 0.02f * lum), //startSize = Mathf.Max(0.002f, 0.004f * Mathf.Sqrt(star.radius)), startColor = temp }); }
void Start() { DefinitionLoader.LoadDefinitions(); Current.Game = new Game(); //Current.Game.TickManager = new TickManager(); Rand.PushSeed(Seed); InitGalaxyGenParams(); Rand.PopSeed(); // GalaxyGenerator GalaxyGenerator.GalaxyGenStepsDirty.Add(new GalaxyGenStep_Stars()); GalaxyGenerator.GalaxyGenStepsDirty.Add(new GalaxyGenStep_Planets()); Current.Game.Galaxy = GalaxyGenerator.GenerateGalaxy(Seed); List <Star> temp = Current.Game.Galaxy.Stars.RetrieveObjectsInArea(new Rect(-320000f, -320000f, 640000f, 640000f)); for (int i = 0; i < temp.Count; i++) { solarSystems.Add(Instantiate(StarPrefab, temp[i].Position, StarPrefab.transform.rotation)); Color tempColor = Mathf.CorrelatedColorTemperatureToRGB((float)temp[i].Temp); float tempMag = (float)temp[i].Mag; solarSystems[i].GetComponent <SpriteRenderer>().color = new Color(tempColor.r * tempMag, tempColor.g * tempMag, tempColor.b * tempMag, tempColor.a); for (int j = 0; j < temp[i].childOrbitals.Count; j++) { Planet planet = (Planet)temp[i].childOrbitals[j]; GameObject obj = Instantiate(StarPrefab, planet.Position, StarPrefab.transform.rotation); planets.Add(obj); obj.transform.SetParent(solarSystems[i].transform); obj.GetComponent <SpriteRenderer>().color = Color.blue; Vector3 scale = obj.transform.localScale; obj.transform.localScale = new Vector3(scale.x * 0.1f, scale.y * 0.1f, scale.z * 0.1f); } } for (int i = 0; i < Current.Galaxy.AllPlanets.Count; i++) { GameObject obj = Instantiate(OrbitPrefab, Current.Galaxy.AllPlanets[i].ParentOrbital.Position, OrbitPrefab.transform.rotation); OrbitCircleDrawer orbit = obj.GetComponent <OrbitCircleDrawer>(); orbitalDrawers.Add(obj); orbit.Radius = Vector3.Distance(Current.Galaxy.AllPlanets[i].Position, Current.Galaxy.AllPlanets[i].ParentOrbital.Position); orbit.Draw(); } }
void FrameChanged(ARCameraFrameEventArgs args) { // WARNING: colorCorrection only exists on Android. if (matchColorTemperature && args.lightEstimation.colorCorrection.HasValue) { Debug.LogWarning("Color correction for ARCore has not been implemented, yet."); } if (matchBrightness && args.lightEstimation.averageBrightness.HasValue) { float deltaBrightness = (args.lightEstimation.averageBrightness.Value - 0.5f) * 2f * brightnessMatchingStrength; intensity = Mathf.Clamp(initialIntensity + deltaBrightness, 0, 1); } // WARNING: averageColorTemperature only exists on iOS. if (matchColorTemperature && args.lightEstimation.averageColorTemperature.HasValue) { float colorTemperature = args.lightEstimation.averageColorTemperature.Value; Color colorTempRGB = Mathf.CorrelatedColorTemperatureToRGB(colorTemperature); ambientColor = Color.Lerp(initialColor, colorTempRGB, colorCorrectionStrength); } }
void BuildLightData(CommandBuffer cmd, HDCamera hdCamera, HDRayTracingLights rayTracingLights, DebugDisplaySettings debugDisplaySettings) { // If no lights, exit if (rayTracingLights.lightCount == 0) { ResizeLightDataBuffer(1); return; } // Also we need to build the light list data if (m_LightDataGPUArray == null || m_LightDataGPUArray.count != rayTracingLights.lightCount) { ResizeLightDataBuffer(rayTracingLights.lightCount); } m_LightDataCPUArray.Clear(); // Grab the shadow settings var hdShadowSettings = hdCamera.volumeStack.GetComponent <HDShadowSettings>(); BoolScalableSetting contactShadowScalableSetting = HDAdditionalLightData.ScalableSettings.UseContactShadow(m_RenderPipeline.asset); // Build the data for every light for (int lightIdx = 0; lightIdx < rayTracingLights.hdLightArray.Count; ++lightIdx) { // Grab the additinal light data to process HDAdditionalLightData additionalLightData = rayTracingLights.hdLightArray[lightIdx]; LightData lightData = new LightData(); // When the user deletes a light source in the editor, there is a single frame where the light is null before the collection of light in the scene is triggered // the workaround for this is simply to add an invalid light for that frame if (additionalLightData == null) { m_LightDataCPUArray.Add(lightData); continue; } // Evaluate all the light type data that we need LightCategory lightCategory = LightCategory.Count; GPULightType gpuLightType = GPULightType.Point; LightVolumeType lightVolumeType = LightVolumeType.Count; HDLightType lightType = additionalLightData.type; HDRenderPipeline.EvaluateGPULightType(lightType, additionalLightData.spotLightShape, additionalLightData.areaLightShape, ref lightCategory, ref gpuLightType, ref lightVolumeType); // Fetch the light component for this light additionalLightData.gameObject.TryGetComponent(out lightComponent); // Build the processed light data that we need ProcessedLightData processedData = new ProcessedLightData(); processedData.additionalLightData = additionalLightData; processedData.lightType = additionalLightData.type; processedData.lightCategory = lightCategory; processedData.gpuLightType = gpuLightType; processedData.lightVolumeType = lightVolumeType; // Both of these positions are non-camera-relative. processedData.distanceToCamera = (additionalLightData.gameObject.transform.position - hdCamera.camera.transform.position).magnitude; processedData.lightDistanceFade = HDUtils.ComputeLinearDistanceFade(processedData.distanceToCamera, additionalLightData.fadeDistance); processedData.volumetricDistanceFade = HDUtils.ComputeLinearDistanceFade(processedData.distanceToCamera, additionalLightData.volumetricFadeDistance); processedData.isBakedShadowMask = HDRenderPipeline.IsBakedShadowMaskLight(lightComponent); // Build a visible light Color finalColor = lightComponent.color.linear * lightComponent.intensity; if (additionalLightData.useColorTemperature) { finalColor *= Mathf.CorrelatedColorTemperatureToRGB(lightComponent.colorTemperature); } visibleLight.finalColor = finalColor; visibleLight.range = lightComponent.range; // This should be done explicitely, localtoworld matrix doesn't work here localToWorldMatrix.SetColumn(3, lightComponent.gameObject.transform.position); localToWorldMatrix.SetColumn(2, lightComponent.transform.forward); localToWorldMatrix.SetColumn(1, lightComponent.transform.up); localToWorldMatrix.SetColumn(0, lightComponent.transform.right); visibleLight.localToWorldMatrix = localToWorldMatrix; visibleLight.spotAngle = lightComponent.spotAngle; int shadowIndex = additionalLightData.shadowIndex; int screenSpaceShadowIndex = -1; int screenSpaceChannelSlot = -1; Vector3 lightDimensions = new Vector3(0.0f, 0.0f, 0.0f); // Use the shared code to build the light data m_RenderPipeline.GetLightData(cmd, hdCamera, hdShadowSettings, visibleLight, lightComponent, in processedData, shadowIndex, contactShadowScalableSetting, isRasterization: false, ref lightDimensions, ref screenSpaceShadowIndex, ref screenSpaceChannelSlot, ref lightData); // We make the light position camera-relative as late as possible in order // to allow the preceding code to work with the absolute world space coordinates. Vector3 camPosWS = hdCamera.mainViewConstants.worldSpaceCameraPos; HDRenderPipeline.UpdateLightCameraRelativetData(ref lightData, camPosWS); // Set the data for this light m_LightDataCPUArray.Add(lightData); } // Push the data to the GPU m_LightDataGPUArray.SetData(m_LightDataCPUArray); }
public void BuildHueColors() { if (colors == null || colors.Length != 256) { colors = new Color[256]; } if (scheme == ColorScheme.Custom) { colorsCount = 0; } else { colorsCount = Mathf.Max(hueCount, scheme.minHues()); } switch (scheme) { case ColorScheme.Custom: break; case ColorScheme.Monochromatic: for (int k = 0; k < colorsCount; k++) { colors[k] = primaryColor; } break; case ColorScheme.Complementary: { for (int k = 0; k < colorsCount; k++) { colors[k] = Color.Lerp(primaryColor, complementary1Color, (float)k / (colorsCount - 1)); } } break; case ColorScheme.Gradient: { for (int k = 0; k < colorsCount; k++) { colors[k] = Color.Lerp(primaryColor, complementary1Color, (float)k / (colorsCount - 1)); } } break; case ColorScheme.SplitComplementary: { const float third = 1f / 3f; const float twoThirds = 2f / 3f; for (int k = 0; k < colorsCount; k++) { float t = (float)k / colorsCount; if (t < third) { colors[k] = Color.Lerp(primaryColor, complementary1Color, t / third); } else if (t < twoThirds) { colors[k] = Color.Lerp(complementary1Color, complementary2Color, (t - third) / third); } else { colors[k] = Color.Lerp(complementary2Color, primaryColor, (t - twoThirds) / third); } } } break; case ColorScheme.Analogous: { for (int k = 0; k < colorsCount; k++) { float t = (float)k / (colorsCount - 1); if (t < 0.5f) { colors[k] = Color.Lerp(complementary1Color, primaryColor, t / 0.5f); } else { colors[k] = Color.Lerp(primaryColor, complementary2Color, (t - 0.5f) / 0.5f); } } } break; case ColorScheme.Triadic: { const float third = 1f / 3f; const float twoThirds = 2f / 3f; for (int k = 0; k < colorsCount; k++) { float t = (float)k / colorsCount; if (t < third) { colors[k] = Color.Lerp(primaryColor, complementary1Color, t / third); } else if (t < twoThirds) { colors[k] = Color.Lerp(complementary1Color, complementary2Color, (t - third) / third); } else { colors[k] = Color.Lerp(complementary2Color, primaryColor, (t - twoThirds) / third); } } } break; case ColorScheme.Tetradic: { for (int k = 0; k < colorsCount; k++) { float t = (float)k / colorsCount; if (t < 0.25f) { colors[k] = Color.Lerp(primaryColor, complementary1Color, t / 0.25f); } else if (t < 0.5f) { colors[k] = Color.Lerp(complementary1Color, complementary2Color, (t - 0.25f) / 0.25f); } else if (t < 0.75f) { colors[k] = Color.Lerp(complementary2Color, complementary3Color, (t - 0.5f) / 0.25f); } else { colors[k] = Color.Lerp(complementary3Color, primaryColor, (t - 0.75f) / 0.25f); } } } break; case ColorScheme.Square: { for (int k = 0; k < colorsCount; k++) { float t = (float)k / colorsCount; if (t < 0.25f) { colors[k] = Color.Lerp(primaryColor, complementary1Color, t / 0.25f); } else if (t < 0.5f) { colors[k] = Color.Lerp(complementary1Color, complementary2Color, (t - 0.25f) / 0.25f); } else if (t < 0.75f) { colors[k] = Color.Lerp(complementary2Color, complementary3Color, (t - 0.5f) / 0.25f); } else { colors[k] = Color.Lerp(complementary3Color, primaryColor, (t - 0.75f) / 0.25f); } } } break; case ColorScheme.AccentedAnalogous: { for (int k = 0; k < colorsCount; k++) { float t = (float)k / colorsCount; if (t < 0.25f) { colors[k] = Color.Lerp(primaryColor, complementary1Color, t / 0.25f); } else if (t < 0.5f) { colors[k] = Color.Lerp(complementary1Color, complementary2Color, (t - 0.25f) / 0.25f); } else if (t < 0.75f) { colors[k] = Color.Lerp(complementary2Color, complementary3Color, (t - 0.5f) / 0.25f); } else { colors[k] = Color.Lerp(complementary3Color, primaryColor, (t - 0.75f) / 0.25f); } } } break; case ColorScheme.Spectrum: for (int k = 0; k < colorsCount; k++) { colors[k] = ColorConversion.GetColor((float)k / colorsCount); } break; } // Add custom colors for (int k = START_INDEX_CUSTOM_COLOR; k < keyColors.Length; k++) { if (colorsCount < colors.Length && keyColors[k].visible) { colors[colorsCount++] = keyColors[k].color; } } // Apply color temp correction if (colorTempStrength > 0) { Color ct = Mathf.CorrelatedColorTemperatureToRGB(kelvin); float ac = 1f - colorTempStrength; for (int k = 0; k < colorsCount; k++) { colors[k].r = colors[k].r * (ct.r * colorTempStrength + ac); colors[k].g = colors[k].g * (ct.g * colorTempStrength + ac); colors[k].b = colors[k].b * (ct.b * colorTempStrength + ac); } } UpdateMaterial(); }
void BuildLightData(CommandBuffer cmd, HDCamera hdCamera, List <HDAdditionalLightData> lightArray) { // Also we need to build the light list data if (m_LightDataGPUArray == null || m_LightDataGPUArray.count != lightArray.Count) { ResizeLightDataBuffer(lightArray.Count); } // Build the data for every light for (int lightIdx = 0; lightIdx < lightArray.Count; ++lightIdx) { var lightData = new LightData(); HDAdditionalLightData additionalLightData = lightArray[lightIdx]; // When the user deletes a light source in the editor, there is a single frame where the light is null before the collection of light in the scene is triggered // the workaround for this is simply to add an invalid light for that frame if (additionalLightData == null) { m_LightDataCPUArray[lightIdx] = lightData; continue; } Light light = additionalLightData.gameObject.GetComponent <Light>(); // Both of these positions are non-camera-relative. float distanceToCamera = (light.gameObject.transform.position - hdCamera.camera.transform.position).magnitude; float lightDistanceFade = HDUtils.ComputeLinearDistanceFade(distanceToCamera, additionalLightData.fadeDistance); bool contributesToLighting = ((additionalLightData.lightDimmer > 0) && (additionalLightData.affectDiffuse || additionalLightData.affectSpecular)) || (additionalLightData.volumetricDimmer > 0); contributesToLighting = contributesToLighting && (lightDistanceFade > 0); if (!contributesToLighting) { continue; } lightData.lightLayers = additionalLightData.GetLightLayers(); LightCategory lightCategory = LightCategory.Count; GPULightType gpuLightType = GPULightType.Point; GetLightGPUType(additionalLightData, light, ref gpuLightType, ref lightCategory); lightData.lightType = gpuLightType; lightData.positionRWS = light.gameObject.transform.position - hdCamera.camera.transform.position; bool applyRangeAttenuation = additionalLightData.applyRangeAttenuation && (gpuLightType != GPULightType.ProjectorBox); lightData.range = light.range; if (applyRangeAttenuation) { lightData.rangeAttenuationScale = 1.0f / (light.range * light.range); lightData.rangeAttenuationBias = 1.0f; if (lightData.lightType == GPULightType.Rectangle) { // Rect lights are currently a special case because they use the normalized // [0, 1] attenuation range rather than the regular [0, r] one. lightData.rangeAttenuationScale = 1.0f; } } else // Don't apply any attenuation but do a 'step' at range { // Solve f(x) = b - (a * x)^2 where x = (d/r)^2. // f(0) = huge -> b = huge. // f(1) = 0 -> huge - a^2 = 0 -> a = sqrt(huge). const float hugeValue = 16777216.0f; const float sqrtHuge = 4096.0f; lightData.rangeAttenuationScale = sqrtHuge / (light.range * light.range); lightData.rangeAttenuationBias = hugeValue; if (lightData.lightType == GPULightType.Rectangle) { // Rect lights are currently a special case because they use the normalized // [0, 1] attenuation range rather than the regular [0, r] one. lightData.rangeAttenuationScale = sqrtHuge; } } Color value = light.color.linear * light.intensity; if (additionalLightData.useColorTemperature) { value *= Mathf.CorrelatedColorTemperatureToRGB(light.colorTemperature); } lightData.color = new Vector3(value.r, value.g, value.b); lightData.forward = light.transform.forward; lightData.up = light.transform.up; lightData.right = light.transform.right; if (lightData.lightType == GPULightType.ProjectorBox) { // Rescale for cookies and windowing. lightData.right *= 2.0f / Mathf.Max(additionalLightData.shapeWidth, 0.001f); lightData.up *= 2.0f / Mathf.Max(additionalLightData.shapeHeight, 0.001f); } else if (lightData.lightType == GPULightType.ProjectorPyramid) { // Get width and height for the current frustum var spotAngle = light.spotAngle; float frustumWidth, frustumHeight; if (additionalLightData.aspectRatio >= 1.0f) { frustumHeight = 2.0f * Mathf.Tan(spotAngle * 0.5f * Mathf.Deg2Rad); frustumWidth = frustumHeight * additionalLightData.aspectRatio; } else { frustumWidth = 2.0f * Mathf.Tan(spotAngle * 0.5f * Mathf.Deg2Rad); frustumHeight = frustumWidth / additionalLightData.aspectRatio; } // Rescale for cookies and windowing. lightData.right *= 2.0f / frustumWidth; lightData.up *= 2.0f / frustumHeight; } if (lightData.lightType == GPULightType.Spot) { var spotAngle = light.spotAngle; var innerConePercent = additionalLightData.GetInnerSpotPercent01(); var cosSpotOuterHalfAngle = Mathf.Clamp(Mathf.Cos(spotAngle * 0.5f * Mathf.Deg2Rad), 0.0f, 1.0f); var sinSpotOuterHalfAngle = Mathf.Sqrt(1.0f - cosSpotOuterHalfAngle * cosSpotOuterHalfAngle); var cosSpotInnerHalfAngle = Mathf.Clamp(Mathf.Cos(spotAngle * 0.5f * innerConePercent * Mathf.Deg2Rad), 0.0f, 1.0f); // inner cone var val = Mathf.Max(0.0001f, (cosSpotInnerHalfAngle - cosSpotOuterHalfAngle)); lightData.angleScale = 1.0f / val; lightData.angleOffset = -cosSpotOuterHalfAngle * lightData.angleScale; // Rescale for cookies and windowing. float cotOuterHalfAngle = cosSpotOuterHalfAngle / sinSpotOuterHalfAngle; lightData.up *= cotOuterHalfAngle; lightData.right *= cotOuterHalfAngle; } else { // These are the neutral values allowing GetAngleAnttenuation in shader code to return 1.0 lightData.angleScale = 0.0f; lightData.angleOffset = 1.0f; } if (lightData.lightType != GPULightType.Directional && lightData.lightType != GPULightType.ProjectorBox) { // Store the squared radius of the light to simulate a fill light. lightData.size = new Vector2(additionalLightData.shapeRadius * additionalLightData.shapeRadius, 0); } if (lightData.lightType == GPULightType.Rectangle || lightData.lightType == GPULightType.Tube) { lightData.size = new Vector2(additionalLightData.shapeWidth, additionalLightData.shapeHeight); } lightData.lightDimmer = lightDistanceFade * (additionalLightData.lightDimmer); lightData.diffuseDimmer = lightDistanceFade * (additionalLightData.affectDiffuse ? additionalLightData.lightDimmer : 0); lightData.specularDimmer = lightDistanceFade * (additionalLightData.affectSpecular ? additionalLightData.lightDimmer * hdCamera.frameSettings.specularGlobalDimmer : 0); lightData.volumetricLightDimmer = lightDistanceFade * (additionalLightData.volumetricDimmer); lightData.contactShadowIndex = -1; lightData.cookieIndex = -1; lightData.shadowIndex = -1; lightData.rayTracedAreaShadowIndex = -1; if (light != null && light.cookie != null) { // TODO: add texture atlas support for cookie textures. switch (light.type) { case LightType.Spot: lightData.cookieIndex = m_LightLoop.cookieTexArray.FetchSlice(cmd, light.cookie); break; case LightType.Point: lightData.cookieIndex = m_LightLoop.cubeCookieTexArray.FetchSlice(cmd, light.cookie); break; } } else if (light.type == LightType.Spot && additionalLightData.spotLightShape != SpotLightShape.Cone) { // Projectors lights must always have a cookie texture. // As long as the cache is a texture array and not an atlas, the 4x4 white texture will be rescaled to 128 lightData.cookieIndex = m_LightLoop.cookieTexArray.FetchSlice(cmd, Texture2D.whiteTexture); } else if (lightData.lightType == GPULightType.Rectangle && additionalLightData.areaLightCookie != null) { lightData.cookieIndex = m_LightLoop.areaLightCookieManager.FetchSlice(cmd, additionalLightData.areaLightCookie); } { lightData.shadowDimmer = 1.0f; lightData.volumetricShadowDimmer = 1.0f; } { // fix up shadow information lightData.shadowIndex = additionalLightData.shadowIndex; } // Value of max smoothness is from artists point of view, need to convert from perceptual smoothness to roughness lightData.minRoughness = (1.0f - additionalLightData.maxSmoothness) * (1.0f - additionalLightData.maxSmoothness); // No usage for the shadow masks lightData.shadowMaskSelector = Vector4.zero; { // use -1 to say that we don't use shadow mask lightData.shadowMaskSelector.x = -1.0f; lightData.nonLightMappedOnly = 0; } // Set the data for this light m_LightDataCPUArray[lightIdx] = lightData; } //Push the data to the GPU m_LightDataGPUArray.SetData(m_LightDataCPUArray); }
public void SetFilter() { values.Clear(); var uiCountryMapWindow = UIMainController.Instance.GetWindow <UICountryMapWindow>(UIConstants.WINDOW_COUNTRY_MAP); var regions = uiCountryMapWindow.UIRegions; var selectedIndexes = new List <int>(); for (int i = 0; i < months.Count; i++) { var month = months[i]; if (month.isOn) { selectedIndexes.Add(i); } } for (int i = 0; i < regions.Count; i++) { var region = regionStats[i]; var value = 0.0f; var count = selectedIndexes.Count; for (int j = 0; j < count; j++) { var index = selectedIndexes[j]; if (index < region.stats.Count) { var regionStats = region.stats[index]; value += regionStats.speed; } } values.Add(value / count); } diagram.Init(values); diagram.Draw(); for (int i = 0; i < diagram.UIParts.Count; i++) { var region = regions[i]; if (cachedColorBlock == default(ColorBlock)) { cachedColorBlock = regions[i].button.colors; } var value = values[i]; var diagramPart = diagram.UIParts.Find(x => x.Origin.value == value); var color = Mathf.CorrelatedColorTemperatureToRGB(value * 1000f); region.button.colors = new ColorBlock() { normalColor = color, pressedColor = cachedColorBlock.pressedColor, highlightedColor = cachedColorBlock.highlightedColor, disabledColor = cachedColorBlock.disabledColor, colorMultiplier = cachedColorBlock.colorMultiplier, fadeDuration = cachedColorBlock.fadeDuration }; region.infoText.color = diagramPart.BaseImage.color; region.infoText.text = string.Format("{0}\n{1}\n({2}%)", region.Origin.name, diagramPart.Origin.value, diagramPart.Origin.percentage * 100f); } }
/// <summary> /// Collects the light's data so it will be packed into a common compute buffer by the lights manager and sent to the compute shader /// </summary> /// <param name="camera"></param> private void PackParameters(Camera camera) { Vector4 colorTemperature = (LightHelpers.IsColorTemperatureAvailable && useColorTemperatureTint) ? (Vector4)Mathf.CorrelatedColorTemperatureToRGB(LightComponent.colorTemperature) : Vector4.one; Vector4 color = (overrideColor ? overridingColor : LightComponent.color * colorTemperature) * LightComponent.intensity * strength; int useDefaultScattering = useScattering == BooleanChoice.Default ? 1 : 0; float scatteringOverride = useScattering == BooleanChoice.False ? -2 : (overrideScattering ? 1.0f - overridingScattering : -1); switch (Type) { case LightType.Directional: { _directionalLightParameters.color = color; _directionalLightParameters.useDefaultScattering = useDefaultScattering; _directionalLightParameters.scatteringOverride = scatteringOverride; _directionalLightParameters.lightPosition = LightComponent.transform.position; _directionalLightParameters.lightDirection = LightComponent.transform.forward; Matrix4x4 lightToWorldMatrix = Matrix4x4.TRS(LightComponent.transform.position, LightComponent.transform.rotation, Vector3.one); _directionalLightParameters.worldToLightMatrix = MatrixFloats.ToMatrixFloats(lightToWorldMatrix.inverse); _directionalLightParameters.lightToWorldMatrix = MatrixFloats.ToMatrixFloats(lightToWorldMatrix); _directionalLightParameters.shadowMapIndex = CastsShadows ? _shadowMapIndex : -1; _directionalLightParameters.cookieMapIndex = -1; if (CastsCookie) { _directionalLightParameters.cookieMapIndex = _cookieMapIndex; _directionalLightParameters.cookieParameters.x = LightComponent.cookieSize; _directionalLightParameters.cookieParameters.y = LightComponent.cookie.wrapMode == TextureWrapMode.Repeat ? 0 : 1; } _directionalLightParameters.enableOutOfPhaseColor = enableOutOfPhaseColor ? 1 : 0; _directionalLightParameters.outOfPhaseColor = (Vector4)outOfPhaseColor * outOfPhaseColorStrength; } break; case LightType.Spot: { _spotLightParameters.color = color; _spotLightParameters.useDefaultScattering = useDefaultScattering; _spotLightParameters.scatteringOverride = scatteringOverride; _spotLightParameters.lightPosition = LightComponent.transform.position; _spotLightParameters.lightDirection = LightComponent.transform.forward; _spotLightParameters.lightRange = LightComponent.range; _spotLightParameters.lightCosHalfAngle = Mathf.Cos(LightComponent.spotAngle * 0.5f * Mathf.Deg2Rad); _spotLightParameters.angularFalloffParameters = new Vector2(customAngularFalloffThreshold, customAngularFalloffPower); _spotLightParameters.distanceFalloffParameters = new Vector2(Mathf.Min(customDistanceFalloffThreshold, 0.999999f), customDistanceFalloffPower); _spotLightParameters.shadowMapIndex = -1; if (CastsShadows) { Matrix4x4 worldToLight = Matrix4x4.TRS(LightComponent.transform.position, LightComponent.transform.rotation, Vector3.one).inverse; Matrix4x4 proj = Matrix4x4.Perspective(LightComponent.spotAngle, 1, LightComponent.shadowNearPlane, LightComponent.range); Matrix4x4 clip = Matrix4x4.TRS(Vector3.one * 0.5f, Quaternion.identity, Vector3.one * 0.5f); Matrix4x4 m = clip * proj; m[0, 2] *= -1; m[1, 2] *= -1; m[2, 2] *= -1; m[3, 2] *= -1; Matrix4x4 worldToShadow = m * worldToLight; _spotLightParameters.worldToShadowMatrix = MatrixFloats.ToMatrixFloats(worldToShadow); _spotLightParameters.shadowMapIndex = _shadowMapIndex; _spotLightParameters.shadowStrength = 1.0f - LightComponent.shadowStrength; } _spotLightParameters.cookieMapIndex = -1; if (CastsCookie) { _spotLightParameters.cookieMapIndex = _cookieMapIndex; _spotLightParameters.cookieParameters.x = customCookieDistanceFalloffStartThreshold; _spotLightParameters.cookieParameters.y = customCookieDistanceFalloffEndThreshold; _spotLightParameters.cookieParameters.z = customCookieDistanceFalloffPower; } } break; case LightType.Point: { _pointLightParameters.color = color; _pointLightParameters.useDefaultScattering = useDefaultScattering; _pointLightParameters.scatteringOverride = scatteringOverride; _pointLightParameters.lightPosition = LightComponent.transform.position; _pointLightParameters.lightRange = LightComponent.range; _pointLightParameters.distanceFalloffParameters = new Vector2(Mathf.Min(customDistanceFalloffThreshold, 0.999999f), customDistanceFalloffPower); _pointLightParameters.shadowMapIndex = -1; if (CastsShadows) { Matrix4x4 worldMatrix = Matrix4x4.TRS(camera.transform.position, transform.rotation, Vector3.one * camera.nearClipPlane * 2); _storePointLightShadowMapMaterial.SetMatrix("_WorldViewProj", GL.GetGPUProjectionMatrix(camera.projectionMatrix, true) * camera.worldToCameraMatrix * worldMatrix); _copyShadowmapCommandBuffer.SetGlobalTexture("_ShadowMapTexture", BuiltinRenderTextureType.CurrentActive); _copyShadowmapCommandBuffer.SetRenderTarget(shadowMapRenderTexture); _copyShadowmapCommandBuffer.DrawMesh(_storePointLightShadowMapMesh, worldMatrix, _storePointLightShadowMapMaterial, 0); Matrix4x4 worldToShadow = Matrix4x4.TRS(LightComponent.transform.position, LightComponent.transform.rotation, Vector3.one * LightComponent.range).inverse; _pointLightParameters.worldToShadowMatrix = MatrixFloats.ToMatrixFloats(worldToShadow); #if UNITY_2017_3_OR_NEWER _pointLightParameters.lightProjectionParameters = new Vector2(LightComponent.range / (LightComponent.shadowNearPlane - LightComponent.range), (LightComponent.shadowNearPlane * LightComponent.range) / (LightComponent.shadowNearPlane - LightComponent.range)); // From UnityShaderVariables.cginc:114 #endif _pointLightParameters.shadowMapIndex = _shadowMapIndex; _pointLightParameters.shadowStrength = 1.0f - LightComponent.shadowStrength; } _pointLightParameters.cookieMapIndex = -1; if (CastsCookie) { _pointLightParameters.cookieMapIndex = _cookieMapIndex; _pointLightParameters.cookieParameters.x = customCookieDistanceFalloffStartThreshold; _pointLightParameters.cookieParameters.y = customCookieDistanceFalloffEndThreshold; _pointLightParameters.cookieParameters.z = customCookieDistanceFalloffPower; } } break; } }
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; } // NOTE: When the user duplicates a light in the editor, the material is not duplicated and when changing the properties of one of them (source or duplication) // It either overrides both or is overriden. Given that when we duplicate an object the name changes, this approach works. When the name of the game object is then changed again // the material is not re-created until one of the light properties is changed again. if (emissiveMeshRenderer.sharedMaterial == null || emissiveMeshRenderer.sharedMaterial.name != gameObject.name) { emissiveMeshRenderer.sharedMaterial = new Material(Shader.Find("HDRP/Unlit")); emissiveMeshRenderer.sharedMaterial.name = gameObject.name; } // 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 *= Mathf.CorrelatedColorTemperatureToRGB(m_Light.colorTemperature); } value *= lightDimmer; emissiveMeshRenderer.sharedMaterial.SetColor("_EmissiveColor", value); // Set the cookie (if there is one) and raise or remove the shader feature emissiveMeshRenderer.sharedMaterial.SetTexture("_EmissiveColorMap", areaLightCookie); CoreUtils.SetKeyword(emissiveMeshRenderer.sharedMaterial, "_EMISSIVE_COLOR_MAP", areaLightCookie != null); }
// Return true if the light must be added to the baking public static bool LightDataGIExtract(Light light, ref LightDataGI lightDataGI) { var add = light.GetComponent <HDAdditionalLightData>(); if (add == null) { add = HDUtils.s_DefaultHDAdditionalLightData; } Cookie cookie; LightmapperUtils.Extract(light, out cookie); lightDataGI.cookieID = cookie.instanceID; lightDataGI.cookieScale = cookie.scale; // 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 = Mathf.CorrelatedColorTemperatureToRGB(light.colorTemperature); } #endif #if UNITY_EDITOR LightMode lightMode = LightmapperUtils.Extract(light.lightmapBakeType); #else LightMode lightMode = LightmapperUtils.Extract(light.bakingOutput.lightmapBakeType); #endif float lightDimmer = 1; if (lightMode == LightMode.Realtime && add.affectDiffuse) { lightDimmer = add.lightDimmer; } lightDataGI.instanceID = light.GetInstanceID(); LinearColor directColor, indirectColor; directColor = add.affectDiffuse ? LinearColor.Convert(light.color, light.intensity) : LinearColor.Black(); directColor.red *= cct.r; directColor.green *= cct.g; directColor.blue *= cct.b; directColor.intensity *= lightDimmer; indirectColor = add.affectDiffuse ? LightmapperUtils.ExtractIndirect(light) : LinearColor.Black(); indirectColor.red *= cct.r; indirectColor.green *= cct.g; indirectColor.blue *= cct.b; indirectColor.intensity *= lightDimmer; lightDataGI.color = directColor; lightDataGI.indirectColor = indirectColor; // 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 lightDataGI.mode = LightmapperUtils.Extract(light.lightmapBakeType); #else lightDataGI.mode = LightmapperUtils.Extract(light.bakingOutput.lightmapBakeType); #endif lightDataGI.shadow = (byte)(light.shadows != LightShadows.None ? 1 : 0); HDLightType lightType = add.ComputeLightType(light); if (lightType != HDLightType.Area) { // 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. lightDataGI.color.intensity /= Mathf.PI; lightDataGI.indirectColor.intensity /= Mathf.PI; directColor.intensity /= Mathf.PI; indirectColor.intensity /= Mathf.PI; } switch (lightType) { case HDLightType.Directional: lightDataGI.orientation = light.transform.rotation; lightDataGI.position = light.transform.position; lightDataGI.range = 0.0f; lightDataGI.coneAngle = add.shapeWidth; lightDataGI.innerConeAngle = add.shapeHeight; #if UNITY_EDITOR lightDataGI.shape0 = light.shadows != LightShadows.None ? (Mathf.Deg2Rad * light.shadowAngle) : 0.0f; #else lightDataGI.shape0 = 0.0f; #endif lightDataGI.shape1 = 0.0f; lightDataGI.type = UnityEngine.Experimental.GlobalIllumination.LightType.Directional; lightDataGI.falloff = FalloffType.Undefined; lightDataGI.coneAngle = add.shapeWidth; lightDataGI.innerConeAngle = add.shapeHeight; break; case HDLightType.Spot: switch (add.spotLightShape) { case SpotLightShape.Cone: { SpotLight spot; spot.instanceID = light.GetInstanceID(); spot.shadow = light.shadows != LightShadows.None; spot.mode = lightMode; #if UNITY_EDITOR spot.sphereRadius = light.shadows != LightShadows.None ? light.shadowRadius : 0.0f; #else spot.sphereRadius = 0.0f; #endif spot.position = light.transform.position; spot.orientation = light.transform.rotation; spot.color = directColor; spot.indirectColor = indirectColor; spot.range = light.range; spot.coneAngle = light.spotAngle * Mathf.Deg2Rad; spot.innerConeAngle = light.spotAngle * Mathf.Deg2Rad * add.innerSpotPercent01; spot.falloff = add.applyRangeAttenuation ? FalloffType.InverseSquared : FalloffType.InverseSquaredNoRangeAttenuation; spot.angularFalloff = AngularFalloffType.AnalyticAndInnerAngle; lightDataGI.Init(ref spot, ref cookie); lightDataGI.shape1 = (float)AngularFalloffType.AnalyticAndInnerAngle; if (light.cookie != null) { lightDataGI.cookieID = light.cookie.GetInstanceID(); } else if (add.IESSpot != null) { lightDataGI.cookieID = add.IESSpot.GetInstanceID(); } else { lightDataGI.cookieID = 0; } } break; case SpotLightShape.Pyramid: { SpotLightPyramidShape pyramid; pyramid.instanceID = light.GetInstanceID(); pyramid.shadow = light.shadows != LightShadows.None; pyramid.mode = lightMode; pyramid.position = light.transform.position; pyramid.orientation = light.transform.rotation; pyramid.color = directColor; pyramid.indirectColor = indirectColor; pyramid.range = light.range; pyramid.angle = light.spotAngle * Mathf.Deg2Rad; pyramid.aspectRatio = add.aspectRatio; pyramid.falloff = add.applyRangeAttenuation ? FalloffType.InverseSquared : FalloffType.InverseSquaredNoRangeAttenuation; lightDataGI.Init(ref pyramid, ref cookie); if (light.cookie != null) { lightDataGI.cookieID = light.cookie.GetInstanceID(); } else if (add.IESSpot != null) { lightDataGI.cookieID = add.IESSpot.GetInstanceID(); } else { lightDataGI.cookieID = 0; } } break; case SpotLightShape.Box: { SpotLightBoxShape box; box.instanceID = light.GetInstanceID(); box.shadow = light.shadows != LightShadows.None; box.mode = lightMode; box.position = light.transform.position; box.orientation = light.transform.rotation; box.color = directColor; box.indirectColor = indirectColor; box.range = light.range; box.width = add.shapeWidth; box.height = add.shapeHeight; lightDataGI.Init(ref box, ref cookie); if (light.cookie != null) { lightDataGI.cookieID = light.cookie.GetInstanceID(); } else if (add.IESSpot != null) { lightDataGI.cookieID = add.IESSpot.GetInstanceID(); } else { lightDataGI.cookieID = 0; } } break; default: Debug.Assert(false, "Encountered an unknown SpotLightShape."); break; } break; case HDLightType.Point: lightDataGI.orientation = light.transform.rotation; lightDataGI.position = light.transform.position; lightDataGI.range = light.range; lightDataGI.coneAngle = 0.0f; lightDataGI.innerConeAngle = 0.0f; #if UNITY_EDITOR lightDataGI.shape0 = light.shadows != LightShadows.None ? light.shadowRadius : 0.0f; #else lightDataGI.shape0 = 0.0f; #endif lightDataGI.shape1 = 0.0f; lightDataGI.type = UnityEngine.Experimental.GlobalIllumination.LightType.Point; lightDataGI.falloff = add.applyRangeAttenuation ? FalloffType.InverseSquared : FalloffType.InverseSquaredNoRangeAttenuation; break; case HDLightType.Area: switch (add.areaLightShape) { case AreaLightShape.Rectangle: lightDataGI.orientation = light.transform.rotation; lightDataGI.position = light.transform.position; lightDataGI.range = light.range; lightDataGI.coneAngle = 0.0f; lightDataGI.innerConeAngle = 0.0f; lightDataGI.shape0 = add.shapeWidth; lightDataGI.shape1 = add.shapeHeight; // TEMP: for now, if we bake a rectangle type this will disable the light for runtime, need to speak with GI team about it! lightDataGI.type = UnityEngine.Experimental.GlobalIllumination.LightType.Rectangle; lightDataGI.falloff = add.applyRangeAttenuation ? FalloffType.InverseSquared : FalloffType.InverseSquaredNoRangeAttenuation; if (add.areaLightCookie != null) { lightDataGI.cookieID = add.areaLightCookie.GetInstanceID(); } else if (add.IESSpot != null) { lightDataGI.cookieID = add.IESSpot.GetInstanceID(); } else { lightDataGI.cookieID = 0; } break; case AreaLightShape.Tube: lightDataGI.InitNoBake(lightDataGI.instanceID); break; case AreaLightShape.Disc: lightDataGI.orientation = light.transform.rotation; lightDataGI.position = light.transform.position; lightDataGI.range = light.range; lightDataGI.coneAngle = 0.0f; lightDataGI.innerConeAngle = 0.0f; #if UNITY_EDITOR lightDataGI.shape0 = light.areaSize.x; lightDataGI.shape1 = light.areaSize.y; #else lightDataGI.shape0 = 0.0f; lightDataGI.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! lightDataGI.type = UnityEngine.Experimental.GlobalIllumination.LightType.Disc; lightDataGI.falloff = add.applyRangeAttenuation ? FalloffType.InverseSquared : FalloffType.InverseSquaredNoRangeAttenuation; lightDataGI.cookieID = add.areaLightCookie ? add.areaLightCookie.GetInstanceID() : 0; break; default: Debug.Assert(false, "Encountered an unknown AreaLightShape."); break; } break; default: Debug.Assert(false, "Encountered an unknown LightType."); break; } return(true); }
/// <summary> /// Effective Job of drawing the set of Lens Flare registered /// </summary> /// <param name="lensFlareShader">Lens Flare material (HDRP or URP shader)</param> /// <param name="lensFlares">Set of Lens Flare</param> /// <param name="cam">Camera</param> /// <param name="actualWidth">Width actually used for rendering after dynamic resolution and XR is applied.</param> /// <param name="actualHeight">Height actually used for rendering after dynamic resolution and XR is applied.</param> /// <param name="usePanini">Set if use Panani Projection</param> /// <param name="paniniDistance">Distance used for Panini projection</param> /// <param name="paniniCropToFit">CropToFit parameter used for Panini projection</param> /// <param name="cmd">Command Buffer</param> /// <param name="colorBuffer">Source Render Target which contains the Color Buffer</param> /// <param name="GetLensFlareLightAttenuation">Delegate to which return return the Attenuation of the light based on their shape which uses the functions ShapeAttenuation...(...), must reimplemented per SRP</param> /// <param name="_FlareTex">ShaderID for the FlareTex</param> /// <param name="_FlareColorValue">ShaderID for the FlareColor</param> /// <param name="_FlareData0">ShaderID for the FlareData0</param> /// <param name="_FlareData1">ShaderID for the FlareData1</param> /// <param name="_FlareData2">ShaderID for the FlareData2</param> /// <param name="_FlareData3">ShaderID for the FlareData3</param> /// <param name="_FlareData4">ShaderID for the FlareData4</param> /// <param name="_FlareData5">ShaderID for the FlareData5</param> /// <param name="debugView">Debug View which setup black background to see only Lens Flare</param> static public void DoLensFlareDataDrivenCommon(Material lensFlareShader, LensFlareCommonSRP lensFlares, Camera cam, float actualWidth, float actualHeight, bool usePanini, float paniniDistance, float paniniCropToFit, Rendering.CommandBuffer cmd, Rendering.RenderTargetIdentifier colorBuffer, System.Func <Light, Camera, Vector3, float> GetLensFlareLightAttenuation, int _FlareTex, int _FlareColorValue, int _FlareData0, int _FlareData1, int _FlareData2, int _FlareData3, int _FlareData4, int _FlareData5, bool debugView) { Vector2 vScreenRatio; if (lensFlares.IsEmpty()) { return; } Vector2 screenSize = new Vector2(actualWidth, actualHeight); float screenRatio = screenSize.x / screenSize.y; vScreenRatio = new Vector2(screenRatio, 1.0f); Rendering.CoreUtils.SetRenderTarget(cmd, colorBuffer); if (debugView) { // Background pitch black to see only the Flares cmd.ClearRenderTarget(false, true, Color.black); } foreach (LensFlareComponentSRP comp in lensFlares.GetData()) { if (comp == null) { continue; } LensFlareDataSRP data = comp.lensFlareData; if (!comp.enabled || !comp.gameObject.activeSelf || !comp.gameObject.activeInHierarchy || data == null || data.elements == null || data.elements.Length == 0) { continue; } Light light = comp.GetComponent <Light>(); Vector3 positionWS; Vector3 viewportPos; bool isDirLight = false; if (light != null && light.type == LightType.Directional) { positionWS = -light.transform.forward * cam.farClipPlane; isDirLight = true; } else { positionWS = comp.transform.position; } viewportPos = cam.WorldToViewportPoint(positionWS); if (usePanini && cam == Camera.main) { viewportPos = DoPaniniProjection(viewportPos, actualWidth, actualHeight, cam.fieldOfView, paniniCropToFit, paniniDistance); } if (viewportPos.z < 0.0f) { continue; } if (!comp.allowOffScreen) { if (viewportPos.x < 0.0f || viewportPos.x > 1.0f || viewportPos.y < 0.0f || viewportPos.y > 1.0f) { continue; } } Vector4 modulationByColor = Vector4.one; Vector4 modulationAttenuation = Vector4.one; Vector3 diffToObject = positionWS - cam.transform.position; float distToObject = diffToObject.magnitude; float coefDistSample = distToObject / comp.maxAttenuationDistance; float coefScaleSample = distToObject / comp.maxAttenuationScale; float distanceAttenuation = !isDirLight && comp.distanceAttenuationCurve.length > 0 ? comp.distanceAttenuationCurve.Evaluate(coefDistSample) : 1.0f; float scaleByDistance = !isDirLight && comp.scaleByDistanceCurve.length >= 1 ? comp.scaleByDistanceCurve.Evaluate(coefScaleSample) : 1.0f; Color globalColorModulation = Color.white; if (light != null) { if (comp.attenuationByLightShape) { globalColorModulation *= GetLensFlareLightAttenuation(light, cam, -diffToObject.normalized); } } globalColorModulation *= distanceAttenuation; Vector3 dir = (cam.transform.position - comp.transform.position).normalized; Vector3 screenPosZ = cam.WorldToViewportPoint(positionWS + dir * comp.occlusionOffset); Vector2 occlusionRadiusEdgeScreenPos0 = (Vector2)cam.WorldToViewportPoint(positionWS); Vector2 occlusionRadiusEdgeScreenPos1 = (Vector2)cam.WorldToViewportPoint(positionWS + cam.transform.up * comp.occlusionRadius); float occlusionRadius = (occlusionRadiusEdgeScreenPos1 - occlusionRadiusEdgeScreenPos0).magnitude; cmd.SetGlobalVector(_FlareData1, new Vector4(occlusionRadius, comp.sampleCount, screenPosZ.z, actualHeight / actualWidth)); if (comp.useOcclusion) { cmd.EnableShaderKeyword("FLARE_OCCLUSION"); } else { cmd.DisableShaderKeyword("FLARE_OCCLUSION"); } foreach (LensFlareDataElementSRP element in data.elements) { if (element == null || (element.lensFlareTexture == null && element.flareType == SRPLensFlareType.Image) || element.localIntensity <= 0.0f || element.count <= 0) { continue; } Color colorModulation = globalColorModulation; if (light != null && element.modulateByLightColor) { if (light.useColorTemperature) { colorModulation *= light.color * Mathf.CorrelatedColorTemperatureToRGB(light.colorTemperature); } else { colorModulation *= light.color; } } Color curColor = colorModulation; Vector2 screenPos = new Vector2(2.0f * viewportPos.x - 1.0f, 1.0f - 2.0f * viewportPos.y); Vector2 translationScale = new Vector2(element.translationScale.x, element.translationScale.y); Texture texture = element.lensFlareTexture; float elemAspectRatio = element.sizeXY.x / element.sizeXY.y; float usedAspectRatio; if (element.flareType == SRPLensFlareType.Image) { usedAspectRatio = element.preserveAspectRatio ? ((((float)texture.height) / (float)texture.width)) : 1.0f; } else { usedAspectRatio = 1.0f; } float rotation = element.rotation; Vector4 tint = Vector4.Scale(element.tint, curColor); Vector2 radPos = new Vector2(Mathf.Abs(screenPos.x), Mathf.Abs(screenPos.y)); float radius = Mathf.Max(radPos.x, radPos.y); // l1 norm (instead of l2 norm) float radialsScaleRadius = comp.radialScreenAttenuationCurve.length > 0 ? comp.radialScreenAttenuationCurve.Evaluate(radius) : 1.0f; Vector2 elemSizeXY; if (element.preserveAspectRatio) { if (usedAspectRatio >= 1.0f) { elemSizeXY = new Vector2(element.sizeXY.x / usedAspectRatio, element.sizeXY.y); } else { elemSizeXY = new Vector2(element.sizeXY.x, element.sizeXY.y * usedAspectRatio); } } else { elemSizeXY = new Vector2(element.sizeXY.x, element.sizeXY.y); } float scaleSize = 0.1f; // Arbitrary value Vector2 size = new Vector2(elemSizeXY.x, elemSizeXY.y); float combinedScale = scaleByDistance * scaleSize * element.uniformScale * comp.scale; size *= combinedScale; Vector4 gradientModulation = new Vector4(1.0f, 1.0f, 1.0f, 1.0f); float currentIntensity = comp.intensity * element.localIntensity * radialsScaleRadius * distanceAttenuation; if (currentIntensity <= 0.0f) { continue; } curColor *= element.tint; curColor *= currentIntensity; float globalCos0 = Mathf.Cos(-element.angularOffset * Mathf.Deg2Rad); float globalSin0 = Mathf.Sin(-element.angularOffset * Mathf.Deg2Rad); float position = 2.0f * element.position; SRPLensFlareBlendMode blendMode = element.blendMode; int materialPass; if (blendMode == SRPLensFlareBlendMode.Additive) { materialPass = 0; } else if (blendMode == SRPLensFlareBlendMode.Screen) { materialPass = 1; } else if (blendMode == SRPLensFlareBlendMode.Premultiply) { materialPass = 2; } else if (blendMode == SRPLensFlareBlendMode.Lerp) { materialPass = 3; } else { materialPass = 0; } if (element.flareType == SRPLensFlareType.Image) { cmd.DisableShaderKeyword("FLARE_CIRCLE"); cmd.DisableShaderKeyword("FLARE_POLYGON"); } else if (element.flareType == SRPLensFlareType.Circle) { cmd.EnableShaderKeyword("FLARE_CIRCLE"); cmd.DisableShaderKeyword("FLARE_POLYGON"); } else if (element.flareType == SRPLensFlareType.Polygon) { cmd.DisableShaderKeyword("FLARE_CIRCLE"); cmd.EnableShaderKeyword("FLARE_POLYGON"); } if (element.flareType == SRPLensFlareType.Circle || element.flareType == SRPLensFlareType.Polygon) { if (element.inverseSDF) { cmd.EnableShaderKeyword("FLARE_INVERSE_SDF"); } else { cmd.DisableShaderKeyword("FLARE_INVERSE_SDF"); } } else { cmd.DisableShaderKeyword("FLARE_INVERSE_SDF"); } if (element.lensFlareTexture != null) { cmd.SetGlobalTexture(_FlareTex, element.lensFlareTexture); } float usedGradientPosition = Mathf.Clamp01((1.0f - element.edgeOffset) - 1e-6f); if (element.flareType == SRPLensFlareType.Polygon) { usedGradientPosition = Mathf.Pow(usedGradientPosition + 1.0f, 5); } Vector2 ComputeLocalSize(Vector2 rayOff, Vector2 rayOff0, Vector2 curSize, AnimationCurve distortionCurve) { Vector2 rayOffZ = GetLensFlareRayOffset(screenPos, position, globalCos0, globalSin0); Vector2 localRadPos; float localRadius; if (!element.distortionRelativeToCenter) { localRadPos = (rayOff - rayOff0) * 0.5f; localRadius = Mathf.Clamp01(Mathf.Max(Mathf.Abs(localRadPos.x), Mathf.Abs(localRadPos.y))); // l1 norm (instead of l2 norm) } else { localRadPos = screenPos + (rayOff + new Vector2(element.positionOffset.x, -element.positionOffset.y)) * element.translationScale; localRadius = Mathf.Clamp01(localRadPos.magnitude); // l2 norm (instead of l1 norm) } float localLerpValue = Mathf.Clamp01(distortionCurve.Evaluate(localRadius)); return(new Vector2(Mathf.Lerp(curSize.x, element.targetSizeDistortion.x * combinedScale / usedAspectRatio, localLerpValue), Mathf.Lerp(curSize.y, element.targetSizeDistortion.y * combinedScale, localLerpValue))); } float usedSDFRoundness = element.sdfRoundness; cmd.SetGlobalVector(_FlareData5, new Vector4(comp.allowOffScreen ? 1.0f : -1.0f, usedGradientPosition, Mathf.Exp(Mathf.Lerp(0.0f, 4.0f, Mathf.Clamp01(1.0f - element.fallOff))), 0.0f)); if (element.flareType == SRPLensFlareType.Polygon) { float invSide = 1.0f / (float)element.sideCount; float rCos = Mathf.Cos(Mathf.PI * invSide); float roundValue = rCos * usedSDFRoundness; float r = rCos - roundValue; float an = 2.0f * Mathf.PI * invSide; float he = r * Mathf.Tan(0.5f * an); cmd.SetGlobalVector(_FlareData4, new Vector4(usedSDFRoundness, r, an, he)); } else { cmd.SetGlobalVector(_FlareData4, new Vector4(usedSDFRoundness, 0.0f, 0.0f, 0.0f)); } if (!element.allowMultipleElement || element.count == 1) { Vector4 flareData0 = GetFlareData0(screenPos, element.translationScale, vScreenRatio, element.rotation, position, element.angularOffset, element.positionOffset, element.autoRotate); Vector2 rayOff = GetLensFlareRayOffset(screenPos, position, globalCos0, globalSin0); Vector2 localSize = size; if (element.enableRadialDistortion) { Vector2 rayOff0 = GetLensFlareRayOffset(screenPos, 0.0f, globalCos0, globalSin0); localSize = ComputeLocalSize(rayOff, rayOff0, localSize, element.distortionCurve); } cmd.SetGlobalVector(_FlareData0, flareData0); cmd.SetGlobalVector(_FlareData2, new Vector4(screenPos.x, screenPos.y, localSize.x, localSize.y)); cmd.SetGlobalVector(_FlareData3, new Vector4(rayOff.x * element.translationScale.x, rayOff.y * element.translationScale.y, 1.0f / (float)element.sideCount, 0.0f)); cmd.SetGlobalVector(_FlareColorValue, curColor); UnityEngine.Rendering.Blitter.DrawQuad(cmd, lensFlareShader, materialPass); } else { float dLength = 2.0f * element.lengthSpread / ((float)(element.count - 1)); if (element.distribution == SRPLensFlareDistribution.Uniform) { for (int elemIdx = 0; elemIdx < element.count; ++elemIdx) { Vector2 rayOff = GetLensFlareRayOffset(screenPos, position, globalCos0, globalSin0); Vector2 localSize = size; if (element.enableRadialDistortion) { Vector2 rayOff0 = GetLensFlareRayOffset(screenPos, 0.0f, globalCos0, globalSin0); localSize = ComputeLocalSize(rayOff, rayOff0, localSize, element.distortionCurve); } float timeScale = element.count >= 2 ? ((float)elemIdx) / ((float)(element.count - 1)) : 0.5f; Color col = element.colorGradient.Evaluate(timeScale); Vector4 flareData0 = GetFlareData0(screenPos, element.translationScale, vScreenRatio, element.rotation, position, element.angularOffset, element.positionOffset, element.autoRotate); cmd.SetGlobalVector(_FlareData0, flareData0); cmd.SetGlobalVector(_FlareData2, new Vector4(screenPos.x, screenPos.y, localSize.x, localSize.y)); cmd.SetGlobalVector(_FlareData3, new Vector4(rayOff.x * element.translationScale.x, rayOff.y * element.translationScale.y, 1.0f / (float)element.sideCount, 0.0f)); cmd.SetGlobalVector(_FlareColorValue, curColor * col); UnityEngine.Rendering.Blitter.DrawQuad(cmd, lensFlareShader, materialPass); position += dLength; } } else if (element.distribution == SRPLensFlareDistribution.Random) { Random.State backupRandState = UnityEngine.Random.state; Random.InitState(element.seed); Vector2 side = new Vector2(Mathf.Sin(-element.angularOffset * Mathf.Deg2Rad), Mathf.Cos(-element.angularOffset * Mathf.Deg2Rad)); side *= element.positionVariation.y; float RandomRange(float min, float max) { return(Random.Range(min, max)); } for (int elemIdx = 0; elemIdx < element.count; ++elemIdx) { float localIntensity = RandomRange(-1.0f, 1.0f) * element.intensityVariation + 1.0f; Vector2 rayOff = GetLensFlareRayOffset(screenPos, position, globalCos0, globalSin0); Vector2 localSize = size; if (element.enableRadialDistortion) { Vector2 rayOff0 = GetLensFlareRayOffset(screenPos, 0.0f, globalCos0, globalSin0); localSize = ComputeLocalSize(rayOff, rayOff0, localSize, element.distortionCurve); } localSize += localSize * (element.scaleVariation * RandomRange(-1.0f, 1.0f)); Color randCol = element.colorGradient.Evaluate(RandomRange(0.0f, 1.0f)); Vector2 localPositionOffset = element.positionOffset + RandomRange(-1.0f, 1.0f) * side; float localRotation = element.rotation + RandomRange(-Mathf.PI, Mathf.PI) * element.rotationVariation; if (localIntensity > 0.0f) { Vector4 flareData0 = GetFlareData0(screenPos, element.translationScale, vScreenRatio, localRotation, position, element.angularOffset, localPositionOffset, element.autoRotate); cmd.SetGlobalVector(_FlareData0, flareData0); cmd.SetGlobalVector(_FlareData2, new Vector4(screenPos.x, screenPos.y, localSize.x, localSize.y)); cmd.SetGlobalVector(_FlareData3, new Vector4(rayOff.x * element.translationScale.x, rayOff.y * element.translationScale.y, 1.0f / (float)element.sideCount, 0.0f)); cmd.SetGlobalVector(_FlareColorValue, curColor * randCol * localIntensity); UnityEngine.Rendering.Blitter.DrawQuad(cmd, lensFlareShader, materialPass); } position += dLength; position += 0.5f * dLength * RandomRange(-1.0f, 1.0f) * element.positionVariation.x; } Random.state = backupRandState; } else if (element.distribution == SRPLensFlareDistribution.Curve) { for (int elemIdx = 0; elemIdx < element.count; ++elemIdx) { float timeScale = element.count >= 2 ? ((float)elemIdx) / ((float)(element.count - 1)) : 0.5f; Color col = element.colorGradient.Evaluate(timeScale); float positionSpacing = element.positionCurve.length > 0 ? element.positionCurve.Evaluate(timeScale) : 1.0f; float localPos = position + 2.0f * element.lengthSpread * positionSpacing; Vector2 rayOff = GetLensFlareRayOffset(screenPos, localPos, globalCos0, globalSin0); Vector2 localSize = size; if (element.enableRadialDistortion) { Vector2 rayOff0 = GetLensFlareRayOffset(screenPos, 0.0f, globalCos0, globalSin0); localSize = ComputeLocalSize(rayOff, rayOff0, localSize, element.distortionCurve); } float sizeCurveValue = element.scaleCurve.length > 0 ? element.scaleCurve.Evaluate(timeScale) : 1.0f; localSize *= sizeCurveValue; Vector4 flareData0 = GetFlareData0(screenPos, element.translationScale, vScreenRatio, element.rotation, localPos, element.angularOffset, element.positionOffset, element.autoRotate); cmd.SetGlobalVector(_FlareData0, flareData0); cmd.SetGlobalVector(_FlareData2, new Vector4(screenPos.x, screenPos.y, localSize.x, localSize.y)); cmd.SetGlobalVector(_FlareData3, new Vector4(rayOff.x * element.translationScale.x, rayOff.y * element.translationScale.y, 1.0f / (float)element.sideCount, 0.0f)); cmd.SetGlobalVector(_FlareColorValue, curColor * col); UnityEngine.Rendering.Blitter.DrawQuad(cmd, lensFlareShader, materialPass); } } } } } }
/// <summary> /// Convert a color temperature in Kelvin to RGB color. /// </summary> /// <param name="kelvin"> /// Temperature in Kelvin. Range 1000 to 40000 Kelvin /// </param> /// <returns> /// Correlated Color Temperature as floating point RGB color. /// </returns> public static Color CorrelatedColorTemperatureToRGB(float kelvin) { return(Mathf.CorrelatedColorTemperatureToRGB(kelvin)); }
public static Color ColorFromTemperature(float temperature) { return(temperature > 0.0f ? Mathf.CorrelatedColorTemperatureToRGB(temperature).gamma : Color.white); }
// 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 = Mathf.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.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 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.Tube) { ld.InitNoBake(ld.instanceID); } else { Debug.Assert(false, "Encountered an unknown LightType."); } return(true); }