예제 #1
0
파일: Atmosphere.cs 프로젝트: dzamkov/L2D
 public AtmosphereVisualComponent(Path ShaderPath, AtmosphereOptions Options, AtmosphereQualityOptions QualityOptions)
 {
     Shader.PrecompilerInput pci = Shader.CreatePrecompilerInput();
     this._Atmosphere = Atmosphere.Generate(Options, QualityOptions, pci, ShaderPath);
     Path atmosphere = ShaderPath["Atmosphere"];
     Atmosphere.DefineConstants(Options, QualityOptions, pci);
     this._Main = Shader.Load(atmosphere["Planet.glsl"], pci);
     this._Radius = Options.RadiusGround;
 }
예제 #2
0
파일: Atmosphere.cs 프로젝트: dzamkov/L2D
        /// <summary>
        /// Creates a precomputed atmosphere using shaders and the graphics card.
        /// </summary>
        public static PrecomputedAtmosphere Generate(
            AtmosphereOptions Options,
            AtmosphereQualityOptions QualityOptions,
            Shader.PrecompilerInput PrecompilerInitial,
            Path ShaderPath)
        {
            PrecomputedAtmosphere pa = new PrecomputedAtmosphere();
            Shader.PrecompilerInput pci = PrecompilerInitial.Copy();
            DefineConstants(Options, QualityOptions, pci);

            Path atmosphere = ShaderPath["Atmosphere"];
            Path precompute = atmosphere["Precompute"];

            // Load shaders.
            Shader.PrecompilerInput transmittancepci = pci.Copy();
            Shader transmittance = Shader.Load(precompute["Transmittance.glsl"], transmittancepci);

            Shader.PrecompilerInput irradianceinitialdeltapci = pci.Copy();
            irradianceinitialdeltapci.Define("INITIAL");
            irradianceinitialdeltapci.Define("DELTA");
            Shader irradianceinitialdelta = Shader.Load(precompute["Irradiance.glsl"], irradianceinitialdeltapci);

            Shader.PrecompilerInput irradianceinitialpci = pci.Copy();
            irradianceinitialpci.Define("INITIAL");
            Shader irradianceinitial = Shader.Load(precompute["Irradiance.glsl"], irradianceinitialpci);

            Shader.PrecompilerInput irradiancedeltapci = pci.Copy();
            irradiancedeltapci.Define("DELTA");
            Shader irradiancedelta = Shader.Load(precompute["Irradiance.glsl"], irradiancedeltapci);

            Shader.PrecompilerInput irradiancepci = pci.Copy();
            Shader irradiance = Shader.Load(precompute["Irradiance.glsl"], irradiancepci);

            Shader.PrecompilerInput inscatterinitialdeltapci = pci.Copy();
            inscatterinitialdeltapci.Define("INITIAL");
            inscatterinitialdeltapci.Define("DELTA");
            Shader inscatterinitialdelta = Shader.Load(precompute["Inscatter.glsl"], inscatterinitialdeltapci);

            Shader.PrecompilerInput inscatterinitialpci = pci.Copy();
            inscatterinitialpci.Define("INITIAL");
            Shader inscatterinitial = Shader.Load(precompute["Inscatter.glsl"], inscatterinitialpci);

            Shader.PrecompilerInput inscatterdeltapci = pci.Copy();
            inscatterdeltapci.Define("DELTA");
            Shader inscatterdelta = Shader.Load(precompute["Inscatter.glsl"], inscatterdeltapci);

            Shader.PrecompilerInput inscatterpci = pci.Copy();
            Shader inscatter = Shader.Load(precompute["Inscatter.glsl"], inscatterpci);

            Shader.PrecompilerInput pointscatterpci = pci.Copy();
            Shader pointscatter = Shader.Load(precompute["PointScatter.glsl"], pointscatterpci);

            // Initialize textures
            int transwidth = QualityOptions.TransmittanceResMu;
            int transheight = QualityOptions.TransmittanceResR;
            int irrwidth = QualityOptions.IrradianceResMu;
            int irrheight = QualityOptions.IrradianceResR;
            int atwidth = QualityOptions.AtmosphereResMuS * QualityOptions.AtmosphereResNu;
            int atheight = QualityOptions.AtmosphereResMu;
            int atdepth = QualityOptions.AtmosphereResR;
            pa.Transmittance = Texture.Initialize2D(transwidth, transheight, Texture.RGB16Float);
            pa.Irradiance = Texture.Initialize2D(irrwidth, irrheight, Texture.RGB16Float);
            pa.Inscatter = Texture.Initialize3D(atwidth, atheight, atdepth, Texture.RGBA16Float);
            Texture irrdelta = Texture.Initialize2D(irrwidth, irrheight, Texture.RGB16Float);
            Texture insdelta = Texture.Initialize3D(atwidth, atheight, atdepth, Texture.RGB16Float);
            Texture ptsdelta = Texture.Initialize3D(atwidth, atheight, atdepth, Texture.RGB16Float);

            pa.Transmittance.SetUnit(TextureTarget.Texture2D, TextureUnit.Texture0);
            pa.Inscatter.SetUnit(TextureTarget.Texture3D, TextureUnit.Texture2);
            irrdelta.SetUnit(TextureTarget.Texture2D, TextureUnit.Texture3);
            insdelta.SetUnit(TextureTarget.Texture3D, TextureUnit.Texture4);
            ptsdelta.SetUnit(TextureTarget.Texture3D, TextureUnit.Texture5);

            uint fbo;
            GL.GenFramebuffers(1, out fbo);
            GL.BindFramebuffer(FramebufferTarget.FramebufferExt, fbo);
            GL.ReadBuffer(ReadBufferMode.ColorAttachment0);
            GL.DrawBuffer(DrawBufferMode.ColorAttachment0);

            // Create transmittance texture (information about how light is filtered through the atmosphere).
            transmittance.Call();
            transmittance.Draw2DFrame(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext,
                pa.Transmittance.ID, transwidth, transheight);

            // Create delta irradiance texture (ground lighting cause by sun).
            irradianceinitialdelta.Call();
            irradianceinitialdelta.SetUniform("Transmittance", TextureUnit.Texture0);
            irradianceinitialdelta.Draw2DFrame(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext,
                irrdelta.ID, irrwidth, irrheight);

            // Create initial inscatter texture (light from atmosphere from sun, rayleigh and mie parts seperated for precision).
            inscatterinitial.Call();
            inscatterinitial.SetUniform("Transmittance", TextureUnit.Texture0);
            inscatterinitial.Draw3DFrame(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext,
                pa.Inscatter.ID, atwidth, atheight, atdepth);

            // Initialize irradiance to zero (ground lighting caused by atmosphere).
            irradianceinitial.Call();
            irradianceinitial.Draw2DFrame(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext,
                pa.Irradiance.ID, irrwidth, irrheight);

            // Copy inscatter to delta inscatter, combining rayleigh and mie parts.
            inscatterinitialdelta.Call();
            inscatterinitialdelta.SetUniform("Inscatter", TextureUnit.Texture2);
            inscatterinitialdelta.Draw3DFrame(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext,
                insdelta.ID, atwidth, atheight, atdepth);

            for (int t = 2; t <= QualityOptions.MultipleScatteringOrder; t++)
            {
                // Generate point scattering information
                // Note that this texture will likely be very dark because it contains data for a single point, as opposed to a long line.
                pointscatter.Call();
                pointscatter.SetUniform("IrradianceDelta", TextureUnit.Texture3);
                pointscatter.SetUniform("InscatterDelta", TextureUnit.Texture4);
                pointscatter.Draw3DFrame(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext,
                    ptsdelta.ID, atwidth, atheight, atdepth);

                // Compute new irradiance delta using current inscatter delta.
                irradiancedelta.Call();
                irradiancedelta.SetUniform("InscatterDelta", TextureUnit.Texture4);
                irradiancedelta.Draw2DFrame(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext,
                    irrdelta.ID, irrwidth, irrheight);

                // Compute new inscatter delta using pointscatter data.
                inscatterdelta.Call();
                inscatterdelta.SetUniform("Transmittance", TextureUnit.Texture0);
                inscatterdelta.SetUniform("PointScatter", TextureUnit.Texture5);
                inscatterdelta.Draw3DFrame(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext,
                    insdelta.ID, atwidth, atheight, atdepth);

                GL.Enable(EnableCap.Blend);
                GL.BlendEquation(BlendEquationMode.FuncAdd);
                GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.One);

                // Add irradiance delta to irradiance.
                irradiance.Call();
                irradiance.SetUniform("IrradianceDelta", TextureUnit.Texture3);
                irradiance.Draw2DFrame(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext,
                    pa.Irradiance.ID, irrwidth, irrheight);

                // Add inscatter delta to inscatter.
                inscatter.Call();
                inscatter.SetUniform("InscatterDelta", TextureUnit.Texture4);
                inscatter.Draw3DFrame(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext,
                    pa.Inscatter.ID, atwidth, atheight, atdepth);

                GL.Disable(EnableCap.Blend);
            }

            insdelta.Delete();
            irrdelta.Delete();
            ptsdelta.Delete();

            GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);
            GL.Finish();
            GL.DeleteFramebuffers(1, ref fbo);

            return pa;
        }