Esempio n. 1
0
        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);
        }