Ejemplo n.º 1
0
        private void RenderRecipeOutLine()
        {
            if (recipeOutlineMeshRef == null || api.HideGuis)
            {
                return;
            }
            IRenderAPI           rpi         = api.Render;
            IClientWorldAccessor worldAccess = api.World;
            EntityPos            plrPos      = worldAccess.Player.Entity.Pos;
            Vec3d camPos = worldAccess.Player.Entity.CameraPos;

            IShaderProgram prog = rpi.GetEngineShader(EnumShaderProgram.Wireframe);

            prog.Use();
            rpi.GlMatrixModeModelView();

            rpi.GLEnableDepthTest();
            rpi.GlToggleBlend(true);



            rpi.GlPushMatrix();
            rpi.GlLoadMatrix(rpi.CameraMatrixOrigin);

            rpi.GlTranslate(pos.X - camPos.X, pos.Y - camPos.Y, pos.Z - camPos.Z);

            prog.UniformMatrix("projectionMatrix", rpi.CurrentProjectionMatrix);
            prog.UniformMatrix("modelViewMatrix", rpi.CurrentModelviewMatrix);

            outLineColorMul.A = 1 - GameMath.Clamp((float)Math.Sqrt(plrPos.SquareDistanceTo(pos.X, pos.Y, pos.Z)) / 5 - 1f, 0, 1);
            prog.Uniform("colorIn", outLineColorMul);

            rpi.RenderMesh(recipeOutlineMeshRef);

            rpi.GlPopMatrix();

            prog.Stop();
        }
        public void OnRenderFrame(float dt, EnumRenderStage stage)
        {
            if (!ShouldRender)
            {
                return;
            }

            bool shadowPass = stage != EnumRenderStage.Opaque;

            EntityPlayer entityPlayer = capi.World.Player.Entity;

            Mat4f.Identity(ModelMat);
            Mat4f.Translate(ModelMat, ModelMat, (float)(pos.X - entityPlayer.CameraPos.X), (float)(pos.Y - entityPlayer.CameraPos.Y), (float)(pos.Z - entityPlayer.CameraPos.Z));

            Mat4f.Translate(ModelMat, ModelMat, 0.5f, 0, 0.5f);
            Mat4f.RotateY(ModelMat, ModelMat, rotation.Y * GameMath.DEG2RAD);
            Mat4f.Translate(ModelMat, ModelMat, -0.5f, 0, -0.5f);

            IRenderAPI rpi = capi.Render;


            IShaderProgram prevProg = rpi.CurrentActiveShader;

            prevProg?.Stop();


            IShaderProgram prog = rpi.GetEngineShader(shadowPass ? EnumShaderProgram.Shadowmapentityanimated : EnumShaderProgram.Entityanimated);

            prog.Use();
            Vec4f lightrgbs = capi.World.BlockAccessor.GetLightRGBs((int)pos.X, (int)pos.Y, (int)pos.Z);

            rpi.GlToggleBlend(true, EnumBlendMode.Standard);

            if (!shadowPass)
            {
                prog.Uniform("rgbaAmbientIn", rpi.AmbientColor);
                prog.Uniform("rgbaFogIn", rpi.FogColor);
                prog.Uniform("fogMinIn", rpi.FogMin);
                prog.Uniform("fogDensityIn", rpi.FogDensity);
                prog.Uniform("rgbaLightIn", lightrgbs);
                prog.Uniform("renderColor", ColorUtil.WhiteArgbVec);
                prog.Uniform("alphaTest", 0.1f);
                prog.UniformMatrix("modelMatrix", ModelMat);
                prog.UniformMatrix("viewMatrix", rpi.CameraMatrixOriginf);
                prog.Uniform("windWaveIntensity", (float)0);
                prog.Uniform("skipRenderJointId", -2);
                prog.Uniform("skipRenderJointId2", -2);
                prog.Uniform("glitchEffectStrength", 0f);
            }
            else
            {
                prog.UniformMatrix("modelViewMatrix", Mat4f.Mul(new float[16], capi.Render.CurrentModelviewMatrix, ModelMat));
            }

            prog.BindTexture2D("entityTex", textureId, 0);
            prog.UniformMatrix("projectionMatrix", rpi.CurrentProjectionMatrix);

            prog.Uniform("addRenderFlags", 0);


            prog.UniformMatrices(
                "elementTransforms",
                GlobalConstants.MaxAnimatedElements,
                animator.Matrices
                );

            capi.Render.RenderMesh(meshref);

            prog.Stop();
            prevProg?.Use();
        }
