加入天空盒

dev-VirtualTexture
wuyize 2023-02-12 12:16:33 +08:00
parent d15e3baa69
commit f3559d133d
12 changed files with 331 additions and 103 deletions

View File

@ -72,7 +72,7 @@
<PreprocessorDefinitions>FRAMELESSHELPER_WIDGETS_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>FRAMELESSHELPER_WIDGETS_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
@ -154,6 +154,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\data.json" /> <None Include="..\data.json" />
<None Include="res\Shaders\cubemap.frag" />
<None Include="res\Shaders\cubemap.vert" />
<None Include="res\Shaders\depth_init.comp" /> <None Include="res\Shaders\depth_init.comp" />
<None Include="res\Shaders\depth_mipmap.comp" /> <None Include="res\Shaders\depth_mipmap.comp" />
<None Include="res\Shaders\element.comp" /> <None Include="res\Shaders\element.comp" />
@ -170,6 +172,8 @@
<None Include="res\Shaders\shader.frag" /> <None Include="res\Shaders\shader.frag" />
<None Include="res\Shaders\shader.vert" /> <None Include="res\Shaders\shader.vert" />
<None Include="res\Shaders\shadow_mapping.comp" /> <None Include="res\Shaders\shadow_mapping.comp" />
<None Include="res\Shaders\skybox.frag" />
<None Include="res\Shaders\skybox.vert" />
<None Include="res\Shaders\ssgi.comp" /> <None Include="res\Shaders\ssgi.comp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -299,6 +299,18 @@
<None Include="res\Shaders\ssgi.comp"> <None Include="res\Shaders\ssgi.comp">
<Filter>Resource Files\Shaders</Filter> <Filter>Resource Files\Shaders</Filter>
</None> </None>
<None Include="res\Shaders\cubemap.vert">
<Filter>Resource Files\Shaders</Filter>
</None>
<None Include="res\Shaders\cubemap.frag">
<Filter>Resource Files\Shaders</Filter>
</None>
<None Include="res\Shaders\skybox.vert">
<Filter>Resource Files\Shaders</Filter>
</None>
<None Include="res\Shaders\skybox.frag">
<Filter>Resource Files\Shaders</Filter>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtUic Include="EditorWidget.ui"> <QtUic Include="EditorWidget.ui">

View File

@ -24,6 +24,10 @@
<file>darkstyle.qss</file> <file>darkstyle.qss</file>
<file>lightstyle.qss</file> <file>lightstyle.qss</file>
<file>Shaders/element.comp</file> <file>Shaders/element.comp</file>
<file>Shaders/cubemap.frag</file>
<file>Shaders/cubemap.vert</file>
<file>Shaders/skybox.frag</file>
<file>Shaders/skybox.vert</file>
</qresource> </qresource>
<qresource prefix="/qt/etc"> <qresource prefix="/qt/etc">
<file>qt.conf</file> <file>qt.conf</file>

View File

@ -0,0 +1,22 @@
#version 450 core
out vec4 FragColor;
in vec3 WorldPos;
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(WorldPos));
vec3 color = texture(equirectangularMap, uv).rgb;
FragColor = vec4(color, 1.0);
}

View File

@ -0,0 +1,13 @@
#version 450 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);
}

View File

