示例#1
0
        protected unsafe override void DoInitialize()
        {
            base.DoInitialize();
            // pbr: generate a 2D LUT from the BRDF equations used.
            // then re-configure capture framebuffer object and render screen-space quad with BRDF shader.
            // pbr: setup framebuffer
            var captureFBO = new Framebuffer(512, 512);

            captureFBO.Bind();
            var captureRBO = new Renderbuffer(512, 512, GL.GL_DEPTH_COMPONENT24);

            captureFBO.Attach(FramebufferTarget.Framebuffer, captureRBO, AttachmentLocation.Depth);
            captureFBO.Attach(FramebufferTarget.Framebuffer, this.texBRDF, 0u);
            captureFBO.CheckCompleteness();
            captureFBO.Unbind();

            RenderMethod   method         = this.RenderUnit.Methods[0];
            ViewportSwitch viewportSwitch = new ViewportSwitch(0, 0, 512, 512);

            viewportSwitch.On();
            captureFBO.Bind();
            GL.Instance.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
            method.Render();
            captureFBO.Unbind();
            viewportSwitch.Off();
            captureFBO.Dispose();

            this.texBRDF.GetImage(512, 512).Save(string.Format("texBRDF.png"));
        }
示例#2
0
        protected unsafe override void DoInitialize()
        {
            base.DoInitialize();
            // pbr: run a quasi monte-carlo simulation on the environment lighting to create a prefilter (cube)map.
            const uint maxMipLevels = 5;
            var        viewport     = new ViewportSwitch();

            for (int mip = 0; mip < maxMipLevels; ++mip)
            {
                // reisze framebuffer according to mip-level size.
                int mipWidth   = (int)(128 * Math.Pow(0.5, mip));
                int mipHeight  = (int)(128 * Math.Pow(0.5, mip));
                var captureFBO = new Framebuffer(mipWidth, mipHeight);
                captureFBO.Bind();
                var captureRBO = new Renderbuffer(mipWidth, mipHeight, GL.GL_DEPTH_COMPONENT24);
                captureFBO.Attach(FramebufferTarget.Framebuffer, captureRBO, AttachmentLocation.Depth);
                captureFBO.CheckCompleteness();
                captureFBO.Unbind();
                viewport.Width = mipWidth; viewport.Height = mipHeight;
                viewport.On();
                // NOTE: I added '/ 10' to make it a clearer visual effect.
                float         roughness = (float)mip / (float)(maxMipLevels - 1) / 5;
                RenderMethod  method    = this.RenderUnit.Methods[0];
                ShaderProgram program   = method.Program;
                program.SetUniform("roughness", roughness);
                program.SetUniform("projection", captureProjection);
                program.SetUniform("environmentMap", this.envCubemap);
                for (uint i = 0; i < 6; ++i)
                {
                    program.SetUniform("view", captureViews[i]);
                    CubemapFace face     = (CubemapFace)(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i);
                    uint        location = 0;
                    //int level = 0;
                    captureFBO.Bind();
                    captureFBO.Attach(FramebufferTarget.Framebuffer, location, face, this.prefilterMap, mip);
                    captureFBO.CheckCompleteness();
                    captureFBO.Unbind();

                    captureFBO.Bind();
                    GL.Instance.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
                    method.Render();
                    captureFBO.Unbind();

                    this.prefilterMap.GetImage(face, mipWidth, mipHeight, mip).Save(string.Format("prefilter.{0}.mip{1}.png", face, mip));
                }

                viewport.Off();
                captureFBO.Dispose();
            }
        }