Ejemplo n.º 3
0
        public void OnRenderFrame(float deltaTime, EnumRenderStage stage)
        {
            if (!renderClouds)
            {
                return;
            }

            if (!capi.IsGamePaused)
            {
                CloudTick(deltaTime);
            }

            if (capi.Render.FrameWidth == 0)
            {
                return;
            }

            prog.Use();
            prog.Uniform("sunPosition", capi.World.Calendar.SunPositionNormalized);


            double plrPosX = capi.World.Player.Entity.Pos.X;
            double plrPosZ = capi.World.Player.Entity.Pos.Z;

            double offsetX = committedState.CenterTilePos.X * CloudTileSize - plrPosX + windOffsetX;
            double offsetZ = committedState.CenterTilePos.Z * CloudTileSize - plrPosZ + windOffsetZ;


            prog.Uniform("sunColor", capi.World.Calendar.SunColor);
            prog.Uniform("dayLight", Math.Max(0, capi.World.Calendar.DayLightStrength - capi.World.Calendar.MoonLightStrength * 0.95f));
            prog.Uniform("windOffset", new Vec3f((float)offsetX, 0, (float)offsetZ));



            prog.Uniform("rgbaFogIn", capi.Ambient.BlendedFogColor);
            prog.Uniform("fogMinIn", capi.Ambient.BlendedFogMin);
            prog.Uniform("fogDensityIn", capi.Ambient.BlendedFogDensity);
            prog.Uniform("playerPos", capi.Render.ShaderUniforms.PlayerPos);
            prog.Uniform("tileOffset", new Vec2f((committedState.CenterTilePos.X - committedState.TileOffsetX) * CloudTileSize, (committedState.CenterTilePos.Z - committedState.TileOffsetZ) * CloudTileSize));

            prog.Uniform("cloudTileSize", CloudTileSize);
            prog.Uniform("cloudsLength", (float)CloudTileSize * CloudTileLength);

            prog.Uniform("globalCloudBrightness", blendedGlobalCloudBrightness);

            float yTranslate = (float)(weatherSys.CloudsYPosition * capi.World.BlockAccessor.MapSizeY + 0.5 - capi.World.Player.Entity.CameraPos.Y);

            prog.Uniform("cloudYTranslate", yTranslate);
            prog.Uniform("cloudCounter", (float)((capi.World.Calendar.TotalHours * 20) % 578f));

            prog.UniformMatrix("projectionMatrix", capi.Render.CurrentProjectionMatrix);

            //int cnt = capi.Render.PointLightsCount;
            //prog.Uniform("pointLightQuantity", cnt);
            //shv.PointLightsArray(cnt, ScreenManager.Platform.PointLights3);
            //shv.PointLightColorsArray(cnt, ScreenManager.Platform.PointLightColors3);

            prog.Uniform("flatFogDensity", capi.Ambient.BlendedFlatFogDensity);
            prog.Uniform("flatFogStart", capi.Ambient.BlendedFlatFogYPosForShader);


            mvMat
            .Set(capi.Render.MvMatrix.Top)
            .FollowPlayer()
            .Translate(offsetX, yTranslate, offsetZ)
            ;


            prog.UniformMatrix("modelViewMatrix", mvMat.Values);
            capi.Render.RenderMeshInstanced(cloudTilesMeshRef, QuantityCloudTiles);


            // Very slightly rotate all the clouds so it looks better when they pass through blocks
            // Putting this line before translate = Clouds no longer centered around the player
            // Putting it after the translate = Clouds hop by a few pixels on every reload
            // Need to find a correct solution for this
            // Mat4.Rotate(mv, mv, 0.04f, new float[] { 0, 1, 0 });

            prog.Stop();
        }