@ -70,90 +70,19 @@ void main()
//FragColor = vec4(vec3(depth*10000),1); //FragColor = vec4(vec3(depth*10000),1);
//FragColor = vec4(vec3(textureSize(gShadowMap, 0)-vec3(1)),1); //FragColor = vec4(vec3(textureSize(gShadowMap, 0)-vec3(1)),1);
//FragColor = vec4(texture(gRadiance, TexCoords).rgb, 1); //FragColor = vec4(texture(gRadiance, TexCoords).rgb, 1);
vec3 albedo = pow(texture(gBaseColor, TexCoords).rgb, vec3(2.2));
vec3 color = albedo * texture(gIndirectLight, TexCoords).rgb + texture(gDirectLight, TexCoords).rgb;
color = color / (color + vec3(1.0));
color = pow(color, vec3(1.0/2.2));
FragColor = vec4(color, 1.0);
return;
//vec3 albedo = pow(texture(gBaseColor, TexCoords).rgb, vec3(2.2));
//vec3 color = albedo * texture(gIndirectLight, TexCoords).rgb + texture(gDirectLight, TexCoords).rgb;
float metallic = texture(gMetallicRoughness, TexCoords).r; vec4 rgbm = texture(gBaseColor, TexCoords);
float roughness = texture(gMetallicRoughness, TexCoords).g; if(rgbm.a==0)
vec3 N = texture(gNormal, TexCoords).xyz;
vec3 WorldPos = texture(gPosition, TexCoords).xyz;
if(N==vec3(0))
{ {
vec3 color = mainLightRadiance; //FragColor = vec4(1,0,0,1);
//return;
discard;
}
vec3 color = 8 * rgbm.rgb * rgbm.a;
color = color / (color + vec3(1.0)); color = color / (color + vec3(1.0));
color = pow(color, vec3(1.0/2.2)); color = pow(color, vec3(1.0/2.2));
FragColor = vec4(color, 1.0); FragColor = vec4(color, 1.0);
return; return;
}
vec3 V = normalize(camPos - WorldPos);
vec3 F0 = vec3(0.04);
F0 = mix(F0, albedo, metallic);
// reflectance equation
vec3 Lo = vec3(0.0);
// calculate per-light radiance
vec3 L = normalize(mainLightDirection);
vec3 H = normalize(V + L);
//float distance = length(lightPositions[i] - WorldPos);
//float attenuation = 1.0 / (distance * distance);
vec3 radiance = mainLightRadiance ;//* attenuation;
// cook-torrance brdf
float NDF = DistributionGGX(N, H, roughness);
float G = GeometrySmith(N, V, L, roughness);
vec3 F = fresnelSchlick(clamp(dot(H, V),0.,1.), F0);
//F = clamp(F,vec3(0),vec3(1));
vec3 kS = F;
vec3 kD = vec3(1.0) - kS;
kD *= 1.0 - metallic;
vec3 nominator = NDF * G * F;
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.001;
vec3 specular = nominator / denominator;
// add to outgoing radiance Lo
float NdotL = max(dot(N, L), 0.0);
Lo += (kD * albedo / PI + specular) * radiance * NdotL;
vec3 ambient = vec3(0.03) * albedo;
//vec4 FragPosLightSpace = lightSpaceMatrix * vec4(WorldPos, 1.0);
//float bias = 0.08 * max(0.05 * (1.0 - dot(N, L)), 0.005);
//int debugLayer;
//float shadow = ShadowCalculation(WorldPos, N, debugLayer);
//vec3 color = ambient + Lo;
//vec3 color = indirect*1;
float directLight = texture(gDirectLight, TexCoords).r;
color = ambient + directLight * Lo;
//color*=mix(mix(vec3(1,0,0), vec3(0,1,0), float(debugLayer)/shadowCascadeCount/0.5),
//mix(vec3(0,1,0), vec3(0,0,1), float(debugLayer)/(shadowCascadeCount)/0.5-1), float(debugLayer)/(shadowCascadeCount));
//vec3 color = (1.0 - shadow) * Lo;
//vec3 color = (1.0 - shadow) * Lo + indirect*10;
color = color / (color + vec3(1.0));
color = pow(color, vec3(1.0/2.2));
FragColor = vec4(color, 1.0);
//FragColor = vec4(vec3(shadow), 1);
//FragColor = vec4(texture(gShadowNormal, TexCoords).rgb, 1.0);
} }

View File

