public static void CreateLightmapTexture(GLContext control, AglLightMap aglLightMap, EnvironmentGraphics environmentSettings, string name, GLTextureCube output) { var lightMapEnv = aglLightMap.LightAreas.FirstOrDefault(x => x.Settings.Name == name); if (lightMapEnv == null) { return; } //Force generate mipmaps to update the mip allocation so mips can be assigned. output.Bind(); GL.GenerateMipmap(GenerateMipmapTarget.TextureCubeMap); GL.BindTexture(TextureTarget.TextureCubeMap, 0); GL.Enable(EnableCap.TextureCubeMapSeamless); if (FilterLevel0 == null) { Init(output.Width); } int CUBE_SIZE = output.Width; FilterLevel0.Bind(); LoadCubemapLevel(control, CUBE_SIZE, 0, aglLightMap, environmentSettings, lightMapEnv, output.ID); FilterLevel0.Unbind(); FilterLevel1.Bind(); LoadCubemapLevel(control, CUBE_SIZE / 2, 1, aglLightMap, environmentSettings, lightMapEnv, output.ID); FilterLevel1.Unbind(); output.SaveDDS($"LIGHTMAP{name}.dds"); }
public void GenerateLightmap(GLContext control, EnvironmentGraphics env, string name) { GLTextureCube output = GLTextureCube.CreateEmptyCubemap( 32, PixelInternalFormat.Rgb32f, PixelFormat.Rgb, PixelType.Float, 2); //Allocate mip data. Need 2 seperate mip levels output.Bind(); output.MinFilter = TextureMinFilter.LinearMipmapLinear; output.MagFilter = TextureMagFilter.Linear; output.UpdateParameters(); output.GenerateMipmaps(); output.Unbind(); if (Lightmaps.ContainsKey(name)) { Lightmaps[name]?.Dispose(); } if (!Lightmaps.ContainsKey(name)) { Lightmaps.Add(name, output); } LightmapManager.CreateLightmapTexture(control, this, env, name, output); Lightmaps[name] = output; }
static void InitTextures() { CubeMapTextureID = GLTextureCubeArray.FromDDS(new DDS($"Resources\\CubemapHDR.dds")); DiffuseCubeTextureID = GLTextureCube.FromDDS( new DDS(new MemoryStream(Resources.CubemapLightmap)), new DDS(new MemoryStream(Resources.CubemapLightmapShadow))); SpecularCubeTextureID = GLTextureCube.CreateEmptyCubemap(32); LightingEngine.LightSettings.InitTextures(); DepthShadowCascadeTextureID = GLTexture2D.FromBitmap(Resources.white); ProjectionTextureID = GLTexture2D.FromBitmap(Resources.white); User1Texture = GLTexture2D.FromBitmap(Resources.white); //Adjust mip levels CubeMapTextureID.Bind(); GL.TexParameter(CubeMapTextureID.Target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexParameter(CubeMapTextureID.Target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear); GL.TexParameter(CubeMapTextureID.Target, TextureParameterName.TextureBaseLevel, 0); GL.TexParameter(CubeMapTextureID.Target, TextureParameterName.TextureMaxLevel, 13); CubeMapTextureID.Unbind(); DiffuseCubeTextureID.Bind(); GL.TexParameter(CubeMapTextureID.Target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexParameter(CubeMapTextureID.Target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear); GL.TexParameter(DiffuseCubeTextureID.Target, TextureParameterName.TextureBaseLevel, 0); GL.TexParameter(DiffuseCubeTextureID.Target, TextureParameterName.TextureMaxLevel, 2); DiffuseCubeTextureID.Unbind(); }
static void FilterProbeVolume(GLContext control, GLTexture2D normalsMap, GLTextureCube diffuseCubemap, Vector4[] shData, int lightmapTexID, int size, int mipLevel) { if (frameBuffer == null) { Init(size); } if (frameBuffer.Width != size) { frameBuffer.Resize(size, size); } frameBuffer.Bind(); GL.Viewport(0, 0, size, size); //attach face to fbo as color attachment for (int i = 0; i < 6; i++) { //Each fragment output is a cubemap face GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + i, TextureTarget.TextureCubeMapPositiveX + i, lightmapTexID, mipLevel); } var shader = GlobalShaders.GetShader("PROBE"); shader.Enable(); var programID = shader.program; LoadUniforms(programID, shData); GL.ActiveTexture(TextureUnit.Texture0 + 1); normalsMap.Bind(); shader.SetInt("sampler0", 1); GL.ActiveTexture(TextureUnit.Texture0 + 2); diffuseCubemap.Bind(); shader.SetInt("sampler1", 2); //Draw once with 6 fragment outputs to form a cubemap GL.ClearColor(0, 0, 0, 1); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); ScreenQuadRender.Draw(); var errorcheck = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer); if (errorcheck != FramebufferErrorCode.FramebufferComplete) { throw new Exception(errorcheck.ToString()); } frameBuffer.Unbind(); GL.BindTexture(TextureTarget.TextureCubeMap, 0); GL.UseProgram(0); }
public void UpdateProbeLighting(GLContext control) { return; if (!UpdateProbeMap || TurboNXRender.DiffuseLightmapTexture == null /*|| Transform.Position == Vector3.Zero*/) { return; } if (DiffuseProbeTexture == null) { DiffuseProbeTexture = GLTextureCube.CreateEmptyCubemap( 32, PixelInternalFormat.Rgb32f, PixelFormat.Rgb, PixelType.Float, 2); //Allocate mip data. Need 2 seperate mip levels DiffuseProbeTexture.Bind(); DiffuseProbeTexture.GenerateMipmaps(); DiffuseProbeTexture.Unbind(); } Transform.Position = new Vector3(ProbeDebugger.Position.X, ProbeDebugger.Position.Y, ProbeDebugger.Position.Z); Transform.UpdateMatrix(true); var output = LightingEngine.LightSettings.UpdateProbeCubemap(control, DiffuseProbeTexture, new Vector3( ProbeDebugger.Position.X, ProbeDebugger.Position.Y, ProbeDebugger.Position.Z)); if (output == null) { return; } ProbeDebugger.Generated = output.Generated; if (output.Generated) { ProbeDebugger.probeData = output.ProbeData; } ProbeDebugger.DiffuseProbeTexture = DiffuseProbeTexture; // DiffuseProbeTexture.SaveDDS("LIGHT_PROBE.dds"); // DiffuseProbeTexture.Save($"LIGHTMAP_PROBE.png"); ProbeDebugger.ForceUpdate = false; UpdateProbeMap = false; }
static void InitTextures() { //Reflective cubemap CubeMapTexture = GLTextureCubeArray.FromDDS(new DDS($"Resources\\CubemapHDR.dds")); CubemapManager.InitDefault(CubeMapTexture); //Diffuse cubemap lighting //Map gets updated when an object moves using probe lighting. DiffuseLightmapTexture = GLTextureCube.FromDDS( new DDS(new MemoryStream(Resources.CubemapLightmap)), new DDS(new MemoryStream(Resources.CubemapLightmapShadow))); //Shadows //Channel usage: //Red - Dynamic shadows //Green - Static shadows (course) //Blue - Soft shading (under kart, dynamic AO?) //Alpha - Usually gray DepthShadowTexture = GLTexture2D.FromBitmap(Resources.white); DepthShadowCascadeTexture = GLTexture2D.FromBitmap(Resources.white); //Tire marks ProjectionTexture = GLTexture2D.FromBitmap(Resources.white); //Used for dynamic lights. Ie spot, point, kart lights //Dynamic lights are setup using the g buffer pass (normals) and depth information before material pass is drawn //Additional slices may be used for bloom intensity LightPPTexture = GLTexture2DArray.FromBitmap(Resources.black); //Depth information. Likely for shadows NormalizedLinearDepth = GLTexture2D.FromBitmap(Resources.black); //Adjust mip levels CubeMapTexture.Bind(); GL.TexParameter(CubeMapTexture.Target, TextureParameterName.TextureBaseLevel, 0); GL.TexParameter(CubeMapTexture.Target, TextureParameterName.TextureMaxLevel, 13); CubeMapTexture.Unbind(); DiffuseLightmapTexture.Bind(); GL.TexParameter(DiffuseLightmapTexture.Target, TextureParameterName.TextureBaseLevel, 0); GL.TexParameter(DiffuseLightmapTexture.Target, TextureParameterName.TextureMaxLevel, 2); DiffuseLightmapTexture.Unbind(); }
static void InitTextures() { //Cube maps DiffuseCubemapTexture = GLTextureCube.FromDDS( new DDS($"Resources\\CubemapIrradianceDefault.dds")); DiffuseCubemapTexture.Bind(); DiffuseCubemapTexture.MagFilter = TextureMagFilter.Linear; DiffuseCubemapTexture.MinFilter = TextureMinFilter.Linear; DiffuseCubemapTexture.UpdateParameters(); GL.TexParameter(DiffuseCubemapTexture.Target, TextureParameterName.TextureBaseLevel, 0); GL.TexParameter(DiffuseCubemapTexture.Target, TextureParameterName.TextureMaxLevel, 0); DiffuseCubemapTexture.Unbind(); SpecularCubemapTexture = GLTextureCube.FromDDS(new DDS($"Resources\\CubemapDefault.dds")); SpecularCubemapTexture.Bind(); SpecularCubemapTexture.MagFilter = TextureMagFilter.Linear; SpecularCubemapTexture.MinFilter = TextureMinFilter.LinearMipmapLinear; SpecularCubemapTexture.UpdateParameters(); GL.TexParameter(SpecularCubemapTexture.Target, TextureParameterName.TextureBaseLevel, 0); GL.TexParameter(SpecularCubemapTexture.Target, TextureParameterName.TextureMaxLevel, 7); SpecularCubemapTexture.Unbind(); //Shadows ShadowDepthNearTexture = GLTexture2D.FromBitmap(Resources.white); ShadowDepthFarTexture = GLTexture2D.FromBitmap(Resources.white); ShadowDepthCharTexture = GLTexture2D.FromBitmap(Resources.white); //Extra ColorBufferTexture = GLTexture2D.FromBitmap(Resources.black); DepthBufferTexture = GLTexture2D.FromBitmap(Resources.black); HalfTone = GLTexture2D.FromBitmap(Resources.dot); }
public static void CreateCubemap(GLContext control, GLTextureCube cubemapInput, GLTexture cubemapOutput, int layer) { int size = cubemapOutput.Width; Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(90), 1.0f, 0.1f, 10.0f); Matrix4[] captureViews = { Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(1.0f, 0.0f, 0.0f), new Vector3(0.0f, -1.0f, 0.0f)), Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(-1.0f, 0.0f, 0.0f), new Vector3(0.0f, -1.0f, 0.0f)), Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f)), Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, -1.0f, 0.0f), new Vector3(0.0f, 0.0f, -1.0f)), Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f), new Vector3(0.0f, -1.0f, 0.0f)), Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, -1.0f), new Vector3(0.0f, -1.0f, 0.0f)), }; GL.BindTexture(TextureTarget.TextureCubeMap, 0); //Bind the cubemap's texture into a filtered quad. //Bind the drawn filter to a cubemap array layer Framebuffer frameBuffer = new Framebuffer(FramebufferTarget.Framebuffer, size, size, PixelInternalFormat.Rgba32f); frameBuffer.Bind(); GL.Disable(EnableCap.Blend); var cubemapFilter = GlobalShaders.GetShader("CUBEMAP_PREFILTER"); cubemapFilter.Enable(); //Allocate mipmaps cubemapOutput.Bind(); cubemapOutput.GenerateMipmaps(); cubemapOutput.Unbind(); GL.ActiveTexture(TextureUnit.Texture0 + 1); cubemapInput.Bind(); cubemapFilter.SetInt("environmentMap", 1); cubemapFilter.SetMatrix4x4("projection", ref projection); //Quick hack, draw once before rendering (first buffer not updating for some reason??) RenderTools.DrawCube(); GL.Disable(EnableCap.CullFace); for (int mip = 0; mip < cubemapOutput.MipCount; mip++) { int mipWidth = (int)(size * Math.Pow(0.5, mip)); int mipHeight = (int)(size * Math.Pow(0.5, mip)); frameBuffer.Resize(mipWidth, mipHeight); GL.Viewport(0, 0, mipWidth, mipHeight); float roughness = (float)mip / (float)(cubemapOutput.MipCount - 1); cubemapFilter.SetFloat("roughness", roughness); for (int i = 0; i < 6; i++) { //attach face to fbo as color attachment 0 if (cubemapOutput is GLTextureCubeArray) { GL.FramebufferTextureLayer(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, cubemapOutput.ID, mip, (layer * 6) + i); } else { GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.TextureCubeMapPositiveX + i, cubemapOutput.ID, mip); } cubemapFilter.SetMatrix4x4("view", ref captureViews[i]); GL.ClearColor(0, 0, 0, 1); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); RenderTools.DrawCube(); } } var errorcheck = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer); if (errorcheck != FramebufferErrorCode.FramebufferComplete) { throw new Exception(errorcheck.ToString()); } GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); GL.Enable(EnableCap.CullFace); GL.Enable(EnableCap.Blend); frameBuffer.Dispoe(); frameBuffer.DisposeRenderBuffer(); GL.UseProgram(0); }
//Update all existing cubemap uint objects public static void GenerateCubemaps(List <GenericRenderer> targetModels, bool isWiiU) { var texture = isWiiU ? CubeMapTextureArray : CubeMapTexture; if (texture != null) { texture.Dispose(); } if (isWiiU) { texture = GLTexture2DArray.CreateUncompressedTexture(CUBEMAP_SIZE, CUBEMAP_SIZE, MAX_LAYER_COUNT * 6, MAX_MIP_LEVEL, PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.Float); } else { texture = GLTextureCubeArray.CreateEmptyCubemap(CUBEMAP_SIZE, MAX_LAYER_COUNT, MAX_MIP_LEVEL, PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.Float); } GLTextureCube cubemapTexture = GLTextureCube.CreateEmptyCubemap( CUBEMAP_UPSCALE_SIZE, PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.Float, 9); //Get a list of cubemaps in the scene //The lighting engine has cube map objects with the object placement to draw var lightingEngine = LightingEngine.LightSettings; var cubemapEnvParams = lightingEngine.Resources.CubeMapFiles.FirstOrDefault().Value; var cubeMapUints = cubemapEnvParams.CubeMapObjects; int layer = 0; foreach (var cubeMap in cubeMapUints) { var cUint = cubeMap.CubeMapUint; //Cubemap has no area assigned skip it if (cubeMap.CubeMapUint.Name == string.Empty) { continue; } //Setup the camera to render the cube map faces CubemapCamera camera = new CubemapCamera( new Vector3(cUint.Position.X, cUint.Position.Y, cUint.Position.Z) * GLContext.PreviewScale, cUint.Near, cUint.Far); var context = new GLContext(); context.Camera = camera; GenerateCubemap(context, cubemapTexture, camera, targetModels, MAX_MIP_LEVEL); cubemapTexture.Bind(); cubemapTexture.GenerateMipmaps(); cubemapTexture.Unbind(); //HDR encode and output into the array CubemapHDREncodeRT.CreateCubemap(cubemapTexture, texture, layer, MAX_MIP_LEVEL, false, true); if (SAVE_TO_DISK) { cubemapTexture.SaveDDS(cubeMap.Name + "default.dds"); } layer++; } cubemapTexture.Dispose(); //Just generate mips to keep things easier texture.Bind(); texture.GenerateMipmaps(); texture.Unbind(); if (SAVE_TO_DISK) { texture.SaveDDS("Cubemap_Array_HDR.dds"); } if (isWiiU) { CubeMapTextureArray = texture; } else { CubeMapTexture = texture; } }
public static void CreateCubemap(GLContext control, GLTextureCube cubemapInput, GLTexture cubemapOutput, int layer, int numMips) { int size = cubemapInput.Width; Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(90), 1.0f, 0.1f, 10.0f); Matrix4[] captureViews = { Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(1.0f, 0.0f, 0.0f), new Vector3(0.0f, -1.0f, 0.0f)), Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(-1.0f, 0.0f, 0.0f), new Vector3(0.0f, -1.0f, 0.0f)), Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f)), Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, -1.0f, 0.0f), new Vector3(0.0f, 0.0f, -1.0f)), Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f), new Vector3(0.0f, -1.0f, 0.0f)), Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, -1.0f), new Vector3(0.0f, -1.0f, 0.0f)), }; GL.BindTexture(TextureTarget.TextureCubeMap, 0); //Bind the cubemap's texture into a filtered quad. //Bind the drawn filter to a cubemap array layer Framebuffer frameBuffer = new Framebuffer(FramebufferTarget.Framebuffer, size, size, PixelInternalFormat.Rgba32f); frameBuffer.Bind(); GL.Disable(EnableCap.Blend); var cubemapFilter = GlobalShaders.GetShader("CUBEMAP_HDRDECODE"); cubemapFilter.Enable(); GL.ActiveTexture(TextureUnit.Texture0 + 1); cubemapInput.Bind(); cubemapFilter.SetInt("cubemapTexture", 1); cubemapFilter.SetMatrix4x4("projection", ref projection); cubemapFilter.SetFloat("gamma", 2.2f); cubemapFilter.SetFloat("range", 1024.0f); cubemapFilter.SetFloat("scale", 4.0f); GL.Disable(EnableCap.CullFace); for (int mip = 0; mip < numMips; mip++) { int mipWidth = (int)(size * Math.Pow(0.5, mip)); int mipHeight = (int)(size * Math.Pow(0.5, mip)); frameBuffer.Resize(mipWidth, mipHeight); GL.Viewport(0, 0, mipWidth, mipHeight); cubemapFilter.SetFloat("mipLevel", mip); for (int i = 0; i < 6; i++) { cubemapFilter.SetInt("faceLevel", i); //attach face to fbo as color attachment 0 if (cubemapOutput is GLTextureCubeArray) { GL.FramebufferTextureLayer(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, cubemapOutput.ID, mip, (layer * 6) + i); } else { GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.TextureCubeMapPositiveX + i, cubemapOutput.ID, mip); } cubemapFilter.SetMatrix4x4("view", ref captureViews[i]); GL.ClearColor(0, 0, 0, 1); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); RenderTools.DrawCube(); } } var errorcheck = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer); if (errorcheck != FramebufferErrorCode.FramebufferComplete) { throw new Exception(errorcheck.ToString()); } GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); GL.Enable(EnableCap.CullFace); GL.Enable(EnableCap.Blend); frameBuffer.Dispoe(); frameBuffer.DisposeRenderBuffer(); GL.UseProgram(0); }
public override void SetTextureUniforms(GLContext control, ShaderProgram shader, STGenericMaterial mat) { var bfresMaterial = (FMAT)mat; GL.ActiveTexture(TextureUnit.Texture0 + 1); GL.BindTexture(TextureTarget.Texture2D, RenderTools.defaultTex.ID); int id = 1; var pixelShader = ShaderModel.GetGX2PixelShader(BinaryIndex); foreach (var sampler in pixelShader.Samplers) { GL.ActiveTexture(TextureUnit.Texture0 + id); switch (sampler.Name) { case "ice_cube": IceCubeTexture.Bind(); break; case "ice_toon": IceToonTexture.Bind(); break; case "light_pre_pass": LightPPTexture.Bind(); break; case "linear_depth": LinearDepthTexture.Bind(); break; case "shadow_pre_pass": ShadowTexture.Bind(); break; case "projection_map": ProjectionTexture.Bind(); break; default: ProjectionTexture.Bind(); break; } this.SetSampler(shader, (int)sampler.Location, ref id); } for (int i = 0; i < bfresMaterial.TextureMaps?.Count; i++) { var name = mat.TextureMaps[i].Name; var sampler = mat.TextureMaps[i].Sampler; //Lookup samplers targeted via animations and use that texture instead if possible if (bfresMaterial.AnimatedSamplers.ContainsKey(sampler)) { name = bfresMaterial.AnimatedSamplers[sampler]; } var location = this.GetSamplerLocation(bfresMaterial.Samplers[i]); if (location == -1) { continue; } if (name == "ZBtoonEX") { GL.ActiveTexture(TextureUnit.Texture0 + id); ToonTexture.Bind(); this.SetSampler(shader, (int)location, ref id); continue; } var binded = BindTexture(shader, GetTextures(), mat.TextureMaps[i], name, id); this.SetSampler(shader, (int)location, ref id); } GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, 0); }