Ejemplo n.º 4
0
        public void OnRenderFrame(float deltaTime, EnumRenderStage stage)
        {
            if (fallTime < -1)
            {
                capi.Event.UnregisterRenderer(this, stage);
                Dispose();
                return;
            }

            float percent = fallTime / startFallTime;

            IRenderAPI rpi    = capi.Render;
            Vec3d      camPos = capi.World.Player.Entity.CameraPos;

            if (isLeaves)
            {
                rpi.GlDisableCullFace();
            }

            rpi.GlToggleBlend(true);

            bool shadowPass = stage != EnumRenderStage.Opaque;

            IShaderProgram prevProg = rpi.CurrentActiveShader;

            prevProg?.Stop();

            IShaderProgram sProg = shadowPass ? rpi.GetEngineShader(EnumShaderProgram.Shadowmapentityanimated) : rpi.PreparedStandardShader(pos.X, pos.Y, pos.Z);

            var mat = ModelMat
                      .Identity()
                      .Translate(pos.X - camPos.X, pos.Y - camPos.Y, pos.Z - camPos.Z)
            ;

            switch (fallDirection.Code)
            {
            case "north":
                mat.RotateXDeg(GameMath.Max(percent * 90.0f - 90.0f, -90.0f));
                break;

            case "south":
                mat.Translate(0, 0, 1);
                mat.RotateXDeg(GameMath.Min(percent * -90.0f + 90.0f, 90.0f));
                mat.Translate(0, 0, -1);
                break;

            case "east":
                mat.Translate(1, 0, 1);
                mat.RotateZDeg(GameMath.Max(percent * 90.0f - 90.0f, -90.0f));
                mat.Translate(-1, 0, -1);
                break;

            case "west":
                mat.Translate(0, 0, 1);
                mat.RotateZDeg(GameMath.Min(percent * -90.0f + 90.0f, 90.0f));
                mat.Translate(0, 0, -1);
                break;

            default:
                break;
            }

            var matVals = mat.Values;

            if (!shadowPass)
            {
                var prog = (IStandardShaderProgram)sProg;

                prog.Tex2D       = capi.BlockTextureAtlas.AtlasTextureIds[0];
                prog.ModelMatrix = matVals;

                prog.AlphaTest = 0.4f;

                prog.ViewMatrix       = rpi.CameraMatrixOriginf;
                prog.ProjectionMatrix = rpi.CurrentProjectionMatrix;
                if (fallTime < 0)
                {
                    prog.RgbaTint = new Vec4f(1, 1, 1, 1.0f - Math.Abs(fallTime));
                }
            }
            else
            {
                sProg.Use();
                sProg.BindTexture2D("entityTex", capi.BlockTextureAtlas.AtlasTextureIds[0], 1);
                sProg.UniformMatrix("projectionMatrix", rpi.CurrentProjectionMatrix);
                sProg.UniformMatrix("modelViewMatrix", Mat4f.Mul(new float[16], capi.Render.CurrentModelviewMatrix, matVals));
            }

            rpi.RenderMesh(treeMesh);
            sProg.Stop();

            prevProg?.Use();

            fallTime -= deltaTime;
        }