示例#3
0
        protected unsafe override void DoInitialize()
        {
            base.DoInitialize();
            ViewportSwitch viewportSwitch = new ViewportSwitch(0, 0, 512, 512);
            // pbr: setup framebuffer
            var captureFBO = new Framebuffer(512, 512);

            captureFBO.Bind();
            var captureRBO = new Renderbuffer(512, 512, GL.GL_DEPTH_COMPONENT24);

            captureFBO.Attach(FramebufferTarget.Framebuffer, captureRBO, AttachmentLocation.Depth);
            captureFBO.CheckCompleteness();
            captureFBO.Unbind();

            // pbr: convert HDR equirectangular environment map to cubemap equivalent
            RenderMethod  method  = this.RenderUnit.Methods[0];
            ShaderProgram program = method.Program;

            program.SetUniform("equirectangularMap", this.texHDR);
            program.SetUniform("projection", captureProjection);
            viewportSwitch.On();
            for (uint i = 0; i < 6; ++i)
            {
                program.SetUniform("view", captureViews[i]);
                CubemapFace face     = (CubemapFace)(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i);
                uint        location = 0;
                int         level    = 0;
                captureFBO.Bind();
                captureFBO.Attach(FramebufferTarget.Framebuffer, location, face, this.environmentMap, level);
                captureFBO.CheckCompleteness();
                captureFBO.Unbind();

                captureFBO.Bind();
                GL.Instance.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
                method.Render();
                captureFBO.Unbind();

                this.environmentMap.GetImage(face, 512, 512).Save(string.Format("texEnvCubemap.{0}.mip{1}.png", face, 0));
            }
            viewportSwitch.Off();
            captureFBO.Dispose();

            this.environmentMap.Bind();
            glGenerateMipmap(GL.GL_TEXTURE_CUBE_MAP);
            this.environmentMap.Unbind();
        }