@ -2,7 +2,8 @@
layout (local_size_x = 8, local_size_y = 8) in; layout (local_size_x = 8, local_size_y = 8) in;
uniform sampler2D gBaseColor; layout(rgba8, binding = 0) uniform image2D gBaseColor;
//uniform sampler2D gBaseColor;
uniform sampler2D gNormal; uniform sampler2D gNormal;
uniform sampler2D gPosition; uniform sampler2D gPosition;
uniform sampler2D gMetallicRoughness; uniform sampler2D gMetallicRoughness;
@ -132,11 +133,26 @@ float ShadowCalculation(vec3 fragPosWorldSpace, vec3 normal, out int layer)
return shadow; return shadow;
} }
vec4 encodeRGBM(vec3 color)
{
if(dot(color,color)==0)
return vec4(0,0,0,1);
vec4 rgbm;
float range = 8;
color /= range;
rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 1e-6)), 0.0, 1.0);
rgbm.a = ceil(rgbm.a * 255.0) / 255.0;
rgbm.rgb = color / rgbm.a;
return rgbm;
}
void main() void main()
{ {
ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy); ivec2 pixelLocation = ivec2(gl_GlobalInvocationID.xy);
vec3 albedo = pow(texelFetch(gBaseColor, pixelLocation, 0).rgb, vec3(2.2));
//vec3 albedo = pow(texelFetch(gBaseColor, pixelLocation, 0).rgb, vec3(2.2));
vec3 albedo = pow(imageLoad(gBaseColor, pixelLocation).rgb, vec3(2.2));
float metallic = texelFetch(gMetallicRoughness, pixelLocation, 0).r; float metallic = texelFetch(gMetallicRoughness, pixelLocation, 0).r;
float roughness = texelFetch(gMetallicRoughness, pixelLocation, 0).g; float roughness = texelFetch(gMetallicRoughness, pixelLocation, 0).g;
@ -145,12 +161,9 @@ void main()
if(normal==vec3(0)) if(normal==vec3(0))
{ {
vec3 color = mainLightRadiance; //vec3 color = mainLightRadiance;
//imageStore(gBaseColor, pixelLocation, vec4(color, 1.0));
//color = color / (color + vec3(1.0)); imageStore(gBaseColor, pixelLocation, vec4(0));
//color = pow(color, vec3(1.0/2.2));
imageStore(gDirectLight, pixelLocation, vec4(color, 1.0));
return; return;
} }
@ -187,5 +200,6 @@ void main()
int debugLayer; int debugLayer;
float shadow = ShadowCalculation(worldPos, normal, debugLayer); float shadow = ShadowCalculation(worldPos, normal, debugLayer);
imageStore(gDirectLight, pixelLocation, vec4((1-shadow)*Lo, 1)); vec3 color = (1-shadow)*Lo + albedo*0.03;
imageStore(gBaseColor, pixelLocation, encodeRGBM(color));
} }

View File

@ -0,0 +1,16 @@
#version 450 core
out vec4 FragColor;
in vec3 WorldPos;
uniform samplerCube environmentMap;
void main()
{
vec3 envColor = texture(environmentMap, WorldPos).rgb;
// HDR tonemap and gamma correct
envColor = envColor / (envColor + vec3(1.0));
envColor = pow(envColor, vec3(1.0/2.2));
FragColor = vec4(envColor, 1.0);
}

View File

@ -0,0 +1,17 @@
#version 450 core
layout (location = 0) in vec3 aPos;
uniform mat4 projection;
uniform mat4 view;
out vec3 WorldPos;
void main()
{
WorldPos = aPos;
mat4 rotView = mat4(mat3(view));
vec4 clipPos = projection * rotView * vec4(WorldPos, 1.0);
gl_Position = clipPos.xyww;
}

View File