Ejemplo n.º 5
0
        public void OnRenderFrame(float deltaTime, EnumRenderStage stage)
        {
            var plrPos = capi.World.Player.Entity.Pos;
            var bh     = capi.World.Player.Entity.GetBehavior <EntityBehaviorTemporalStabilityAffected>();

            if (bh != null)
            {
                bh.stabilityOffset = 0;
            }

            if (modsys.nearestRifts.Length > 0)
            {
                Rift rift = modsys.nearestRifts[0];

                float dist   = Math.Max(0, GameMath.Sqrt(plrPos.SquareDistanceTo(rift.Position)) - 1 - rift.Size / 2f);
                float f      = Math.Max(0, 1 - dist / 3f);
                float jitter = capi.World.Rand.NextDouble() < 0.25 ? f * ((float)capi.World.Rand.NextDouble() - 0.5f) / 1f : 0;

                GlobalConstants.GuiGearRotJitter = jitter;

                capi.ModLoader.GetModSystem <SystemTemporalStability>().modGlitchStrength = Math.Min(1, f * 1.3f);

                if (bh != null)
                {
                    bh.stabilityOffset = -Math.Pow(Math.Max(0, 1 - dist / 3), 2) * 20;
                }
            }
            else
            {
                capi.ModLoader.GetModSystem <SystemTemporalStability>().modGlitchStrength = 0;
            }

            counter += deltaTime;
            if (capi.World.Rand.NextDouble() < 0.012)
            {
                counter += 20 * (float)capi.World.Rand.NextDouble();
            }

            capi.Render.GLDepthMask(false);

            prog.Use();
            prog.BindTexture2D("primaryFb", capi.Render.FrameBuffers[(int)EnumFrameBuffer.Primary].ColorTextureIds[0], 0);
            prog.BindTexture2D("depthTex", capi.Render.FrameBuffers[(int)EnumFrameBuffer.Primary].DepthTextureId, 1);
            prog.UniformMatrix("projectionMatrix", capi.Render.CurrentProjectionMatrix);


            int width  = capi.Render.FrameWidth;
            int height = capi.Render.FrameHeight;

            prog.Uniform("counter", counter);
            float bf = 200 + (float)GameMath.Sin(capi.InWorldEllapsedMilliseconds / 24000.0) * 100;

            prog.Uniform("counterSmooth", bf);
            prog.Uniform("invFrameSize", new Vec2f(1f / width, 1f / height));
            int riftIndex = 0;

            cnt = (cnt + 1) % 3;

            foreach (var rift in rifts)
            {
                if (cnt == 0)
                {
                    rift.Visible = capi.World.BlockAccessor.GetChunkAtBlockPos((int)rift.Position.X, (int)rift.Position.Y, (int)rift.Position.Z) != null;
                }

                riftIndex++;
                matrixf.Identity();

                float dx = (float)(rift.Position.X - plrPos.X);
                float dy = (float)(rift.Position.Y - plrPos.Y);
                float dz = (float)(rift.Position.Z - plrPos.Z);

                matrixf.Translate(dx, dy, dz);
                matrixf.ReverseMul(capi.Render.CameraMatrixOriginf);

                matrixf.Values[0] = 1f;
                matrixf.Values[1] = 0f;
                matrixf.Values[2] = 0f;

                //matrixf.Values[4] = 0f;
                //matrixf.Values[5] = 1f;
                //matrixf.Values[6] = 0f;

                matrixf.Values[8]  = 0f;
                matrixf.Values[9]  = 0f;
                matrixf.Values[10] = 1f;

                float size = rift.GetNowSize(capi);
                matrixf.Scale(size, size, size);

                prog.UniformMatrix("modelViewMatrix", matrixf.Values);
                prog.Uniform("riftIndex", riftIndex);

                capi.Render.RenderMesh(meshref);

                if (dx * dx + dy * dy + dz * dz < 40 * 40)
                {
                    Vec3d ppos = rift.Position;
                    capi.World.SpawnParticles(0.1f, ColorUtil.ColorFromRgba(21 / 2, 70 / 2, 116 / 2, 128), ppos, ppos, new Vec3f(-0.125f, -0.125f, -0.125f), new Vec3f(0.125f, 0.125f, 0.125f), 5, 0, (0.125f / 2 + (float)capi.World.Rand.NextDouble() * 0.25f) / 2);
                }
            }


            counter = GameMath.Mod(counter + deltaTime, GameMath.TWOPI * 100f);

            prog.Stop();

            capi.Render.GLDepthMask(true);
        }