示例#4
0
        protected override void DoInitialize()
        {
            // init textures.
            this.envCubeMap     = LoadEnvCubeMap();
            this.irradianceMap  = LoadIrradianceMap();
            this.prefliterMap   = LoadPrefliterMap();
            this.brdfLUTTexture = LoadBRDFTexture();
            //this.hdrTexture = LoadHdrEnvironmentMap(@"Texture\hdr\newport_loft.hdr");
            this.hdrTexture = LoadHDRTexture(@"Texture\hdr\newport_loft.hdr");
            //{
            //    Bitmap bitmap = LoadHdrFormFreeImage(@"Texture\hdr\newport_loft.hdr");
            //    var storage = new TexImageBitmap(bitmap, GL.GL_RGB16F);
            //    var texture = new Texture(storage,
            //        new TexParameteri(TexParameter.PropertyName.TextureWrapS, (int)GL.GL_CLAMP_TO_EDGE),
            //        new TexParameteri(TexParameter.PropertyName.TextureWrapT, (int)GL.GL_CLAMP_TO_EDGE),
            //        new TexParameteri(TexParameter.PropertyName.TextureMinFilter, (int)GL.GL_LINEAR),
            //        new TexParameteri(TexParameter.PropertyName.TextureMagFilter, (int)GL.GL_LINEAR));
            //    texture.Initialize();
            //    this.hdrTexture = texture;
            //}

            this.albedoMap = LoadTexture(@"Texture\agedplanks1-albedo.png");
            this.albedoMap.TextureUnitIndex = 3;
            this.normalMap = LoadTexture(@"Texture\agedplanks1-normal4-ue.png");
            this.normalMap.TextureUnitIndex = 4;
            this.metallicMap = LoadTexture(@"Texture\agedplanks1-ao.png");
            this.metallicMap.TextureUnitIndex = 5;
            this.roughnessMap = LoadTexture(@"Texture\agedplanks1-roughness.png");
            this.roughnessMap.TextureUnitIndex = 6;
            this.aoMap = LoadTexture(@"Texture\agedplanks1-ao.png");
            this.aoMap.TextureUnitIndex = 7;

            this.pbrProgram.SetUniform("albedoMap", this.albedoMap);
            this.pbrProgram.SetUniform("normalMap", this.normalMap);
            this.pbrProgram.SetUniform("metallicMap", this.metallicMap);
            this.pbrProgram.SetUniform("roughnessMap", this.roughnessMap);
            this.pbrProgram.SetUniform("aoMap", this.aoMap);

            //设置投影矩阵
            mat4 captureProjection = glm.perspective((float)(Math.PI / 2), 1.0f, 0.1f, 20.0f);

            mat4[] captureView =
            {
                glm.lookAt(new vec3(0, 0, 0), new vec3(1.0f,   0.0f,  0.0f), new vec3(0.0f, -1.0f,  0.0f)),
                glm.lookAt(new vec3(0, 0, 0), new vec3(-1.0f,  0.0f,  0.0f), new vec3(0.0f, -1.0f,  0.0f)),
                glm.lookAt(new vec3(0, 0, 0), new vec3(0.0f,   1.0f,  0.0f), new vec3(0.0f,  0.0f,  1.0f)),
                glm.lookAt(new vec3(0, 0, 0), new vec3(0.0f,  -1.0f,  0.0f), new vec3(0.0f,  0.0f, -1.0f)),
                glm.lookAt(new vec3(0, 0, 0), new vec3(0.0f,   0.0f,  1.0f), new vec3(0.0f, -1.0f,  0.0f)),
                glm.lookAt(new vec3(0, 0, 0), new vec3(0.0f,   0.0f, -1.0f), new vec3(0.0f, -1.0f,  0.0f)),
            };

            ViewportSwitch viewportSwitch = new ViewportSwitch(0, 0, 512, 512);
            //转换HDR Equirectangular environmentMap 为 HDR cubeMap
            {
                //创建渲染到CubeMap的FBO
                var fbo = new Framebuffer(512, 512);
                fbo.Bind();
                var rbo = new Renderbuffer(512, 512, GL.GL_DEPTH_COMPONENT24);
                fbo.Attach(FramebufferTarget.Framebuffer, rbo, AttachmentLocation.Depth);
                fbo.CheckCompleteness();
                fbo.Unbind();

                viewportSwitch.On();
                ShaderProgram program = this.equiRectangular2CubemapProgram;
                program.SetUniform("equirectangularMap", this.hdrTexture);
                program.SetUniform("ProjMatrix", captureProjection);
                for (uint i = 0; i < 6; ++i)
                {
                    fbo.Bind();
                    CubemapFace face     = (CubemapFace)(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i);
                    uint        location = 0;
                    int         level    = 0;
                    fbo.Attach(FramebufferTarget.Framebuffer, location, face, envCubeMap, level);
                    fbo.CheckCompleteness();
                    fbo.Unbind();

                    fbo.Bind();
                    program.Bind();
                    program.SetUniform("ViewMatrix", captureView[i]);
                    program.PushUniforms();
                    GL.Instance.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
                    renderCube();
                    program.Unbind();
                    fbo.Unbind();

                    envCubeMap.GetImage(face, fbo.Width, fbo.Height).Save(
                        string.Format("envCubeMap.{0}.png", face));
                }
                viewportSwitch.Off();
                fbo.Dispose();
            }
            //创建一个irradianceMap
            {
                var fbo = new Framebuffer(irradianceMapLength, irradianceMapLength);
                fbo.Bind();
                var rbo = new Renderbuffer(irradianceMapLength, irradianceMapLength, GL.GL_DEPTH_COMPONENT24);
                fbo.Attach(FramebufferTarget.Framebuffer, rbo, AttachmentLocation.Depth);
                fbo.CheckCompleteness();
                fbo.Unbind();

                //pbr:通过卷积来创建一张irradianceMap来解决diffueIntegral
                viewportSwitch.Width = irradianceMapLength; viewportSwitch.Height = irradianceMapLength;
                viewportSwitch.On();
                ShaderProgram program = this.irradianceProgram;
                program.SetUniform("environmentMap", envCubeMap);
                program.SetUniform("ProjMatrix", captureProjection);
                for (uint i = 0; i < 6; ++i)
                {
                    fbo.Bind();
                    CubemapFace face     = (CubemapFace)(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i);
                    uint        location = 0;
                    int         level    = 0;
                    fbo.Attach(FramebufferTarget.Framebuffer, location, face, irradianceMap, level);
                    fbo.CheckCompleteness();
                    fbo.Unbind();

                    //vec3 color = System.Drawing.Color.SkyBlue.ToVec3();
                    vec3 color = System.Drawing.Color.Black.ToVec3();

                    fbo.Bind();
                    program.Bind();
                    program.SetUniform("ViewMatrix", captureView[i]);
                    program.PushUniforms();
                    GL.Instance.ClearColor(color.x, color.y, color.z, 1);
                    GL.Instance.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
                    renderCube();
                    program.Unbind();
                    fbo.Unbind();

                    irradianceMap.GetImage(face, fbo.Width, fbo.Height).Save(
                        string.Format("irradianceMap.fill.{0}.png", face));
                }
                viewportSwitch.Off();
                fbo.Dispose();
            }
            //对环境光用蒙特卡洛积分来创建一个prefliterMap贴图
            {
                ShaderProgram program = this.prefliterProgram;
                program.SetUniform("environmentMap", envCubeMap);
                program.SetUniform("ProjMatrix", captureProjection);
                const int maxMipLevels = 5;
                for (int level = 0; level < maxMipLevels; level++)
                {
                    int mipWidth  = (int)(128 * Math.Pow(0.5, level));
                    int mipHeight = (int)(128 * Math.Pow(0.5, level));
                    var fbo       = new Framebuffer(mipWidth, mipHeight);
                    fbo.Bind();
                    var rbo = new Renderbuffer(mipWidth, mipHeight, GL.GL_DEPTH_COMPONENT24);
                    fbo.Attach(FramebufferTarget.Framebuffer, rbo, AttachmentLocation.Depth);
                    fbo.CheckCompleteness();
                    fbo.Unbind();

                    viewportSwitch.Width = mipWidth; viewportSwitch.Height = mipHeight;
                    viewportSwitch.On();
                    float roughness = (float)level / (float)(maxMipLevels - 1);
                    program.SetUniform("roughness", roughness);
                    for (uint j = 0; j < 6; j++)
                    {
                        program.SetUniform("ViewMatrix", captureView[level]);

                        fbo.Bind();
                        CubemapFace face     = (CubemapFace)(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X + j);
                        uint        location = 0;
                        fbo.Attach(FramebufferTarget.Framebuffer, location, face, prefliterMap, level);
                        fbo.CheckCompleteness();
                        fbo.Unbind();

                        fbo.Bind();
                        program.Bind();
                        program.PushUniforms();
                        GL.Instance.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
                        renderCube();
                        program.Unbind();
                        fbo.Unbind();

                        prefliterMap.GetImage(face, fbo.Width, fbo.Height, level).Save(
                            string.Format("prefliterMap.{0}.{1}.png", level, face));
                    }
                    viewportSwitch.Off();
                    fbo.Dispose();
                }
                program.Unbind();
            }
            {
                var fbo = new Framebuffer(512, 512);
                fbo.Bind();
                var rbo = new Renderbuffer(512, 512, GL.GL_DEPTH_COMPONENT24);
                fbo.Attach(FramebufferTarget.Framebuffer, rbo, AttachmentLocation.Depth);
                fbo.Attach(FramebufferTarget.Framebuffer, brdfLUTTexture, 0u);
                fbo.CheckCompleteness();
                fbo.Unbind();

                fbo.Bind();
                viewportSwitch.Width = 512; viewportSwitch.Height = 512;
                viewportSwitch.On();
                ShaderProgram program = this.brdfProgram;
                program.Bind();
                program.PushUniforms();
                GL.Instance.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
                renderQuad();
                program.Unbind();
                viewportSwitch.Off();
                fbo.Unbind();
                fbo.Dispose();

                brdfLUTTexture.GetImage(fbo.Width, fbo.Height).Save(
                    string.Format("BRDF.GetImage.png"));
            }
        }