@ -6,6 +6,10 @@
#include <QScreen> #include <QScreen>
#include <QGuiApplication> #include <QGuiApplication>
#include <random> #include <random>
#include <glm/gtc/matrix_transform.hpp>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
using namespace Renderer; using namespace Renderer;
//QVector3D lightPositions[] = { 2000 * QVector3D(0.2, 4, 1).normalized(), QVector3D(100,100,100) ,QVector3D(-100,100,100) ,QVector3D(100,100,-100) }; //QVector3D lightPositions[] = { 2000 * QVector3D(0.2, 4, 1).normalized(), QVector3D(100,100,100) ,QVector3D(-100,100,100) ,QVector3D(100,100,-100) };
QVector3D lightColors[] = { 20 * QVector3D(0.7529,0.7450,0.6784).normalized(), QVector3D(0,0,0) ,QVector3D(0,0,0) ,QVector3D(0,0,0) }; QVector3D lightColors[] = { 20 * QVector3D(0.7529,0.7450,0.6784).normalized(), QVector3D(0,0,0) ,QVector3D(0,0,0) ,QVector3D(0,0,0) };
@ -89,13 +93,180 @@ void RendererGLWidget::setMainLightYaw(float yaw)
sunYaw = yaw; sunYaw = yaw;
} }
QOpenGLTexture randomMap(QOpenGLTexture::Target2D); QOpenGLTexture randomMap(QOpenGLTexture::Target2D);
void renderCube(QOpenGLFunctions_4_5_Compatibility* glFunc)
{
static GLuint cubeVAO = 0, cubeVBO = 0;
// initialize (if necessary)
if (cubeVAO == 0)
{
float vertices[] = {
// back face
-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, // bottom-left
1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, // top-right
1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, // bottom-right
1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, // top-right
-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, // bottom-left
-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, // top-left
// front face
-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom-left
1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, // bottom-right
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // top-right
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // top-right
-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // top-left
-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom-left
// left face
-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-right
-1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top-left
-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-left
-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-left
-1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom-right
-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-right
// right face
1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-left
1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-right
1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top-right
1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // bottom-right
1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // top-left
1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom-left
// bottom face
-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, // top-right
1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, // top-left
1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom-left
1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom-left
-1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom-right
-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, // top-right
// top face
-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top-left
1.0f, 1.0f , 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom-right
1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top-right
1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom-right
-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top-left
-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f // bottom-left
};
glFunc->glGenVertexArrays(1, &cubeVAO);
glFunc->glGenBuffers(1, &cubeVBO);
// fill buffer
glFunc->glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glFunc->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// link vertex attributes
glFunc->glBindVertexArray(cubeVAO);
glFunc->glEnableVertexAttribArray(0);
glFunc->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glFunc->glEnableVertexAttribArray(1);
glFunc->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glFunc->glEnableVertexAttribArray(2);
glFunc->glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glFunc->glBindBuffer(GL_ARRAY_BUFFER, 0);
glFunc->glBindVertexArray(0);
}
// render Cube
glFunc->glBindVertexArray(cubeVAO);
glFunc->glDrawArrays(GL_TRIANGLES, 0, 36);
glFunc->glBindVertexArray(0);
}
GLuint generateCubemap(QOpenGLFunctions_4_5_Compatibility* glFunc)
{
QOpenGLShaderProgram shader;
if (!shader.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/cubemap.vert"))
qDebug() << "ERROR:" << shader.log();
if (!shader.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/cubemap.frag"))
qDebug() << "ERROR:" << shader.log();
if (!shader.link())
qDebug() << "ERROR:" << shader.log();
// pbr: setup framebuffer
// ----------------------
unsigned int captureFBO;
unsigned int captureRBO;
glFunc->glGenFramebuffers(1, &captureFBO);
glFunc->glGenRenderbuffers(1, &captureRBO);
glFunc->glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
glFunc->glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
glFunc->glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 1024, 1024);
glFunc->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO);
// pbr: load the HDR environment map
// ---------------------------------
stbi_set_flip_vertically_on_load(true);
int width, height, nrComponents;
float* data = stbi_loadf("HDRI/clarens_midday_4k.hdr", &width, &height, &nrComponents, 0);
unsigned int hdrTexture;
if (data)
{
glGenTextures(1, &hdrTexture);
glBindTexture(GL_TEXTURE_2D, hdrTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
stbi_image_free(data);
}
else
std::cout << "Failed to load HDR image." << std::endl;
// pbr: setup cubemap to render to and attach to framebuffer
// ---------------------------------------------------------
unsigned int envCubemap;
glFunc->glGenTextures(1, &envCubemap);
glFunc->glBindTexture(GL_TEXTURE_CUBE_MAP, envCubemap);
for (unsigned int i = 0; i < 6; ++i)
{
glFunc->glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 512, 512, 0, GL_RGB, GL_FLOAT, nullptr);
}
glFunc->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glFunc->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFunc->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glFunc->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glFunc->glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// pbr: set up projection and view matrices for capturing data onto the 6 cubemap face directions
// ----------------------------------------------------------------------------------------------
QMatrix4x4 captureProjection;
captureProjection.perspective(90.0f, 1.0f, 0.1f, 10.0f);
QMatrix4x4 captureViews[6];
captureViews[0].lookAt(QVector3D(0.0f, 0.0f, 0.0f), QVector3D( 1.0f, 0.0f, 0.0f), QVector3D(0.0f, -1.0f, 0.0f));
captureViews[1].lookAt(QVector3D(0.0f, 0.0f, 0.0f), QVector3D(-1.0f, 0.0f, 0.0f), QVector3D(0.0f, -1.0f, 0.0f));
captureViews[2].lookAt(QVector3D(0.0f, 0.0f, 0.0f), QVector3D( 0.0f, 1.0f, 0.0f), QVector3D(0.0f, 0.0f, 1.0f));
captureViews[3].lookAt(QVector3D(0.0f, 0.0f, 0.0f), QVector3D( 0.0f, -1.0f, 0.0f), QVector3D(0.0f, 0.0f, -1.0f));
captureViews[4].lookAt(QVector3D(0.0f, 0.0f, 0.0f), QVector3D( 0.0f, 0.0f, 1.0f), QVector3D(0.0f, -1.0f, 0.0f));
captureViews[5].lookAt(QVector3D(0.0f, 0.0f, 0.0f), QVector3D( 0.0f, 0.0f, -1.0f), QVector3D(0.0f, -1.0f, 0.0f));
// pbr: convert HDR equirectangular environment map to cubemap equivalent
// ----------------------------------------------------------------------
shader.bind();
shader.setUniformValue("equirectangularMap", 0);
shader.setUniformValue("projection", captureProjection);
glFunc->glActiveTexture(GL_TEXTURE0);
glFunc->glBindTexture(GL_TEXTURE_2D, hdrTexture);
glFunc->glViewport(0, 0, 512, 512); // don't forget to configure the viewport to the capture dimensions.
glFunc->glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
for (unsigned int i = 0; i < 6; ++i)
{
shader.setUniformValue("view", captureViews[i]);
glFunc->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, envCubemap, 0);
glFunc->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
renderCube(glFunc);
}
glFunc->glBindFramebuffer(GL_FRAMEBUFFER, 0);
return envCubemap;
}
void RendererGLWidget::initializeGL() void RendererGLWidget::initializeGL()
{ {
initializeOpenGLFunctions(); initializeOpenGLFunctions();
qDebug() << "GL_VERSION" << (char*)glGetString(GL_VERSION); qDebug() << "GL_VERSION" << (char*)glGetString(GL_VERSION);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE); glDepthFunc(GL_LEQUAL);
glClearColor(0, 0, 0, 1); glClearColor(0, 0, 0, 1);
shadowProgramPtr = new QOpenGLShaderProgram; shadowProgramPtr = new QOpenGLShaderProgram;
@ -162,6 +333,13 @@ void RendererGLWidget::initializeGL()
if (!finalProgramPtr->link()) if (!finalProgramPtr->link())
qDebug() << "ERROR:" << finalProgramPtr->log(); qDebug() << "ERROR:" << finalProgramPtr->log();
skyBoxProgramPtr = new QOpenGLShaderProgram;
if (!skyBoxProgramPtr->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/Shaders/skybox.vert"))
qDebug() << "ERROR:" << skyBoxProgramPtr->log();
if (!skyBoxProgramPtr->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/Shaders/skybox.frag"))
qDebug() << "ERROR:" << skyBoxProgramPtr->log();
if (!skyBoxProgramPtr->link())
qDebug() << "ERROR:" << skyBoxProgramPtr->log();
shadowProgramPtr->bind(); shadowProgramPtr->bind();
glGenBuffers(1, &lightSpaceMatricesUBO); glGenBuffers(1, &lightSpaceMatricesUBO);
@ -177,7 +355,7 @@ void RendererGLWidget::initializeGL()
depthInitProgramPtr->release(); depthInitProgramPtr->release();
shadowMappingProgramPtr->bind(); shadowMappingProgramPtr->bind();
shadowMappingProgramPtr->setUniformValue("gBaseColor", 0); //shadowMappingProgramPtr->setUniformValue("gBaseColor", 0);
shadowMappingProgramPtr->setUniformValue("gNormal", 1); shadowMappingProgramPtr->setUniformValue("gNormal", 1);
shadowMappingProgramPtr->setUniformValue("gPosition", 2); shadowMappingProgramPtr->setUniformValue("gPosition", 2);
shadowMappingProgramPtr->setUniformValue("gMetallicRoughness", 3); shadowMappingProgramPtr->setUniformValue("gMetallicRoughness", 3);
@ -229,6 +407,11 @@ void RendererGLWidget::initializeGL()
paintingHelper = new PaintingHelper(QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Compatibility>()); paintingHelper = new PaintingHelper(QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Compatibility>());
model = new Model(context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper); model = new Model(context(), modelProgramPtr, paintingProgramPtr, shadowProgramPtr, paintingHelper);
skyBoxProgramPtr->bind();
skyBoxProgramPtr->setUniformValue("environmentMap", 0);
skyBoxProgramPtr->release();
skyCubemap = generateCubemap(QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Compatibility>());
quadVAO.create(); quadVAO.create();
QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO); QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO);
@ -259,6 +442,7 @@ void RendererGLWidget::initializeGL()
void RendererGLWidget::paintGL() void RendererGLWidget::paintGL()
{ {
glEnable(GL_CULL_FACE);
light.lightDirection.setX(cos(qDegreesToRadians(sunPitch)) * cos(qDegreesToRadians(sunYaw))); light.lightDirection.setX(cos(qDegreesToRadians(sunPitch)) * cos(qDegreesToRadians(sunYaw)));
light.lightDirection.setY(sin(qDegreesToRadians(sunPitch))); light.lightDirection.setY(sin(qDegreesToRadians(sunPitch)));
@ -266,13 +450,13 @@ void RendererGLWidget::paintGL()
light.lightDirection.normalize(); light.lightDirection.normalize();
const std::vector<QMatrix4x4> lightMatrices = light.getLightSpaceMatrices(); const std::vector<QMatrix4x4> lightMatrices = light.getLightSpaceMatrices();
//qDebug() << lightMatrices;
glBindBuffer(GL_UNIFORM_BUFFER, lightSpaceMatricesUBO); glBindBuffer(GL_UNIFORM_BUFFER, lightSpaceMatricesUBO);
for (size_t i = 0; i < lightMatrices.size(); i++) for (size_t i = 0; i < lightMatrices.size(); i++)
{ {
glBufferSubData(GL_UNIFORM_BUFFER, i * 16 * sizeof(GLfloat), 16 * sizeof(GLfloat), lightMatrices[i].data()); glBufferSubData(GL_UNIFORM_BUFFER, i * 16 * sizeof(GLfloat), 16 * sizeof(GLfloat), lightMatrices[i].data());
} }
glBindBuffer(GL_UNIFORM_BUFFER, 0); glBindBuffer(GL_UNIFORM_BUFFER, 0);
{ {
glBindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle); glBindFramebuffer(GL_FRAMEBUFFER, shadowFboHandle);
glViewport(0, 0, shadowMapResolution, shadowMapResolution); glViewport(0, 0, shadowMapResolution, shadowMapResolution);
@ -303,7 +487,6 @@ void RendererGLWidget::paintGL()
if (model != nullptr) if (model != nullptr)
model->draw(); model->draw();
fboPtr->release(); fboPtr->release();
} }
@ -350,8 +533,8 @@ void RendererGLWidget::paintGL()
shadowMappingProgramPtr->setUniformValue("camPos", camera.Position); shadowMappingProgramPtr->setUniformValue("camPos", camera.Position);
shadowMappingProgramPtr->setUniformValue("mainLightDirection", light.lightDirection); shadowMappingProgramPtr->setUniformValue("mainLightDirection", light.lightDirection);
shadowMappingProgramPtr->setUniformValue("mainLightRadiance", lightColors[0]); shadowMappingProgramPtr->setUniformValue("mainLightRadiance", lightColors[0]);
glActiveTexture(GL_TEXTURE0); /*glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gbuffers[0]); glBindTexture(GL_TEXTURE_2D, gbuffers[0]);*/
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gbuffers[1]); glBindTexture(GL_TEXTURE_2D, gbuffers[1]);
glActiveTexture(GL_TEXTURE2); glActiveTexture(GL_TEXTURE2);
@ -360,11 +543,12 @@ void RendererGLWidget::paintGL()
glBindTexture(GL_TEXTURE_2D, gbuffers[3]); glBindTexture(GL_TEXTURE_2D, gbuffers[3]);
glActiveTexture(GL_TEXTURE4); glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer); glBindTexture(GL_TEXTURE_2D_ARRAY, shadowGbuffer);
glBindImageTexture(0, gbuffers[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
glBindImageTexture(1, gbuffers[8], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA16F); glBindImageTexture(1, gbuffers[8], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA16F);
glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1); glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
shadowMappingProgramPtr->release(); shadowMappingProgramPtr->release();
ssgiProgramPtr->bind(); /*ssgiProgramPtr->bind();
ssgiProgramPtr->setUniformValue("camPos", camera.Position); ssgiProgramPtr->setUniformValue("camPos", camera.Position);
ssgiProgramPtr->setUniformValue("cameraMatrix", projection * view); ssgiProgramPtr->setUniformValue("cameraMatrix", projection * view);
ssgiProgramPtr->setUniformValue("projectionMatrix", projection); ssgiProgramPtr->setUniformValue("projectionMatrix", projection);
@ -386,11 +570,11 @@ void RendererGLWidget::paintGL()
glBindTexture(GL_TEXTURE_2D, gbuffers[8]); glBindTexture(GL_TEXTURE_2D, gbuffers[8]);
glBindImageTexture(1, gbuffers[9], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA16F); glBindImageTexture(1, gbuffers[9], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA16F);
glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1); glDispatchCompute(ceil(frameWidth / 8.), ceil(frameHeight / 8.), 1);
ssgiProgramPtr->release(); ssgiProgramPtr->release();*/
glViewport(0, 0, frameWidth, frameHeight); glViewport(0, 0, frameWidth, frameHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO); //QOpenGLVertexArrayObject::Binder vaoBinder(&quadVAO);
finalProgramPtr->bind(); finalProgramPtr->bind();
/*finalProgramPtr->setUniformValue("camPos", camera.Position); /*finalProgramPtr->setUniformValue("camPos", camera.Position);
finalProgramPtr->setUniformValue("mainLightDirection", light.lightDirection); finalProgramPtr->setUniformValue("mainLightDirection", light.lightDirection);
@ -411,9 +595,20 @@ void RendererGLWidget::paintGL()
//glBindTexture(GL_TEXTURE_2D, gbuffers[7]); //glBindTexture(GL_TEXTURE_2D, gbuffers[7]);
//glActiveTexture(GL_TEXTURE5); //glActiveTexture(GL_TEXTURE5);
//glBindTexture(GL_TEXTURE_2D, gbuffers[8]); //glBindTexture(GL_TEXTURE_2D, gbuffers[8]);
quadVAO.bind();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
quadVAO.release();
finalProgramPtr->release(); finalProgramPtr->release();
skyBoxProgramPtr->bind();
glDisable(GL_CULL_FACE);
skyBoxProgramPtr->setUniformValue("view", view);
skyBoxProgramPtr->setUniformValue("projection", projection);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, skyCubemap);
renderCube(QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_4_5_Compatibility>());
skyBoxProgramPtr->release();
GLuint paintingCompDuration; GLuint paintingCompDuration;
glGetQueryObjectuiv(paintingCompQuery, GL_QUERY_RESULT, &paintingCompDuration); glGetQueryObjectuiv(paintingCompQuery, GL_QUERY_RESULT, &paintingCompDuration);

View File

@ -57,11 +57,13 @@ namespace Renderer
QOpenGLShaderProgram* shadowMappingProgramPtr = nullptr; QOpenGLShaderProgram* shadowMappingProgramPtr = nullptr;
QOpenGLShaderProgram* ssgiProgramPtr = nullptr; QOpenGLShaderProgram* ssgiProgramPtr = nullptr;
QOpenGLShaderProgram* finalProgramPtr = nullptr; QOpenGLShaderProgram* finalProgramPtr = nullptr;
QOpenGLShaderProgram* skyBoxProgramPtr = nullptr;
QOpenGLFramebufferObject* fboPtr = nullptr; QOpenGLFramebufferObject* fboPtr = nullptr;
GLuint gbuffers[10]; GLuint gbuffers[10];
GLuint shadowFboHandle = 0; GLuint shadowFboHandle = 0;
GLuint shadowGbuffer; GLuint shadowGbuffer;
GLuint lightSpaceMatricesUBO; GLuint lightSpaceMatricesUBO;
GLuint skyCubemap;
QOpenGLBuffer quadVBO; QOpenGLBuffer quadVBO;
QOpenGLVertexArrayObject quadVAO; QOpenGLVertexArrayObject quadVAO;
Model* model = nullptr; Model* model = nullptr;