Ejemplo n.º 6
0
        public void OnRenderFrame(float deltaTime, EnumRenderStage stage)
        {
            capi.Render.GlMatrixModeModelView();

            if (!renderClouds || capi.Render.FrameWidth == 0)
            {
                return;
            }



            prog.Use();
            prog.Uniform("sunPosition", capi.World.Calendar.SunPositionNormalized);

            int[] hsv = ColorUtil.RgbToHsvInts((int)(capi.World.Calendar.SunColor.R * 255), (int)(capi.World.Calendar.SunColor.G * 255), (int)(capi.World.Calendar.SunColor.B * 255));
            hsv[1] = (int)(hsv[1] * 0.9);
            hsv[2] = (int)(hsv[2] * 0.9);
            int[] rgba   = ColorUtil.Hsv2RgbInts(hsv[0], hsv[1], hsv[2]);
            Vec3f sunCol = new Vec3f(rgba[0] / 255f, rgba[1] / 255f, rgba[2] / 255f);

            prog.Uniform("sunColor", sunCol);
            prog.Uniform("dayLight", Math.Max(0, capi.World.Calendar.DayLightStrength + capi.World.Calendar.MoonLightStrength - 0.15f));
            prog.Uniform("windOffset", new Vec3f(
                             (float)(GameMath.Mod((float)capi.World.Player.Entity.Pos.X, CloudTileSize)),
                             0,
                             (float)(GameMath.Mod((float)capi.World.Player.Entity.Pos.Z, CloudTileSize))
                             ));
            prog.Uniform("globalCloudBrightness", blendedGlobalCloudBrightness);
            prog.Uniform("rgbaFogIn", capi.Ambient.BlendedFogColor);
            prog.Uniform("fogMinIn", capi.Ambient.BlendedFogMin);
            prog.Uniform("fogDensityIn", capi.Ambient.BlendedFogDensity);
            prog.Uniform("playerPos", capi.World.Player.Entity.Pos.XYZFloat);

            prog.Uniform("cloudTileSize", CloudTileSize);
            prog.Uniform("cloudsLength", (float)CloudTileSize * CloudTileLength);

            prog.UniformMatrix("projectionMatrix", capi.Render.CurrentProjectionMatrix);

            //int cnt = capi.Render.PointLightsCount;
            //prog.Uniform("pointLightQuantity", cnt);
            //shv.PointLightsArray(cnt, ScreenManager.Platform.PointLights3);
            //shv.PointLightColorsArray(cnt, ScreenManager.Platform.PointLightColors3);

            prog.Uniform("flatFogDensity", capi.Ambient.BlendedFlatFogDensity);
            prog.Uniform("flatFogStart", capi.Ambient.BlendedFlatFogYPosForShader);



            capi.Render.GlPushMatrix();
            {
                double[] mvMatd = capi.Render.MvMatrix.Top;
                mvMatd[12] = 0;
                mvMatd[13] = 0;
                mvMatd[14] = 0;

                double partialTileOffsetX = capi.World.Player.Entity.Pos.X % CloudTileSize;
                double partialTileOffsetZ = capi.World.Player.Entity.Pos.Z % CloudTileSize;

                Mat4d.Translate(mvMatd, mvMatd, new double[] {
                    windOffsetX - partialTileOffsetX,
                    (int)(0.8627 * capi.World.BlockAccessor.MapSizeY) + 0.5 - capi.World.Player.Entity.Pos.Y,
                    windOffsetZ - partialTileOffsetZ
                });

                // Basic model view matrix
                float[] mvMatf = new float[16];
                for (int i = 0; i < 16; i++)
                {
                    mvMatf[i] = (float)mvMatd[i];
                }

                prog.UniformMatrix("modelViewMatrix", mvMatf);
                capi.Render.RenderMeshInstanced(cloudTilesMeshRef, QuantityCloudTiles);
            }
            capi.Render.GlPopMatrix();


            // Very slightly rotate all the clouds so it looks better when they pass through blocks

            // Putting this line before translate = Clouds no longer centered around the player
            // Putting it after the translate = Clouds hop by a few pixels on every reload
            // Need to find a correct solution for this
            // Mat4.Rotate(mv, mv, 0.04f, new float[] { 0, 1, 0 });


            prog.Stop();
        }
