More PBR improvements. Fix skybox to be a proper skybox
This commit is contained in:
parent
c061c9b052
commit
304b00fe49
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 vbo_position);
|
||||||
GL.GenBuffers(1, out ibo_elements);
|
GL.GenBuffers(1, out ibo_elements);
|
||||||
|
|
||||||
|
TransformBones();
|
||||||
|
|
||||||
UpdateVertexData();
|
UpdateVertexData();
|
||||||
UpdateTextureMaps();
|
UpdateTextureMaps();
|
||||||
}
|
}
|
||||||
@ -82,6 +84,17 @@ namespace FirstPlugin
|
|||||||
GL.DeleteBuffer(ibo_elements);
|
GL.DeleteBuffer(ibo_elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TransformBones()
|
||||||
|
{
|
||||||
|
foreach (var model in models)
|
||||||
|
{
|
||||||
|
foreach (var bone in model.Skeleton.bones)
|
||||||
|
{
|
||||||
|
bone.ModelMatrix = ModelTransform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region Rendering
|
#region Rendering
|
||||||
|
|
||||||
|
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -492,11 +492,6 @@ namespace Switch_Toolbox.Library
|
|||||||
|
|
||||||
ArrayCount = 1;
|
ArrayCount = 1;
|
||||||
|
|
||||||
if (header.caps2 == (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES)
|
|
||||||
{
|
|
||||||
ArrayCount = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DX10HeaderSize = 0;
|
int DX10HeaderSize = 0;
|
||||||
if (header.ddspf.fourCC == FOURCC_DX10)
|
if (header.ddspf.fourCC == FOURCC_DX10)
|
||||||
{
|
{
|
||||||
@ -506,6 +501,11 @@ namespace Switch_Toolbox.Library
|
|||||||
ReadDX10Header(reader);
|
ReadDX10Header(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (header.caps2 == (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES)
|
||||||
|
{
|
||||||
|
ArrayCount = 6;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsCompressed = false;
|
bool IsCompressed = false;
|
||||||
bool HasLuminance = false;
|
bool HasLuminance = false;
|
||||||
bool HasAlpha = false;
|
bool HasAlpha = false;
|
||||||
@ -678,6 +678,12 @@ namespace Switch_Toolbox.Library
|
|||||||
case TEX_FORMAT.BC3_UNORM_SRGB:
|
case TEX_FORMAT.BC3_UNORM_SRGB:
|
||||||
pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
|
pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
|
||||||
break;
|
break;
|
||||||
|
case TEX_FORMAT.BC6H_UF16:
|
||||||
|
pixelInternalFormat = PixelInternalFormat.CompressedRgbBptcUnsignedFloat;
|
||||||
|
break;
|
||||||
|
case TEX_FORMAT.BC6H_SF16:
|
||||||
|
pixelInternalFormat = PixelInternalFormat.CompressedRgbBptcUnsignedFloat;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Exception("Unsupported format! " + dds.Format);
|
throw new Exception("Unsupported format! " + dds.Format);
|
||||||
}
|
}
|
||||||
@ -693,8 +699,22 @@ namespace Switch_Toolbox.Library
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
texture.LoadImageData((int)dds.header.width, new SFGraphics.GLObjects.Textures.TextureFormats.TextureFormatUncompressed(PixelInternalFormat.Rgba,
|
PixelInternalFormat pixelInternalFormat = PixelInternalFormat.Rgba;
|
||||||
OpenTK.Graphics.OpenGL.PixelFormat.Rgba, OpenTK.Graphics.OpenGL.PixelType.UnsignedByte),
|
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[0].mipmaps[0],
|
||||||
cubemap[1].mipmaps[0],
|
cubemap[1].mipmaps[0],
|
||||||
cubemap[2].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 Quaternion rot = Quaternion.FromMatrix(Matrix3.Zero);
|
||||||
public Matrix4 Transform, invert;
|
public Matrix4 Transform, invert;
|
||||||
|
|
||||||
|
//Used for shifting models with the bones in the shader
|
||||||
|
public Matrix4 ModelMatrix = Matrix4.Identity;
|
||||||
|
|
||||||
public Vector3 GetPosition()
|
public Vector3 GetPosition()
|
||||||
{
|
{
|
||||||
return pos;
|
return pos;
|
||||||
|
@ -51,6 +51,7 @@ namespace Switch_Toolbox.Library
|
|||||||
uniform mat4 bone;
|
uniform mat4 bone;
|
||||||
uniform mat4 parent;
|
uniform mat4 parent;
|
||||||
uniform mat4 rotation;
|
uniform mat4 rotation;
|
||||||
|
uniform mat4 ModelMatrix;
|
||||||
uniform int hasParent;
|
uniform int hasParent;
|
||||||
uniform float scale;
|
uniform float scale;
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ namespace Switch_Toolbox.Library
|
|||||||
else
|
else
|
||||||
position = bone * rotation * vec4((point.xyz - vec3(0, 1, 0)) * scale, 1);
|
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.SetVector4("boneColor", ColorUtility.ToVector4(boneColor));
|
||||||
solidColorShaderProgram.SetFloat("scale", Runtime.bonePointSize);
|
solidColorShaderProgram.SetFloat("scale", Runtime.bonePointSize);
|
||||||
|
solidColorShaderProgram.SetMatrix4x4("ModelMatrix", ref bn.ModelMatrix);
|
||||||
|
|
||||||
|
|
||||||
Matrix4 transform = bn.Transform;
|
Matrix4 transform = bn.Transform;
|
||||||
|
|
||||||
|
@ -43,6 +43,8 @@ namespace Switch_Toolbox.Library.Rendering
|
|||||||
if (!Runtime.OpenTKInitialized || !Runtime.PBR.UseSkybox || pass == Pass.TRANSPARENT)
|
if (!Runtime.OpenTKInitialized || !Runtime.PBR.UseSkybox || pass == Pass.TRANSPARENT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
GL.Disable(EnableCap.CullFace);
|
||||||
|
|
||||||
GL.Enable(EnableCap.DepthTest);
|
GL.Enable(EnableCap.DepthTest);
|
||||||
GL.DepthFunc(DepthFunction.Lequal);
|
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.
|
// enable seamless cubemap sampling for lower mip levels in the pre-filter map.
|
||||||
GL.Enable(EnableCap.TextureCubeMapSeamless);
|
GL.Enable(EnableCap.TextureCubeMapSeamless);
|
||||||
|
|
||||||
Matrix4 proj = Matrix4.Identity;
|
Matrix4 proj = control.ProjectionMatrix;
|
||||||
Matrix4 rot = Matrix4.CreateFromQuaternion(control.ModelMatrix.ExtractRotation());
|
// Matrix4 rot = Matrix4.CreateFromQuaternion(control.ModelMatrix.ExtractRotation());
|
||||||
|
Matrix4 rot = new Matrix4(new Matrix3(control.CameraMatrix));
|
||||||
|
|
||||||
GL.UniformMatrix4(defaultShaderProgram["projection"], false, ref proj);
|
defaultShaderProgram.SetMatrix4x4("projection", ref proj);
|
||||||
GL.UniformMatrix4(defaultShaderProgram["rotView"], false, ref rot);
|
defaultShaderProgram.SetMatrix4x4("rotView", ref rot);
|
||||||
|
|
||||||
if (Runtime.PBR.UseDiffuseSkyTexture)
|
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\GenericModel.cs" />
|
||||||
<Compile Include="Generics\GenericObject.cs" />
|
<Compile Include="Generics\GenericObject.cs" />
|
||||||
<Compile Include="Generics\GenericTexture.cs" />
|
<Compile Include="Generics\GenericTexture.cs" />
|
||||||
|
<Compile Include="Generics\OpenGLTexture.cs" />
|
||||||
<Compile Include="Generics\RenderableTex.cs" />
|
<Compile Include="Generics\RenderableTex.cs" />
|
||||||
<Compile Include="Generics\STBone.cs" />
|
<Compile Include="Generics\STBone.cs" />
|
||||||
<Compile Include="Generics\STGenericWrapper.cs" />
|
<Compile Include="Generics\STGenericWrapper.cs" />
|
||||||
@ -622,6 +623,7 @@
|
|||||||
<Compile Include="Rendering\DrawableSkybox.cs" />
|
<Compile Include="Rendering\DrawableSkybox.cs" />
|
||||||
<Compile Include="Rendering\DrawableFloor.cs" />
|
<Compile Include="Rendering\DrawableFloor.cs" />
|
||||||
<Compile Include="Rendering\DrawableXyzLines.cs" />
|
<Compile Include="Rendering\DrawableXyzLines.cs" />
|
||||||
|
<Compile Include="Rendering\PBRMapGenerator.cs" />
|
||||||
<Compile Include="Rendering\ProbeLighting.cs" />
|
<Compile Include="Rendering\ProbeLighting.cs" />
|
||||||
<Compile Include="Rendering\RenderTools.cs" />
|
<Compile Include="Rendering\RenderTools.cs" />
|
||||||
<Compile Include="Rendering\ScreenTriangle.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.tabPage3 = new System.Windows.Forms.TabPage();
|
||||||
this.stLabel13 = new Switch_Toolbox.Library.Forms.STLabel();
|
this.stLabel13 = new Switch_Toolbox.Library.Forms.STLabel();
|
||||||
this.botwGamePathTB = new Switch_Toolbox.Library.Forms.STTextBox();
|
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.stLabel14 = new Switch_Toolbox.Library.Forms.STLabel();
|
||||||
this.tpGamePathTB = new Switch_Toolbox.Library.Forms.STTextBox();
|
this.tpGamePathTB = new Switch_Toolbox.Library.Forms.STTextBox();
|
||||||
this.stLabel12 = new Switch_Toolbox.Library.Forms.STLabel();
|
this.stLabel12 = new Switch_Toolbox.Library.Forms.STLabel();
|
||||||
@ -105,8 +107,6 @@
|
|||||||
this.chkDiffyseSkybox = new Switch_Toolbox.Library.Forms.STCheckBox();
|
this.chkDiffyseSkybox = new Switch_Toolbox.Library.Forms.STCheckBox();
|
||||||
this.stLabel16 = new Switch_Toolbox.Library.Forms.STLabel();
|
this.stLabel16 = new Switch_Toolbox.Library.Forms.STLabel();
|
||||||
this.diffuseCubemapPathTB = new Switch_Toolbox.Library.Forms.STTextBox();
|
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.chkUseSkyobx = new Switch_Toolbox.Library.Forms.STCheckBox();
|
||||||
this.stLabel15 = new Switch_Toolbox.Library.Forms.STLabel();
|
this.stLabel15 = new Switch_Toolbox.Library.Forms.STLabel();
|
||||||
this.specularCubemapPathTB = new Switch_Toolbox.Library.Forms.STTextBox();
|
this.specularCubemapPathTB = new Switch_Toolbox.Library.Forms.STTextBox();
|
||||||
@ -130,8 +130,8 @@
|
|||||||
((System.ComponentModel.ISupportInitialize)(this.bgGradientBottom)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.bgGradientBottom)).BeginInit();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.bgGradientTop)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.bgGradientTop)).BeginInit();
|
||||||
this.tabPage3.SuspendLayout();
|
this.tabPage3.SuspendLayout();
|
||||||
this.tabPage4.SuspendLayout();
|
|
||||||
this.stContextMenuStrip1.SuspendLayout();
|
this.stContextMenuStrip1.SuspendLayout();
|
||||||
|
this.tabPage4.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// contentContainer
|
// contentContainer
|
||||||
@ -988,6 +988,20 @@
|
|||||||
this.botwGamePathTB.TabIndex = 8;
|
this.botwGamePathTB.TabIndex = 8;
|
||||||
this.botwGamePathTB.Click += new System.EventHandler(this.botwGamePathTB_Click);
|
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
|
// stLabel14
|
||||||
//
|
//
|
||||||
this.stLabel14.AutoSize = true;
|
this.stLabel14.AutoSize = true;
|
||||||
@ -1098,34 +1112,20 @@
|
|||||||
this.stLabel16.AutoSize = true;
|
this.stLabel16.AutoSize = true;
|
||||||
this.stLabel16.Location = new System.Drawing.Point(16, 73);
|
this.stLabel16.Location = new System.Drawing.Point(16, 73);
|
||||||
this.stLabel16.Name = "stLabel16";
|
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.TabIndex = 4;
|
||||||
this.stLabel16.Text = "Custom Diffuse Cubemap:";
|
this.stLabel16.Text = "Diffuse Cubemap (Irradiance) :";
|
||||||
//
|
//
|
||||||
// diffuseCubemapPathTB
|
// diffuseCubemapPathTB
|
||||||
//
|
//
|
||||||
this.diffuseCubemapPathTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
this.diffuseCubemapPathTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||||
this.diffuseCubemapPathTB.ContextMenuStrip = this.stContextMenuStrip1;
|
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.Name = "diffuseCubemapPathTB";
|
||||||
this.diffuseCubemapPathTB.Size = new System.Drawing.Size(197, 20);
|
this.diffuseCubemapPathTB.Size = new System.Drawing.Size(197, 20);
|
||||||
this.diffuseCubemapPathTB.TabIndex = 3;
|
this.diffuseCubemapPathTB.TabIndex = 3;
|
||||||
this.diffuseCubemapPathTB.Click += new System.EventHandler(this.diffuseCubemapPathTBB_Click);
|
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
|
// chkUseSkyobx
|
||||||
//
|
//
|
||||||
this.chkUseSkyobx.AutoSize = true;
|
this.chkUseSkyobx.AutoSize = true;
|
||||||
@ -1142,15 +1142,15 @@
|
|||||||
this.stLabel15.AutoSize = true;
|
this.stLabel15.AutoSize = true;
|
||||||
this.stLabel15.Location = new System.Drawing.Point(16, 47);
|
this.stLabel15.Location = new System.Drawing.Point(16, 47);
|
||||||
this.stLabel15.Name = "stLabel15";
|
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.TabIndex = 1;
|
||||||
this.stLabel15.Text = "Custom Specular Cubemap:";
|
this.stLabel15.Text = "Specular Cubemap {Radiance) :";
|
||||||
//
|
//
|
||||||
// specularCubemapPathTB
|
// specularCubemapPathTB
|
||||||
//
|
//
|
||||||
this.specularCubemapPathTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
this.specularCubemapPathTB.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||||
this.specularCubemapPathTB.ContextMenuStrip = this.stContextMenuStrip1;
|
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.Name = "specularCubemapPathTB";
|
||||||
this.specularCubemapPathTB.Size = new System.Drawing.Size(197, 20);
|
this.specularCubemapPathTB.Size = new System.Drawing.Size(197, 20);
|
||||||
this.specularCubemapPathTB.TabIndex = 0;
|
this.specularCubemapPathTB.TabIndex = 0;
|
||||||
@ -1192,9 +1192,9 @@
|
|||||||
((System.ComponentModel.ISupportInitialize)(this.bgGradientTop)).EndInit();
|
((System.ComponentModel.ISupportInitialize)(this.bgGradientTop)).EndInit();
|
||||||
this.tabPage3.ResumeLayout(false);
|
this.tabPage3.ResumeLayout(false);
|
||||||
this.tabPage3.PerformLayout();
|
this.tabPage3.PerformLayout();
|
||||||
|
this.stContextMenuStrip1.ResumeLayout(false);
|
||||||
this.tabPage4.ResumeLayout(false);
|
this.tabPage4.ResumeLayout(false);
|
||||||
this.tabPage4.PerformLayout();
|
this.tabPage4.PerformLayout();
|
||||||
this.stContextMenuStrip1.ResumeLayout(false);
|
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -138,15 +138,15 @@ void main()
|
|||||||
if (vBone.x != -1.0)
|
if (vBone.x != -1.0)
|
||||||
objPos = skin(vPosition, index);
|
objPos = skin(vPosition, index);
|
||||||
|
|
||||||
vec4 position = mtxCam * mtxMdl * vec4(objPos.xyz, 1.0);
|
vec4 position = mtxCam * (mtxMdl * vec4(objPos.xyz, 1.0));
|
||||||
|
|
||||||
normal = vNormal;
|
normal = vNormal;
|
||||||
|
|
||||||
viewNormal = mat3(sphereMatrix) * normal.xyz;
|
viewNormal = mat3(sphereMatrix) * normal.xyz;
|
||||||
|
|
||||||
if(vBone.x != -1.0)
|
if(vBone.x != -1.0)
|
||||||
normal = normalize((skinNRM(vNormal.xyz, index)).xyz);
|
normal = normalize((skinNRM(vNormal.xyz, index)).xyz);
|
||||||
|
|
||||||
|
|
||||||
if (RigidSkinning == 1)
|
if (RigidSkinning == 1)
|
||||||
{
|
{
|
||||||
position = mtxCam * mtxMdl * (bones[index.x] * vec4(vPosition, 1.0));
|
position = mtxCam * mtxMdl * (bones[index.x] * vec4(vPosition, 1.0));
|
||||||
@ -156,9 +156,10 @@ void main()
|
|||||||
{
|
{
|
||||||
position = mtxCam * mtxMdl * (SingleBoneBindTransform * vec4(vPosition, 1.0));
|
position = mtxCam * mtxMdl * (SingleBoneBindTransform * vec4(vPosition, 1.0));
|
||||||
normal = mat3(SingleBoneBindTransform) * vNormal.xyz * 1;
|
normal = mat3(SingleBoneBindTransform) * vNormal.xyz * 1;
|
||||||
//normal = normalize(normal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
normal = normalize(mat3(mtxMdl) * normal.xyz);
|
||||||
|
|
||||||
gl_Position =position;
|
gl_Position =position;
|
||||||
|
|
||||||
f_texcoord0 = vUV0;
|
f_texcoord0 = vUV0;
|
||||||
|
@ -286,11 +286,12 @@ void main()
|
|||||||
vec3 V = normalize(I); // view
|
vec3 V = normalize(I); // view
|
||||||
vec3 L = normalize(specLightDirection); // Light
|
vec3 L = normalize(specLightDirection); // Light
|
||||||
vec3 H = normalize(specLightDirection + I); // half angle
|
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 f0 = mix(vec3(0.04), albedo, metallic); // dialectric
|
||||||
vec3 kS = FresnelSchlickRoughness(max(dot(N, V), 0.0), f0, roughness);
|
vec3 kS = FresnelSchlickRoughness(max(dot(N, V), 0.0), f0, roughness);
|
||||||
|
|
||||||
|
|
||||||
vec3 kD = 1.0 - kS;
|
vec3 kD = 1.0 - kS;
|
||||||
kD *= 1.0 - metallic;
|
kD *= 1.0 - metallic;
|
||||||
|
|
||||||
@ -306,7 +307,7 @@ void main()
|
|||||||
// Diffuse pass
|
// Diffuse pass
|
||||||
vec3 diffuseIblColor = texture(irradianceMap, N).rgb;
|
vec3 diffuseIblColor = texture(irradianceMap, N).rgb;
|
||||||
vec3 diffuseTerm = diffuseIblColor * albedo;
|
vec3 diffuseTerm = diffuseIblColor * albedo;
|
||||||
// diffuseTerm *= kD;
|
diffuseTerm *= kD;
|
||||||
diffuseTerm *= cavity;
|
diffuseTerm *= cavity;
|
||||||
diffuseTerm *= ao;
|
diffuseTerm *= ao;
|
||||||
diffuseTerm *= shadow;
|
diffuseTerm *= shadow;
|
||||||
@ -323,7 +324,7 @@ void main()
|
|||||||
|
|
||||||
vec2 envBRDF = texture(brdfLUT, vec2(max(dot(N, V), 0.0), roughness)).rg;
|
vec2 envBRDF = texture(brdfLUT, vec2(max(dot(N, V), 0.0), roughness)).rg;
|
||||||
vec3 brdfTerm = (kS * envBRDF.x + envBRDF.y);
|
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.
|
// Add render passes.
|
||||||
@ -339,6 +340,8 @@ void main()
|
|||||||
|
|
||||||
fragColor.rgb *= min(boneWeightsColored, vec3(1));
|
fragColor.rgb *= min(boneWeightsColored, vec3(1));
|
||||||
|
|
||||||
|
// HDR tonemapping
|
||||||
|
fragColor.rgb = fragColor.rgb / (fragColor.rgb + vec3(1.0));
|
||||||
|
|
||||||
// Convert back to sRGB.
|
// Convert back to sRGB.
|
||||||
fragColor.rgb = pow(fragColor.rgb, vec3(1 / gamma));
|
fragColor.rgb = pow(fragColor.rgb, vec3(1 / gamma));
|
||||||
|
@ -3,6 +3,7 @@ layout (location = 0) in vec3 aPos;
|
|||||||
|
|
||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
uniform mat4 rotView;
|
uniform mat4 rotView;
|
||||||
|
uniform mat4 mtxCam;
|
||||||
|
|
||||||
out vec3 TexCoords;
|
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">
|
<None Include="Shader\Legacy\KCL.vert">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</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">
|
<None Include="Shader\Utility\Utility.frag">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user