4#include "SEnvironmentMgr.h"
6#include "../AssetsDef.h"
9#include "../CaptureDef.h"
13#include "../Loader/STB/stb_image.h"
15#include "../Settings.h"
16#include "../GLProgramHandle.h"
20unsigned int SEnvironmentMgr::m_width = 0;
21unsigned int SEnvironmentMgr::m_height = 0;
22unsigned int SEnvironmentMgr::m_planeVAO = 0;
23unsigned int SEnvironmentMgr::m_cubeVAO = 0;
25SEnvironmentMgr::SEnvironmentMgr() {
29SEnvironmentMgr::~SEnvironmentMgr() {
30 glDeleteVertexArrays(1, &m_cubeVAO);
31 glDeleteBuffers(1, &m_cubeVBO);
32 glDeleteVertexArrays(1, &m_planeVAO);
33 glDeleteBuffers(1, &m_planeVBO);
36void SEnvironmentMgr::RenderPBREnvironment() {
38 std::string cubemap_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() +
"Shader/PBR/IBL/cubemap.vert");
39 std::string etc_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() +
"Shader/PBR/IBL/equirectangular_to_cubemap.frag");
40 std::string irr_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() +
"Shader/PBR/IBL/irradiance_convolution.frag");
41 std::string pre_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() +
"Shader/PBR/IBL/prefilter.frag");
42 std::string brdf_v_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() +
"Shader/PBR/IBL/brdf.vert");
43 std::string brdf_f_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() +
"Shader/PBR/IBL/brdf.frag");
53 unsigned int captureFBO;
54 unsigned int captureRBO;
56 glDisable(GL_CULL_FACE);
58 glGenRenderbuffers(1, &captureRBO);
59 glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
60 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 512, 512);
62 glGenFramebuffers(1, &captureFBO);
63 glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
64 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
65 GL_RENDERBUFFER, captureRBO);
69 stbi_set_flip_vertically_on_load(
true);
70 std::string hdr_path = CSE::AssetsPath() +
"Texture/hdr/newport_loft.hdr";
71 m_hdrTexture = SResource::Create<STexture>(hdr_path);
72 stbi_set_flip_vertically_on_load(
false);
76 m_envCubemap =
new STexture(STexture::TEX_CUBE);
77 m_envCubemap->SetName(
"envCubemap.textureCubeMap");
78 m_envCubemap->SetAbsoluteID(
"envCubemap.textureCubeMap");
79 std::string hash =
"CSEENV0000000001";
80 m_envCubemap->SetHash(hash);
81 m_envCubemap->InitTextureMipmap(512, 512);
86 mat4 captureProjection = mat4::Perspective(90.0f, 1.0f, 0.1f, 10.0f);
89 mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f),
vec3(1.0f, 0.0f, 0.0f),
vec3(0.0f, -1.0f, 0.0f)),
90 mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f),
vec3(-1.0f, 0.0f, 0.0f),
vec3(0.0f, -1.0f, 0.0f)),
91 mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f),
vec3(0.0f, 1.0f, 0.0f),
vec3(0.0f, 0.0f, 1.0f)),
92 mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f),
vec3(0.0f, -1.0f, 0.0f),
vec3(0.0f, 0.0f, -1.0f)),
93 mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f),
vec3(0.0f, 0.0f, 1.0f),
vec3(0.0f, -1.0f, 0.0f)),
94 mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f),
vec3(0.0f, 0.0f, -1.0f),
vec3(0.0f, -1.0f, 0.0f))
99 glUseProgram(m_equirectangularToCubemapShader->Program);
100 int hdrTextureLocation = m_equirectangularToCubemapShader->UniformLocation(
"EquirectangularMap")->id;
101 m_equirectangularToCubemapShader->SetUniformMat4(
"PROJECTION_MATRIX", captureProjection);
103 m_hdrTexture->Bind(hdrTextureLocation, 0);
107 glViewport(0, 0, 512, 512);
108 glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
109 std::cout <<
"[PBR] Generating Environment Cubemap...";
110 for (
unsigned int i = 0; i < 6; ++i) {
111 m_equirectangularToCubemapShader->SetUniformMat4(
"VIEW_MATRIX", captureViews[i]);
113 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
114 m_envCubemap->GetTextureID(), 0);
116 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
121 m_envCubemap->GenerateMipmap();
123 std::cout <<
" finished!\n";
127 m_irradianceMap =
new STexture(STexture::TEX_CUBE);
128 m_irradianceMap->SetName(
"irradiance.textureCubeMap");
129 m_irradianceMap->SetAbsoluteID(
"irradiance.textureCubeMap");
130 hash =
"CSEENV0000000002";
131 m_irradianceMap->SetHash(hash);
132 m_irradianceMap->InitTexture(32, 32);
134 glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
135 glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
136 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 32, 32);
140 glUseProgram(m_irradianceShader->Program);
141 int envTextureLocation = m_irradianceShader->UniformLocation(
"EnvironmentMap")->id;
142 m_irradianceShader->SetUniformMat4(
"PROJECTION_MATRIX", captureProjection);
143 m_envCubemap->Bind(envTextureLocation, 0);
145 glViewport(0, 0, 32, 32);
146 glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
147 std::cout <<
"[PBR] Generating Irradiance Cubemap...";
148 for (
unsigned int i = 0; i < 6; ++i) {
149 m_irradianceShader->SetUniformMat4(
"VIEW_MATRIX", captureViews[i]);
151 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
152 m_irradianceMap->GetTextureID(), 0);
154 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
158 std::cout <<
" finished!\n";
162 m_prefilterMap =
new STexture(STexture::TEX_CUBE);
163 m_prefilterMap->SetName(
"prefilter.textureCubeMap");
164 m_prefilterMap->SetAbsoluteID(
"prefilter.textureCubeMap");
165 hash =
"CSEENV0000000003";
166 m_prefilterMap->SetHash(hash);
167 m_prefilterMap->InitTextureMipmap(128, 128);
170 m_prefilterMap->GenerateMipmap();
174 glUseProgram(m_prefilterShader->Program);
175 envTextureLocation = m_prefilterShader->UniformLocation(
"EnvironmentMap")->id;
176 m_prefilterShader->SetUniformMat4(
"PROJECTION_MATRIX", captureProjection);
177 m_envCubemap->Bind(envTextureLocation, 0);
180 glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
181 unsigned int maxMipLevels = 5;
183 std::cout <<
"[PBR] Backing Prefiltering Textures...";
184 for (
unsigned int mip = 0; mip < maxMipLevels; ++mip) {
186 unsigned int mipWidth = 128 * std::pow(0.5, mip);
187 unsigned int mipHeight = 128 * std::pow(0.5, mip);
188 glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
189 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mipWidth, mipHeight);
190 glViewport(0, 0, mipWidth, mipHeight);
192 float roughness = (float) mip / (
float) (maxMipLevels - 1);
193 m_prefilterShader->SetUniformFloat(
"FLOAT_ROUGHNESS", roughness);
194 for (
unsigned int i = 0; i < 6; ++i) {
195 m_prefilterShader->SetUniformMat4(
"VIEW_MATRIX", captureViews[i]);
196 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
197 m_prefilterMap->GetTextureID(), mip);
200 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
205 std::cout <<
"Level " << mip <<
"..";
207 std::cout <<
" finished!\n";
211 std::cout <<
"[PBR] Backing a 2D LUT from the BRDF equations used...";
213 m_brdfMap->SetName(
"brdfLUT.texture");
214 m_brdfMap->SetAbsoluteID(
"brdfLUT.texture");
215 hash =
"CSEENV0000000004";
216 m_brdfMap->SetHash(hash);
217 m_brdfMap->InitTexture(512, 512, GL_RG, GL_RG16F, GL_FLOAT);
220 glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);
221 glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);
222 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 512, 512);
223 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_brdfMap->GetTextureID(), 0);
225 glViewport(0, 0, 512, 512);
226 glUseProgram(m_brdfShader->Program);
227 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
233 std::cout <<
" finished!\n";
236 glDeleteFramebuffers(1, &captureFBO);
237 glDeleteRenderbuffers(1, &captureRBO);
239 glBindFramebuffer(GL_FRAMEBUFFER, 0);
240 glEnable(GL_CULL_FACE);
243void SEnvironmentMgr::LoadCubeVAO() {
246 -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
247 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
248 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
249 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
250 -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
251 -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
253 -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
254 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
255 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
256 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
257 -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
258 -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
260 -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
261 -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
262 -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
263 -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
264 -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
265 -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
267 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
268 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
269 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
270 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
271 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
272 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
274 -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
275 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
276 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
277 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
278 -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
279 -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
281 -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
282 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
283 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
284 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
285 -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
286 -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f
288 glGenVertexArrays(1, &m_cubeVAO);
289 glGenBuffers(1, &m_cubeVBO);
291 glBindBuffer(GL_ARRAY_BUFFER, m_cubeVBO);
292 glBufferData(GL_ARRAY_BUFFER,
sizeof(vertices), vertices, GL_STATIC_DRAW);
294 glBindVertexArray(m_cubeVAO);
295 glEnableVertexAttribArray(0);
296 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 *
sizeof(
float), (
void*) 0);
297 glEnableVertexAttribArray(1);
298 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 *
sizeof(
float), (
void*)(3 *
sizeof(
float)));
299 glEnableVertexAttribArray(2);
300 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 *
sizeof(
float), (
void*)(6 *
sizeof(
float)));
301 glBindBuffer(GL_ARRAY_BUFFER, 0);
302 glBindVertexArray(0);
305void SEnvironmentMgr::RenderCubeVAO() {
307 glBindVertexArray(m_cubeVAO);
308 glDrawArrays(GL_TRIANGLES, 0, 36);
309 glBindVertexArray(0);
312void SEnvironmentMgr::LoadPlaneVAO() {
313 float quadVertices[] = {
315 -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
316 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
317 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
318 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
321 glGenVertexArrays(1, &m_planeVAO);
322 glGenBuffers(1, &m_planeVBO);
323 glBindVertexArray(m_planeVAO);
324 glBindBuffer(GL_ARRAY_BUFFER, m_planeVBO);
325 glBufferData(GL_ARRAY_BUFFER,
sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
326 glEnableVertexAttribArray(0);
327 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 *
sizeof(
float), (
void*) 0);
328 glEnableVertexAttribArray(1);
329 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 *
sizeof(
float), (
void*) (3 *
sizeof(
float)));
332void SEnvironmentMgr::RenderPlaneVAO() {
333 glBindVertexArray(m_planeVAO);
334 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
335 glBindVertexArray(0);
338unsigned int SEnvironmentMgr::GetWidth() {
342void SEnvironmentMgr::SetWidth(
unsigned int width) {
346unsigned int SEnvironmentMgr::GetHeight() {
350void SEnvironmentMgr::SetHeight(
unsigned int height) {
354unsigned int* SEnvironmentMgr::GetPointerWidth() {
358unsigned int* SEnvironmentMgr::GetPointerHeight() {
362void SEnvironmentMgr::BindPBREnvironmentMap(
const GLProgramHandle* handle,
int textureLayout)
const {
363 if(handle ==
nullptr)
return;
364 m_irradianceMap->Bind(handle->Uniforms.LightIrradiance, textureLayout);
365 m_prefilterMap->Bind(handle->Uniforms.LightPrefilter, textureLayout + 1);
366 m_brdfMap->Bind(handle->Uniforms.LightBrdfLut, textureLayout + 2);
static GLProgramHandle * CreateProgramHandle(const GLchar *vertexSource, const GLchar *fragmentSource, GLProgramHandle *handle=nullptr)
Creates a program handle.