Ejemplo n.º 7
0
        public void OnRenderFrame(float dt, EnumRenderStage stage)
        {
            if (!ShouldRender)
            {
                return;
            }

            animator.OnFrame(activeAnimationsByAnimCode, dt);

            EntityPlayer entityPlayer = capi.World.Player.Entity;

            Mat4f.Identity(ModelMat);
            Mat4f.Translate(ModelMat, ModelMat, (float)(pos.X - entityPlayer.CameraPos.X), (float)(pos.Y - entityPlayer.CameraPos.Y), (float)(pos.Z - entityPlayer.CameraPos.Z));

            Mat4f.Translate(ModelMat, ModelMat, 0.5f, 0, 0.5f);
            Mat4f.RotateY(ModelMat, ModelMat, rotation.Y * GameMath.DEG2RAD);
            Mat4f.Translate(ModelMat, ModelMat, -0.5f, 0, -0.5f);

            IRenderAPI rpi = capi.Render;


            IShaderProgram prevProg = rpi.CurrentActiveShader;

            prevProg?.Stop();


            IShaderProgram prog = rpi.GetEngineShader(EnumShaderProgram.Entityanimated);

            prog.Use();

            prog.Uniform("rgbaAmbientIn", rpi.AmbientColor);
            prog.Uniform("rgbaFogIn", rpi.FogColor);
            prog.Uniform("fogMinIn", rpi.FogMin);
            prog.Uniform("fogDensityIn", rpi.FogDensity);
            prog.BindTexture2D("entityTex", textureId, 0);
            prog.Uniform("alphaTest", 0.1f);
            prog.UniformMatrix("projectionMatrix", rpi.CurrentProjectionMatrix);


            rpi.GlToggleBlend(true, EnumBlendMode.Standard);


            Vec4f lightrgbs = capi.World.BlockAccessor.GetLightRGBs((int)pos.X, (int)pos.Y, (int)pos.Z);

            prog.Uniform("rgbaLightIn", lightrgbs);
            //prog.Uniform("extraGlow", entity.Properties.Client.GlowLevel);
            prog.UniformMatrix("modelMatrix", ModelMat);
            prog.UniformMatrix("viewMatrix", rpi.CameraMatrixOriginf);
            prog.Uniform("addRenderFlags", 0);
            prog.Uniform("windWaveIntensity", (float)0);

            /*color[0] = (entity.RenderColor >> 16 & 0xff) / 255f;
             * color[1] = ((entity.RenderColor >> 8) & 0xff) / 255f;
             * color[2] = ((entity.RenderColor >> 0) & 0xff) / 255f;
             * color[3] = ((entity.RenderColor >> 24) & 0xff) / 255f;
             *
             * prog.Uniform("renderColor", color);*/

            prog.Uniform("renderColor", ColorUtil.WhiteArgbVec);


            prog.UniformMatrices(
                "elementTransforms",
                GlobalConstants.MaxAnimatedElements,
                animator.Matrices
                );

            capi.Render.RenderMesh(meshref);

            prog.Stop();
            prevProg?.Use();
        }
