mirror of
https://github.com/KillzXGaming/Switch-Toolbox
synced 2024-11-10 07:04:36 +00:00
More PBR improvements. Fix skybox to be a proper skybox
This commit is contained in:
parent
c061c9b052
commit
304b00fe49
27 changed files with 645 additions and 43 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -67,6 +67,8 @@ namespace FirstPlugin
|
|||
GL.GenBuffers(1, out vbo_position);
|
||||
GL.GenBuffers(1, out ibo_elements);
|
||||
|
||||
TransformBones();
|
||||
|
||||
UpdateVertexData();
|
||||
UpdateTextureMaps();
|
||||
}
|
||||
|
@ -82,6 +84,17 @@ namespace FirstPlugin
|
|||
GL.DeleteBuffer(ibo_elements);
|
||||
}
|
||||
|
||||
private void TransformBones()
|
||||
{
|
||||
foreach (var model in models)
|
||||
{
|
||||
foreach (var bone in model.Skeleton.bones)
|
||||
{
|
||||
bone.ModelMatrix = ModelTransform;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Rendering
|
||||
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -492,11 +492,6 @@ namespace Switch_Toolbox.Library
|
|||
|
||||
ArrayCount = 1;
|
||||
|
||||
if (header.caps2 == (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES)
|
||||
{
|
||||
ArrayCount = 6;
|
||||
}
|
||||
|
||||
int DX10HeaderSize = 0;
|
||||
if (header.ddspf.fourCC == FOURCC_DX10)
|
||||
{
|
||||
|
@ -506,6 +501,11 @@ namespace Switch_Toolbox.Library
|
|||
ReadDX10Header(reader);
|
||||
}
|
||||
|
||||
if (header.caps2 == (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES)
|
||||
{
|
||||
ArrayCount = 6;
|
||||
}
|
||||
|
||||
bool IsCompressed = false;
|
||||
bool HasLuminance = false;
|
||||
bool HasAlpha = false;
|
||||
|
@ -678,6 +678,12 @@ namespace Switch_Toolbox.Library
|
|||
case TEX_FORMAT.BC3_UNORM_SRGB:
|
||||
pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
|
||||
break;
|
||||
case TEX_FORMAT.BC6H_UF16:
|
||||
pixelInternalFormat = PixelInternalFormat.CompressedRgbBptcUnsignedFloat;
|
||||
break;
|
||||
case TEX_FORMAT.BC6H_SF16:
|
||||
pixelInternalFormat = PixelInternalFormat.CompressedRgbBptcUnsignedFloat;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unsupported format! " + dds.Format);
|
||||
}
|
||||
|
@ -693,8 +699,22 @@ namespace Switch_Toolbox.Library
|
|||
}
|
||||
else
|
||||
{
|
||||
texture.LoadImageData((int)dds.header.width, new SFGraphics.GLObjects.Textures.TextureFormats.TextureFormatUncompressed(PixelInternalFormat.Rgba,
|
||||
OpenTK.Graphics.OpenGL.PixelFormat.Rgba, OpenTK.Graphics.OpenGL.PixelType.UnsignedByte),
|
||||
PixelInternalFormat pixelInternalFormat = PixelInternalFormat.Rgba;
|
||||
PixelType pixelType = PixelType.UnsignedByte;
|
||||
PixelFormat pixelFormat = PixelFormat.Rgba;
|
||||
|
||||
switch (dds.Format)
|
||||
{
|
||||
case TEX_FORMAT.R32G32B32A32_FLOAT:
|
||||
pixelInternalFormat = PixelInternalFormat.Rgba32f;
|
||||
pixelType = PixelType.Float;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unsupported format! " + dds.Format);
|
||||
}
|
||||
|
||||
texture.LoadImageData((int)dds.header.width, new SFGraphics.GLObjects.Textures.TextureFormats.TextureFormatUncompressed(pixelInternalFormat,
|
||||
pixelFormat, pixelType),
|
||||
cubemap[0].mipmaps[0],
|
||||
cubemap[1].mipmaps[0],
|
||||
cubemap[2].mipmaps[0],
|
||||
|
|
88
Switch_Toolbox_Library/Generics/OpenGLTexture.cs
Normal file
88
Switch_Toolbox_Library/Generics/OpenGLTexture.cs
Normal file
|
@ -0,0 +1,88 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
|
||||
namespace Switch_Toolbox.Library
|
||||
{
|
||||
//Class based on https://github.com/ScanMountGoat/SFGraphics/blob/2cba15420b40d42c4254583336dbc3ca6a0d28dc/Projects/SFGraphics/GLObjects/Textures/Texture.cs
|
||||
//This makes managing textures easier
|
||||
public class OpenGLTexture
|
||||
{
|
||||
public int TexID;
|
||||
|
||||
public int Width { get; protected set; }
|
||||
|
||||
public int Height { get; protected set; }
|
||||
|
||||
public TextureTarget TextureTarget { get; }
|
||||
|
||||
private TextureMinFilter minFilter;
|
||||
public TextureMinFilter MinFilter
|
||||
{
|
||||
get { return minFilter; }
|
||||
set
|
||||
{
|
||||
minFilter = value;
|
||||
SetTexParameter(TextureParameterName.TextureMinFilter, (int)value);
|
||||
}
|
||||
}
|
||||
|
||||
private TextureMagFilter magFilter;
|
||||
public TextureMagFilter MagFilter
|
||||
{
|
||||
get { return magFilter; }
|
||||
set
|
||||
{
|
||||
magFilter = value;
|
||||
SetTexParameter(TextureParameterName.TextureMagFilter, (int)value);
|
||||
}
|
||||
}
|
||||
|
||||
private TextureWrapMode textureWrapS;
|
||||
public TextureWrapMode TextureWrapS
|
||||
{
|
||||
get { return textureWrapS; }
|
||||
set
|
||||
{
|
||||
textureWrapS = value;
|
||||
SetTexParameter(TextureParameterName.TextureWrapS, (int)value);
|
||||
}
|
||||
}
|
||||
|
||||
private TextureWrapMode textureWrapT;
|
||||
public TextureWrapMode TextureWrapT
|
||||
{
|
||||
get { return textureWrapT; }
|
||||
set
|
||||
{
|
||||
textureWrapT = value;
|
||||
SetTexParameter(TextureParameterName.TextureWrapT, (int)value);
|
||||
}
|
||||
}
|
||||
|
||||
private TextureWrapMode textureWrapR;
|
||||
public TextureWrapMode TextureWrapR
|
||||
{
|
||||
get { return textureWrapR; }
|
||||
set
|
||||
{
|
||||
textureWrapR = value;
|
||||
SetTexParameter(TextureParameterName.TextureWrapR, (int)value);
|
||||
}
|
||||
}
|
||||
|
||||
public void Bind()
|
||||
{
|
||||
GL.BindTexture(TextureTarget, TexID);
|
||||
}
|
||||
|
||||
private void SetTexParameter(TextureParameterName param, int value)
|
||||
{
|
||||
Bind();
|
||||
GL.TexParameter(TextureTarget, param, value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,6 +37,9 @@ namespace Switch_Toolbox.Library
|
|||
public Quaternion rot = Quaternion.FromMatrix(Matrix3.Zero);
|
||||
public Matrix4 Transform, invert;
|
||||
|
||||
//Used for shifting models with the bones in the shader
|
||||
public Matrix4 ModelMatrix = Matrix4.Identity;
|
||||
|
||||
public Vector3 GetPosition()
|
||||
{
|
||||
return pos;
|
||||
|
|
|
@ -51,6 +51,7 @@ namespace Switch_Toolbox.Library
|
|||
uniform mat4 bone;
|
||||
uniform mat4 parent;
|
||||
uniform mat4 rotation;
|
||||
uniform mat4 ModelMatrix;
|
||||
uniform int hasParent;
|
||||
uniform float scale;
|
||||
|
||||
|
@ -63,7 +64,7 @@ namespace Switch_Toolbox.Library
|
|||
else
|
||||
position = bone * rotation * vec4((point.xyz - vec3(0, 1, 0)) * scale, 1);
|
||||
}
|
||||
gl_Position = mtxCam * mtxMdl * vec4(position.xyz, 1);
|
||||
gl_Position = mtxCam * ModelMatrix * mtxMdl * vec4(position.xyz, 1);
|
||||
|
||||
}");
|
||||
|
||||
|
@ -236,6 +237,8 @@ namespace Switch_Toolbox.Library
|
|||
|
||||
solidColorShaderProgram.SetVector4("boneColor", ColorUtility.ToVector4(boneColor));
|
||||
solidColorShaderProgram.SetFloat("scale", Runtime.bonePointSize);
|
||||
solidColorShaderProgram.SetMatrix4x4("ModelMatrix", ref bn.ModelMatrix);
|
||||
|
||||
|
||||
Matrix4 transform = bn.Transform;
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ namespace Switch_Toolbox.Library.Rendering
|
|||
if (!Runtime.OpenTKInitialized || !Runtime.PBR.UseSkybox || pass == Pass.TRANSPARENT)
|
||||
return;
|
||||
|
||||
GL.Disable(EnableCap.CullFace);
|
||||
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
GL.DepthFunc(DepthFunction.Lequal);
|
||||
|
||||
|
@ -56,11 +58,12 @@ namespace Switch_Toolbox.Library.Rendering
|
|||
// enable seamless cubemap sampling for lower mip levels in the pre-filter map.
|
||||
GL.Enable(EnableCap.TextureCubeMapSeamless);
|
||||
|
||||
Matrix4 proj = Matrix4.Identity;
|
||||
Matrix4 rot = Matrix4.CreateFromQuaternion(control.ModelMatrix.ExtractRotation());
|
||||
Matrix4 proj = control.ProjectionMatrix;
|
||||
// Matrix4 rot = Matrix4.CreateFromQuaternion(control.ModelMatrix.ExtractRotation());
|
||||
Matrix4 rot = new Matrix4(new Matrix3(control.CameraMatrix));
|
||||
|
||||
GL.UniformMatrix4(defaultShaderProgram["projection"], false, ref proj);
|
||||
GL.UniformMatrix4(defaultShaderProgram["rotView"], false, ref rot);
|
||||
defaultShaderProgram.SetMatrix4x4("projection", ref proj);
|
||||
defaultShaderProgram.SetMatrix4x4("rotView", ref rot);
|
||||
|
||||
if (Runtime.PBR.UseDiffuseSkyTexture)
|
||||
{
|
||||
|
|
107
Switch_Toolbox_Library/Rendering/PBRMapGenerator.cs
Normal file
107
Switch_Toolbox_Library/Rendering/PBRMapGenerator.cs
Normal file
|
@ -0,0 +1,107 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GL_EditorFramework.Interfaces;
|
||||
using GL_EditorFramework.GL_Core;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using OpenTK;
|
||||
|
||||
namespace Switch_Toolbox.Library.Rendering
|
||||
{
|
||||
public class PBRMapGenerator
|
||||
{
|
||||
public int BrdfLUTMap = -1;
|
||||
|
||||
private ShaderProgram BrdfShader;
|
||||
|
||||
private int captureFBO = 1;
|
||||
private int captureRBO = 1;
|
||||
|
||||
private bool IsBufferCreated()
|
||||
{
|
||||
return (captureFBO != -1 && captureRBO != -1);
|
||||
}
|
||||
|
||||
private void GenerateFrameBuffer()
|
||||
{
|
||||
// setup framebuffer
|
||||
GL.GenFramebuffers(1, out captureFBO);
|
||||
GL.GenFramebuffers(1, out captureRBO);
|
||||
}
|
||||
|
||||
public void GeneratImageBasedLightingMap()
|
||||
{
|
||||
// enable seamless cubemap sampling for lower mip levels in the pre-filter map.
|
||||
GL.Enable(EnableCap.TextureCubeMapSeamless);
|
||||
|
||||
if (!IsBufferCreated())
|
||||
GenerateFrameBuffer();
|
||||
}
|
||||
|
||||
public void GenerateBrdfMap()
|
||||
{
|
||||
if (!IsBufferCreated())
|
||||
GenerateFrameBuffer();
|
||||
|
||||
GL.UseProgram(BrdfShader.program);
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||
RenderQuad();
|
||||
|
||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
|
||||
|
||||
BrdfLUTMap = LoadBrdfLUTTexture();
|
||||
|
||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, captureFBO);
|
||||
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, captureRBO);
|
||||
GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent24, 512, 512);
|
||||
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, BrdfLUTMap, 0);
|
||||
|
||||
Matrix4 proj = Matrix4.Identity;
|
||||
}
|
||||
|
||||
public static int LoadBrdfLUTTexture()
|
||||
{
|
||||
int texture;
|
||||
GL.GenTextures(1, out texture);
|
||||
GL.BindTexture(TextureTarget.Texture2D, texture);
|
||||
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rg32f, 512, 512, 0, OpenTK.Graphics.OpenGL.PixelFormat.Rg, PixelType.Float, (IntPtr)0);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
private static void RenderQuad()
|
||||
{
|
||||
int quadVAO = 0;
|
||||
int quadVBO;
|
||||
if (quadVAO == 0)
|
||||
{
|
||||
float[] vertices = {
|
||||
// positions // texture Coords
|
||||
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
};
|
||||
|
||||
GL.GenVertexArrays(1, out quadVAO);
|
||||
GL.GenBuffers(1, out quadVBO);
|
||||
GL.BindVertexArray(quadVAO);
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, quadVBO);
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, 4 * vertices.Length, vertices, BufferUsageHint.StaticDraw);
|
||||
GL.EnableVertexAttribArray(0);
|
||||
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 5 * sizeof(float), (IntPtr)0);
|
||||
GL.EnableVertexAttribArray(1);
|
||||
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), (IntPtr)(3 * sizeof(float)));
|
||||
}
|
||||
GL.BindVertexArray(quadVAO);
|
||||
GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
|
||||
GL.BindVertexArray(0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -497,6 +497,7 @@
|
|||
<Compile Include="Generics\GenericModel.cs" />
|
||||
<Compile Include="Generics\GenericObject.cs" />
|
||||
<Compile Include="Generics\GenericTexture.cs" />
|
||||
<Compile Include="Generics\OpenGLTexture.cs" />
|
||||
<Compile Include="Generics\RenderableTex.cs" />
|
||||
<Compile Include="Generics\STBone.cs" />
|
||||
<Compile Include="Generics\STGenericWrapper.cs" />
|
||||
|
@ -622,6 +623,7 @@
|
|||
<Compile Include="Rendering\DrawableSkybox.cs" />
|
||||
<Compile Include="Rendering\DrawableFloor.cs" />
|
||||
<Compile Include="Rendering\DrawableXyzLines.cs" />
|
||||
<Compile Include="Rendering\PBRMapGenerator.cs" />
|
||||
<Compile Include="Rendering\ProbeLighting.cs" />
|
||||
<Compile Include="Rendering\RenderTools.cs" />
|
||||
<Compile Include="Rendering\ScreenTriangle.cs" />
|
||||
|
|
48
Toolbox/GUI/Settings.Designer.cs
generated
48
Toolbox/GUI/Settings.Designer.cs
generated
|
@ -93,6 +93,8 @@
|
|||
this.tabPage3 = new System.Windows.Forms.TabPage();
|
||||
this.stLabel13 = new Switch_Toolbox.Library.Forms.STLabel();
|
||||
this.botwGamePathTB = new Switch_Toolbox.Library.Forms.STTextBox();
|
||||
this.stContextMenuStrip1 = new Switch_Toolbox.Library.Forms.STContextMenuStrip(this.components);
|
||||
this.clearSettingToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.stLabel14 = new Switch_Toolbox.Library.Forms.STLabel();
|
||||
this.tpGamePathTB = new Switch_Toolbox.Library.Forms.STTextBox();
|
||||
this.stLabel12 = new Switch_Toolbox.Library.Forms.STLabel();
|
||||
|
@ -105,8 +107,6 @@
|
|||
this.chkDiffyseSkybox = new Switch_Toolbox.Library.Forms.STCheckBox();
|
||||
this.stLabel16 = new Switch_Toolbox.Library.Forms.STLabel();
|
||||
this.diffuseCubemapPathTB = new Switch_Toolbox.Library.Forms.STTextBox();
|
||||
this.stContextMenuStrip1 = new Switch_Toolbox.Library.Forms.STContextMenuStrip(this.components);
|
||||
this.clearSettingToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.chkUseSkyobx = new Switch_Toolbox.Library.Forms.STCheckBox();
|
||||
this.stLabel15 = new Switch_Toolbox.Library.Forms.STLabel();
|
||||
this.specularCubemapPathTB = new Switch_Toolbox.Library.Forms.STTextBox();
|
||||
|
@ -130,8 +130,8 @@
|
|||
((System.ComponentModel.ISupportInitialize)(this.bgGradientBottom)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.bgGradientTop)).BeginInit();
|
||||
this.tabPage3.SuspendLayout();
|
||||
this.tabPage4.SuspendLayout();
|
||||
this.stContextMenuStrip1.SuspendLayout();
|
||||
this.tabPage4.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// contentContainer
|
||||
|
@ -988,6 +988,20 @@
|
|||
this.botwGamePathTB.TabIndex = 8;
|
||||
this.botwGamePathTB.Click += new System.EventHandler(this.botwGamePathTB_Click);
|
||||
//
|
||||
// stContextMenuStrip1
|
||||
//
|
||||
this.stContextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.clearSettingToolStripMenuItem});
|
||||
this.stContextMenuStrip1.Name = "stContextMenuStrip1";
|
||||
this.stContextMenuStrip1.Size = new System.Drawing.Size(142, 26);
|
||||
//
|
||||
// clearSettingToolStripMenuItem
|
||||
//
|
||||
this.clearSettingToolStripMenuItem.Name = "clearSettingToolStripMenuItem";
|
||||
this.clearSettingToolStripMenuItem.Size = new System.Drawing.Size(141, 22);
|
||||
this.clearSettingToolStripMenuItem.Text = "Clear Setting";
|
||||
this.clearSettingToolStripMenuItem.Click += new System.EventHandler(this.clearSettingToolStripMenuItem_Click);
|
||||
//
|
||||
// stLabel14
|
||||
//
|
||||
this.stLabel14.AutoSize = true;
|
||||
|
@ -1098,34 +1112,20 @@
|
|||
this.stLabel16.AutoSize = true;
|
||||
this.stLabel16.Location = new System.Drawing.Point(16, 73);
|
||||
this.stLabel16.Name = "stLabel16";
|
||||
this.stLabel16.Size = new System.Drawing.Size(129, 13);
|
||||
this.stLabel16.Size = new System.Drawing.Size(150, 13);
|
||||
this.stLabel16.TabIndex = 4;
|
||||
this.stLabel16.Text = "Custom Diffuse Cubemap:";
|
||||
this.stLabel16.Text = "Diffuse Cubemap (Irradiance) :";
|
||||
//
|
||||
// diffuseCubemapPathTB
|
||||
//
|
||||
this.diffuseCubemapPathTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.diffuseCubemapPathTB.ContextMenuStrip = this.stContextMenuStrip1;
|
||||
this.diffuseCubemapPathTB.Location = new System.Drawing.Point(160, 71);
|
||||
this.diffuseCubemapPathTB.Location = new System.Drawing.Point(181, 73);
|
||||
this.diffuseCubemapPathTB.Name = "diffuseCubemapPathTB";
|
||||
this.diffuseCubemapPathTB.Size = new System.Drawing.Size(197, 20);
|
||||
this.diffuseCubemapPathTB.TabIndex = 3;
|
||||
this.diffuseCubemapPathTB.Click += new System.EventHandler(this.diffuseCubemapPathTBB_Click);
|
||||
//
|
||||
// stContextMenuStrip1
|
||||
//
|
||||
this.stContextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.clearSettingToolStripMenuItem});
|
||||
this.stContextMenuStrip1.Name = "stContextMenuStrip1";
|
||||
this.stContextMenuStrip1.Size = new System.Drawing.Size(142, 26);
|
||||
//
|
||||
// clearSettingToolStripMenuItem
|
||||
//
|
||||
this.clearSettingToolStripMenuItem.Name = "clearSettingToolStripMenuItem";
|
||||
this.clearSettingToolStripMenuItem.Size = new System.Drawing.Size(141, 22);
|
||||
this.clearSettingToolStripMenuItem.Text = "Clear Setting";
|
||||
this.clearSettingToolStripMenuItem.Click += new System.EventHandler(this.clearSettingToolStripMenuItem_Click);
|
||||
//
|
||||
// chkUseSkyobx
|
||||
//
|
||||
this.chkUseSkyobx.AutoSize = true;
|
||||
|
@ -1142,15 +1142,15 @@
|
|||
this.stLabel15.AutoSize = true;
|
||||
this.stLabel15.Location = new System.Drawing.Point(16, 47);
|
||||
this.stLabel15.Name = "stLabel15";
|
||||
this.stLabel15.Size = new System.Drawing.Size(138, 13);
|
||||
this.stLabel15.Size = new System.Drawing.Size(159, 13);
|
||||
this.stLabel15.TabIndex = 1;
|
||||
this.stLabel15.Text = "Custom Specular Cubemap:";
|
||||
this.stLabel15.Text = "Specular Cubemap {Radiance) :";
|
||||
//
|
||||
// specularCubemapPathTB
|
||||
//
|
||||
this.specularCubemapPathTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.specularCubemapPathTB.ContextMenuStrip = this.stContextMenuStrip1;
|
||||
this.specularCubemapPathTB.Location = new System.Drawing.Point(160, 45);
|
||||
this.specularCubemapPathTB.Location = new System.Drawing.Point(181, 45);
|
||||
this.specularCubemapPathTB.Name = "specularCubemapPathTB";
|
||||
this.specularCubemapPathTB.Size = new System.Drawing.Size(197, 20);
|
||||
this.specularCubemapPathTB.TabIndex = 0;
|
||||
|
@ -1192,9 +1192,9 @@
|
|||
((System.ComponentModel.ISupportInitialize)(this.bgGradientTop)).EndInit();
|
||||
this.tabPage3.ResumeLayout(false);
|
||||
this.tabPage3.PerformLayout();
|
||||
this.stContextMenuStrip1.ResumeLayout(false);
|
||||
this.tabPage4.ResumeLayout(false);
|
||||
this.tabPage4.PerformLayout();
|
||||
this.stContextMenuStrip1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
|
|
@ -138,15 +138,15 @@ void main()
|
|||
if (vBone.x != -1.0)
|
||||
objPos = skin(vPosition, index);
|
||||
|
||||
vec4 position = mtxCam * mtxMdl * vec4(objPos.xyz, 1.0);
|
||||
vec4 position = mtxCam * (mtxMdl * vec4(objPos.xyz, 1.0));
|
||||
|
||||
normal = vNormal;
|
||||
|
||||
viewNormal = mat3(sphereMatrix) * normal.xyz;
|
||||
|
||||
if(vBone.x != -1.0)
|
||||
normal = normalize((skinNRM(vNormal.xyz, index)).xyz);
|
||||
|
||||
|
||||
if (RigidSkinning == 1)
|
||||
{
|
||||
position = mtxCam * mtxMdl * (bones[index.x] * vec4(vPosition, 1.0));
|
||||
|
@ -156,9 +156,10 @@ void main()
|
|||
{
|
||||
position = mtxCam * mtxMdl * (SingleBoneBindTransform * vec4(vPosition, 1.0));
|
||||
normal = mat3(SingleBoneBindTransform) * vNormal.xyz * 1;
|
||||
//normal = normalize(normal);
|
||||
}
|
||||
|
||||
normal = normalize(mat3(mtxMdl) * normal.xyz);
|
||||
|
||||
gl_Position =position;
|
||||
|
||||
f_texcoord0 = vUV0;
|
||||
|
|
|
@ -286,11 +286,12 @@ void main()
|
|||
vec3 V = normalize(I); // view
|
||||
vec3 L = normalize(specLightDirection); // Light
|
||||
vec3 H = normalize(specLightDirection + I); // half angle
|
||||
vec3 R = reflect(I, N); // reflection
|
||||
vec3 R = reflect(-I, N); // reflection
|
||||
|
||||
vec3 f0 = mix(vec3(0.04), albedo, metallic); // dialectric
|
||||
vec3 kS = FresnelSchlickRoughness(max(dot(N, V), 0.0), f0, roughness);
|
||||
|
||||
|
||||
vec3 kD = 1.0 - kS;
|
||||
kD *= 1.0 - metallic;
|
||||
|
||||
|
@ -306,7 +307,7 @@ void main()
|
|||
// Diffuse pass
|
||||
vec3 diffuseIblColor = texture(irradianceMap, N).rgb;
|
||||
vec3 diffuseTerm = diffuseIblColor * albedo;
|
||||
// diffuseTerm *= kD;
|
||||
diffuseTerm *= kD;
|
||||
diffuseTerm *= cavity;
|
||||
diffuseTerm *= ao;
|
||||
diffuseTerm *= shadow;
|
||||
|
@ -323,7 +324,7 @@ void main()
|
|||
|
||||
vec2 envBRDF = texture(brdfLUT, vec2(max(dot(N, V), 0.0), roughness)).rg;
|
||||
vec3 brdfTerm = (kS * envBRDF.x + envBRDF.y);
|
||||
vec3 specularTerm = specularIblColor * brdfTerm * specIntensity * 0.7f;
|
||||
vec3 specularTerm = specularIblColor * (kS * brdfTerm.x + brdfTerm.y) * specIntensity;
|
||||
|
||||
|
||||
// Add render passes.
|
||||
|
@ -339,6 +340,8 @@ void main()
|
|||
|
||||
fragColor.rgb *= min(boneWeightsColored, vec3(1));
|
||||
|
||||
// HDR tonemapping
|
||||
fragColor.rgb = fragColor.rgb / (fragColor.rgb + vec3(1.0));
|
||||
|
||||
// Convert back to sRGB.
|
||||
fragColor.rgb = pow(fragColor.rgb, vec3(1 / gamma));
|
||||
|
|
|
@ -3,6 +3,7 @@ layout (location = 0) in vec3 aPos;
|
|||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 rotView;
|
||||
uniform mat4 mtxCam;
|
||||
|
||||
out vec3 TexCoords;
|
||||
|
||||
|
|
22
Toolbox/Shader/PBR/HDR.frag
Normal file
22
Toolbox/Shader/PBR/HDR.frag
Normal file
|
@ -0,0 +1,22 @@
|
|||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
in vec3 localPos;
|
||||
|
||||
uniform sampler2D equirectangularMap;
|
||||
|
||||
const vec2 invAtan = vec2(0.1591, 0.3183);
|
||||
vec2 SampleSphericalMap(vec3 v)
|
||||
{
|
||||
vec2 uv = vec2(atan(v.z, v.x), asin(v.y));
|
||||
uv *= invAtan;
|
||||
uv += 0.5;
|
||||
return uv;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = SampleSphericalMap(normalize(localPos)); // make sure to normalize localPos
|
||||
vec3 color = texture(equirectangularMap, uv).rgb;
|
||||
|
||||
FragColor = vec4(color, 1.0);
|
||||
}
|
13
Toolbox/Shader/PBR/HDR.vert
Normal file
13
Toolbox/Shader/PBR/HDR.vert
Normal file
|
@ -0,0 +1,13 @@
|
|||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
out vec3 localPos;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
|
||||
void main()
|
||||
{
|
||||
localPos = aPos;
|
||||
gl_Position = projection * view * vec4(localPos, 1.0);
|
||||
}
|
113
Toolbox/Shader/PBR/brdf.frag
Normal file
113
Toolbox/Shader/PBR/brdf.frag
Normal file
|
@ -0,0 +1,113 @@
|
|||
#version 330 core
|
||||
out vec2 FragColor;
|
||||
in vec2 TexCoords;
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
// ----------------------------------------------------------------------------
|
||||
// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
|
||||
// efficient VanDerCorpus calculation.
|
||||
float RadicalInverse_VdC(uint bits)
|
||||
{
|
||||
bits = (bits << 16u) | (bits >> 16u);
|
||||
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
||||
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
||||
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
||||
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
||||
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
vec2 Hammersley(uint i, uint N)
|
||||
{
|
||||
return vec2(float(i)/float(N), RadicalInverse_VdC(i));
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
|
||||
{
|
||||
float a = roughness*roughness;
|
||||
|
||||
float phi = 2.0 * PI * Xi.x;
|
||||
float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
|
||||
float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
|
||||
|
||||
// from spherical coordinates to cartesian coordinates - halfway vector
|
||||
vec3 H;
|
||||
H.x = cos(phi) * sinTheta;
|
||||
H.y = sin(phi) * sinTheta;
|
||||
H.z = cosTheta;
|
||||
|
||||
// from tangent-space H vector to world-space sample vector
|
||||
vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
|
||||
vec3 tangent = normalize(cross(up, N));
|
||||
vec3 bitangent = cross(N, tangent);
|
||||
|
||||
vec3 sampleVec = tangent * H.x + bitangent * H.y + N * H.z;
|
||||
return normalize(sampleVec);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
float GeometrySchlickGGX(float NdotV, float roughness)
|
||||
{
|
||||
// note that we use a different k for IBL
|
||||
float a = roughness;
|
||||
float k = (a * a) / 2.0;
|
||||
|
||||
float nom = NdotV;
|
||||
float denom = NdotV * (1.0 - k) + k;
|
||||
|
||||
return nom / denom;
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
|
||||
{
|
||||
float NdotV = max(dot(N, V), 0.0);
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
|
||||
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
|
||||
|
||||
return ggx1 * ggx2;
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
vec2 IntegrateBRDF(float NdotV, float roughness)
|
||||
{
|
||||
vec3 V;
|
||||
V.x = sqrt(1.0 - NdotV*NdotV);
|
||||
V.y = 0.0;
|
||||
V.z = NdotV;
|
||||
|
||||
float A = 0.0;
|
||||
float B = 0.0;
|
||||
|
||||
vec3 N = vec3(0.0, 0.0, 1.0);
|
||||
|
||||
const uint SAMPLE_COUNT = 1024u;
|
||||
for(uint i = 0u; i < SAMPLE_COUNT; ++i)
|
||||
{
|
||||
// generates a sample vector that's biased towards the
|
||||
// preferred alignment direction (importance sampling).
|
||||
vec2 Xi = Hammersley(i, SAMPLE_COUNT);
|
||||
vec3 H = ImportanceSampleGGX(Xi, N, roughness);
|
||||
vec3 L = normalize(2.0 * dot(V, H) * H - V);
|
||||
|
||||
float NdotL = max(L.z, 0.0);
|
||||
float NdotH = max(H.z, 0.0);
|
||||
float VdotH = max(dot(V, H), 0.0);
|
||||
|
||||
if(NdotL > 0.0)
|
||||
{
|
||||
float G = GeometrySmith(N, V, L, roughness);
|
||||
float G_Vis = (G * VdotH) / (NdotH * NdotV);
|
||||
float Fc = pow(1.0 - VdotH, 5.0);
|
||||
|
||||
A += (1.0 - Fc) * G_Vis;
|
||||
B += Fc * G_Vis;
|
||||
}
|
||||
}
|
||||
A /= float(SAMPLE_COUNT);
|
||||
B /= float(SAMPLE_COUNT);
|
||||
return vec2(A, B);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
void main()
|
||||
{
|
||||
vec2 integratedBRDF = IntegrateBRDF(TexCoords.x, TexCoords.y);
|
||||
FragColor = integratedBRDF;
|
||||
}
|
11
Toolbox/Shader/PBR/brdf.vert
Normal file
11
Toolbox/Shader/PBR/brdf.vert
Normal file
|
@ -0,0 +1,11 @@
|
|||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoords;
|
||||
|
||||
out vec2 TexCoords;
|
||||
|
||||
void main()
|
||||
{
|
||||
TexCoords = aTexCoords;
|
||||
gl_Position = vec4(aPos, 1.0);
|
||||
}
|
43
Toolbox/Shader/PBR/irradianceShader.frag
Normal file
43
Toolbox/Shader/PBR/irradianceShader.frag
Normal file
|
@ -0,0 +1,43 @@
|
|||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
in vec3 WorldPos;
|
||||
|
||||
uniform samplerCube environmentMap;
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
|
||||
void main()
|
||||
{
|
||||
// The world vector acts as the normal of a tangent surface
|
||||
// from the origin, aligned to WorldPos. Given this normal, calculate all
|
||||
// incoming radiance of the environment. The result of this radiance
|
||||
// is the radiance of light coming from -Normal direction, which is what
|
||||
// we use in the PBR shader to sample irradiance.
|
||||
vec3 N = normalize(WorldPos);
|
||||
|
||||
vec3 irradiance = vec3(0.0);
|
||||
|
||||
// tangent space calculation from origin point
|
||||
vec3 up = vec3(0.0, 1.0, 0.0);
|
||||
vec3 right = cross(up, N);
|
||||
up = cross(N, right);
|
||||
|
||||
float sampleDelta = 0.025;
|
||||
float nrSamples = 0.0;
|
||||
for(float phi = 0.0; phi < 2.0 * PI; phi += sampleDelta)
|
||||
{
|
||||
for(float theta = 0.0; theta < 0.5 * PI; theta += sampleDelta)
|
||||
{
|
||||
// spherical to cartesian (in tangent space)
|
||||
vec3 tangentSample = vec3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
|
||||
// tangent space to world
|
||||
vec3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * N;
|
||||
|
||||
irradiance += texture(environmentMap, sampleVec).rgb * cos(theta) * sin(theta);
|
||||
nrSamples++;
|
||||
}
|
||||
}
|
||||
irradiance = PI * irradiance * (1.0 / float(nrSamples));
|
||||
|
||||
FragColor = vec4(irradiance, 1.0);
|
||||
}
|
13
Toolbox/Shader/PBR/irradianceShader.vert
Normal file
13
Toolbox/Shader/PBR/irradianceShader.vert
Normal file
|
@ -0,0 +1,13 @@
|
|||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
out vec3 WorldPos;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
|
||||
void main()
|
||||
{
|
||||
WorldPos = aPos;
|
||||
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||
}
|
106
Toolbox/Shader/PBR/preFilter.frag
Normal file
106
Toolbox/Shader/PBR/preFilter.frag
Normal file
|
@ -0,0 +1,106 @@
|
|||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
in vec3 WorldPos;
|
||||
|
||||
uniform samplerCube environmentMap;
|
||||
uniform float roughness;
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
// ----------------------------------------------------------------------------
|
||||
float DistributionGGX(vec3 N, vec3 H, float roughness)
|
||||
{
|
||||
float a = roughness*roughness;
|
||||
float a2 = a*a;
|
||||
float NdotH = max(dot(N, H), 0.0);
|
||||
float NdotH2 = NdotH*NdotH;
|
||||
|
||||
float nom = a2;
|
||||
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
|
||||
denom = PI * denom * denom;
|
||||
|
||||
return nom / denom;
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
|
||||
// efficient VanDerCorpus calculation.
|
||||
float RadicalInverse_VdC(uint bits)
|
||||
{
|
||||
bits = (bits << 16u) | (bits >> 16u);
|
||||
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
||||
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
||||
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
||||
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
||||
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
vec2 Hammersley(uint i, uint N)
|
||||
{
|
||||
return vec2(float(i)/float(N), RadicalInverse_VdC(i));
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
|
||||
{
|
||||
float a = roughness*roughness;
|
||||
|
||||
float phi = 2.0 * PI * Xi.x;
|
||||
float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
|
||||
float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
|
||||
|
||||
// from spherical coordinates to cartesian coordinates - halfway vector
|
||||
vec3 H;
|
||||
H.x = cos(phi) * sinTheta;
|
||||
H.y = sin(phi) * sinTheta;
|
||||
H.z = cosTheta;
|
||||
|
||||
// from tangent-space H vector to world-space sample vector
|
||||
vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
|
||||
vec3 tangent = normalize(cross(up, N));
|
||||
vec3 bitangent = cross(N, tangent);
|
||||
|
||||
vec3 sampleVec = tangent * H.x + bitangent * H.y + N * H.z;
|
||||
return normalize(sampleVec);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
void main()
|
||||
{
|
||||
vec3 N = normalize(WorldPos);
|
||||
|
||||
// make the simplyfying assumption that V equals R equals the normal
|
||||
vec3 R = N;
|
||||
vec3 V = R;
|
||||
|
||||
const uint SAMPLE_COUNT = 1024u;
|
||||
vec3 prefilteredColor = vec3(0.0);
|
||||
float totalWeight = 0.0;
|
||||
|
||||
for(uint i = 0u; i < SAMPLE_COUNT; ++i)
|
||||
{
|
||||
// generates a sample vector that's biased towards the preferred alignment direction (importance sampling).
|
||||
vec2 Xi = Hammersley(i, SAMPLE_COUNT);
|
||||
vec3 H = ImportanceSampleGGX(Xi, N, roughness);
|
||||
vec3 L = normalize(2.0 * dot(V, H) * H - V);
|
||||
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
if(NdotL > 0.0)
|
||||
{
|
||||
// sample from the environment's mip level based on roughness/pdf
|
||||
float D = DistributionGGX(N, H, roughness);
|
||||
float NdotH = max(dot(N, H), 0.0);
|
||||
float HdotV = max(dot(H, V), 0.0);
|
||||
float pdf = D * NdotH / (4.0 * HdotV) + 0.0001;
|
||||
|
||||
float resolution = 512.0; // resolution of source cubemap (per face)
|
||||
float saTexel = 4.0 * PI / (6.0 * resolution * resolution);
|
||||
float saSample = 1.0 / (float(SAMPLE_COUNT) * pdf + 0.0001);
|
||||
|
||||
float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel);
|
||||
|
||||
prefilteredColor += textureLod(environmentMap, L, mipLevel).rgb * NdotL;
|
||||
totalWeight += NdotL;
|
||||
}
|
||||
}
|
||||
|
||||
prefilteredColor = prefilteredColor / totalWeight;
|
||||
|
||||
FragColor = vec4(prefilteredColor, 1.0);
|
||||
}
|
13
Toolbox/Shader/PBR/preFilter.vert
Normal file
13
Toolbox/Shader/PBR/preFilter.vert
Normal file
|
@ -0,0 +1,13 @@
|
|||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
out vec3 WorldPos;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
|
||||
void main()
|
||||
{
|
||||
WorldPos = aPos;
|
||||
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||
}
|
|
@ -216,6 +216,30 @@
|
|||
<None Include="Shader\Legacy\KCL.vert">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Shader\PBR\brdf.frag">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Shader\PBR\brdf.vert">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Shader\PBR\HDR.frag">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Shader\PBR\HDR.vert">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Shader\PBR\irradianceShader.frag">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Shader\PBR\irradianceShader.vert">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Shader\PBR\preFilter.frag">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Shader\PBR\preFilter.vert">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Shader\Utility\Utility.frag">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
|
Loading…
Reference in a new issue