public Color SampleLight(List <BlockLight> lightList, BlockSpacePosition samplePosition, CubeSide sampleSide) { float ambientPercentage = (samplePosition.y - Configuration.AMBIENT_SUBTERRANEAN_FULL_HEIGHT) / Configuration.AMBIENT_SUBTERRANEAN_START_HEIGHT; ambientPercentage = Mathf.Clamp(ambientPercentage, 0.0f, 1.0f); float calcHue = Mathf.Lerp(Configuration.AMBIENT_LIGHT_HUE_SUBTERRANEAN, Configuration.AMBIENT_LIGHT_HUE, ambientPercentage); float calcSaturation = Mathf.Lerp(Configuration.AMBIENT_LIGHT_SATURATION_SUBTERRANEAN, Configuration.AMBIENT_LIGHT_SATURATION, ambientPercentage); float calcValue = Mathf.Lerp(Configuration.AMBIENT_LIGHT_VALUE_SUBTERRANEAN, Configuration.AMBIENT_LIGHT_VALUE, ambientPercentage); HSBColor hsbColor; hsbColor.a = 1.0f; hsbColor.h = calcHue / 255.0f; hsbColor.s = calcSaturation / 255.0f; hsbColor.b = calcValue / 255.0f; Color calcColor = hsbColor.ToColor(); // Calculate sunlight Vector3 startPosition; startPosition.x = samplePosition.x; startPosition.y = samplePosition.y; startPosition.z = samplePosition.z; Vector3 sunPosition = startPosition + (Configuration.SUN_ANGLE * Configuration.HEIGHT); BlockSpacePosition blockSunPosition; blockSunPosition.x = (int)sunPosition.x; blockSunPosition.y = (int)sunPosition.y; blockSunPosition.z = (int)sunPosition.z; byte sunlightHue; byte sunlightSaturation; byte sunlightValue; bool sunlight = !RaytraceLightBeam(blockSunPosition, samplePosition, sampleSide, Configuration.SUNLIGHT_HUE, Configuration.SUNLIGHT_SATURATION, Configuration.SUNLIGHT_VALUE, out sunlightHue, out sunlightSaturation, out sunlightValue); if (sunlight && LightCanAffectFace(samplePosition, blockSunPosition, sampleSide)) { calcColor = AddLightSample(calcColor, sunlightHue, sunlightSaturation, sunlightValue); } // Calculate artificial light int lightListCount = lightList.Count; for (int i = 0; i < lightListCount; i++) { BlockLight light = lightList[i]; BlockSpacePosition worldLightPosition = light.chunkPosition.GetBlockSpacePosition(light.chunk); if (worldLightPosition.x == samplePosition.x && worldLightPosition.y == samplePosition.y && worldLightPosition.z == samplePosition.z) { // Emitter - Full light calcValue = 255; } else { bool lightFace = LightCanAffectFace(samplePosition, worldLightPosition, sampleSide); float distance = Vector3.Distance(worldLightPosition.GetVector3(), samplePosition.GetVector3()); BlockDefinition lightBlock = light.blockDefinition; if (distance < lightBlock.LightEmitRadius()) { byte lightHue = lightBlock.LightEmitHue(); byte lightSaturation = lightBlock.LightEmitSaturation(); byte lightValue = lightBlock.LightEmitValue(); if (lightFace) { lightFace = RaytraceLightBeam(worldLightPosition, samplePosition, sampleSide, lightBlock.LightEmitHue(), lightBlock.LightEmitSaturation(), lightBlock.LightEmitValue(), out lightHue, out lightSaturation, out lightValue) == false; } if (lightFace) { byte effectiveLightValue = (byte)Mathf.Min(lightValue * (1.0f - distance / lightBlock.LightEmitRadius())); calcColor = AddLightSample(calcColor, lightHue, lightSaturation, effectiveLightValue); } #if INEXPENSIVE_FAKE_GLOBAL_ILLUMINATION else { byte effectiveLightValue = (byte)Mathf.Min(calcValue + lightValue / 2.0f * ((1 - distance / lightBlock.LightEmitRadius()) * 0.4f), 254); calcColor = AddLightSample(calcColor, lightHue, lightSaturation, effectiveLightValue); } #endif } } } return(calcColor); }