Ejemplo n.º 8
0
        public void OnRenderFrame(float deltaTime, EnumRenderStage stage)
        {
            if (!renderAurora)
            {
                return;
            }

            if (capi.Render.FrameWidth == 0)
            {
                return;
            }



            quarterSecAccum += deltaTime;
            if (quarterSecAccum > 0.25f)
            {
                plrPos.X = (int)capi.World.Player.Entity.CameraPos.X;
                plrPos.Y = capi.World.SeaLevel;
                plrPos.Z = (int)capi.World.Player.Entity.CameraPos.Z;

                clientClimateCond = capi.World.BlockAccessor.GetClimateAt(plrPos);
                quarterSecAccum   = 0;
            }

            if (clientClimateCond == null)
            {
                return;
            }

            float tempfac = GameMath.Clamp((Math.Max(0, -clientClimateCond.Temperature) - 5) / 15f, 0, 1);

            col.W = GameMath.Clamp(1 - 1.5f * capi.World.Calendar.DayLightStrength, 0, 1) * tempfac;

            if (col.W <= 0)
            {
                return;
            }

            prog.Use();
            prog.Uniform("color", col);
            prog.Uniform("rgbaFogIn", capi.Ambient.BlendedFogColor);
            prog.Uniform("fogMinIn", capi.Ambient.BlendedFogMin);
            prog.Uniform("fogDensityIn", capi.Ambient.BlendedFogDensity);
            prog.UniformMatrix("projectionMatrix", capi.Render.CurrentProjectionMatrix);

            prog.Uniform("flatFogDensity", capi.Ambient.BlendedFlatFogDensity);
            prog.Uniform("flatFogStart", capi.Ambient.BlendedFlatFogYPosForShader);

            float speedmul = capi.World.Calendar.SpeedOfTime / 60f;

            prog.Uniform("auroraCounter", (float)(capi.InWorldEllapsedMilliseconds / 4000.0 * speedmul) % 579f);


            mvMat
            .Set(capi.Render.MvMatrix.Top)
            .FollowPlayer()
            .Translate(
                0, //    capi.World.BlockAccessor.MapSizeX/2,
                (1.1f * capi.World.BlockAccessor.MapSizeY + 0.5 - capi.World.Player.Entity.CameraPos.Y),
                0  //   capi.World.BlockAccessor.MapSizeZ/2
                )
            ;

            prog.UniformMatrix("modelViewMatrix", mvMat.Values);
            capi.Render.RenderMesh(quadTilesRef);

            prog.Stop();
        }
        public void OnRenderFrame(float dt, EnumRenderStage stage)
        {
            if (stage == EnumRenderStage.Opaque)
            {
                prog.Use();
                prog.UniformMatrix("projection", capi.Render.CurrentProjectionMatrix);
                prog.UniformMatrix("view", capi.Render.CameraMatrixOriginf);

                for (int i = 0; i < lightningFlashes.Count; i++)
                {
                    var lflash = lightningFlashes[i];
                    lflash.Render(dt);

                    if (!lflash.Alive)
                    {
                        lflash.Dispose();
                        lightningFlashes.RemoveAt(i);
                        i--;
                    }
                }

                prog.Stop();
                return;
            }

            if (stage == EnumRenderStage.Done)
            {
                AmbientModifier sunGlowAmb = capi.Ambient.CurrentModifiers["sunglow"];
                actualSunGlowAmb.FogColor.Weight = sunGlowAmb.FogColor.Weight;

                dt = Math.Min(0.5f, dt);

                if (nearLightningCoolDown > 0)
                {
                    nearLightningCoolDown -= dt;
                }

                return;
            }

            if (lightningTime > 0)
            {
                float mul = Math.Min(10 * lightningIntensity * lightningTime, 1.5f);

                WeatherDataSnapshot weatherData = weatherSysc.BlendedWeatherData;

                LightningAmbient.CloudBrightness.Value = Math.Max(weatherData.Ambient.SceneBrightness.Value, mul);
                LightningAmbient.FogBrightness.Value   = Math.Max(weatherData.Ambient.FogBrightness.Value, mul);

                LightningAmbient.CloudBrightness.Weight = Math.Min(1, mul);
                LightningAmbient.FogBrightness.Weight   = Math.Min(1, mul);

                float sceneBrightIncrease = GameMath.Min(mul, GameMath.Max(0, lightningIntensity - 0.75f));

                if (sceneBrightIncrease > 0)
                {
                    LightningAmbient.SceneBrightness.Weight = Math.Min(1, sceneBrightIncrease);
                    LightningAmbient.SceneBrightness.Value  = 1;

                    AmbientModifier sunGlowAmb = capi.Ambient.CurrentModifiers["sunglow"];

                    float nowWeight = GameMath.Clamp(1 - sceneBrightIncrease, 0, 1);

                    sunGlowAmb.FogColor.Weight     = Math.Min(sunGlowAmb.FogColor.Weight, nowWeight);
                    sunGlowAmb.AmbientColor.Weight = Math.Min(sunGlowAmb.AmbientColor.Weight, nowWeight);
                }


                lightningTime -= dt / 1.7f;

                if (lightningTime <= 0)
                {
                    // Restore previous values
                    AmbientModifier sunGlowAmb = capi.Ambient.CurrentModifiers["sunglow"];
                    sunGlowAmb.FogColor.Weight     = actualSunGlowAmb.FogColor.Weight;
                    sunGlowAmb.AmbientColor.Weight = actualSunGlowAmb.AmbientColor.Weight;

                    LightningAmbient.CloudBrightness.Weight = 0;
                    LightningAmbient.FogBrightness.Weight   = 0;
                    LightningAmbient.SceneBrightness.Weight = 0;
                }
            }
        }