4#include "SEnvironmentMgr.h"
6#include "../AssetsDef.h"
12#include "../Loader/STB/stb_image.h"
14#include "../Settings.h"
15#include "../GLProgramHandle.h"
19unsigned int SEnvironmentMgr::m_width = 0;
20unsigned int SEnvironmentMgr::m_height = 0;
21unsigned int SEnvironmentMgr::m_planeVAO = 0;
22unsigned int SEnvironmentMgr::m_cubeVAO = 0;
24SEnvironmentMgr::SEnvironmentMgr() {
27SEnvironmentMgr::~SEnvironmentMgr() {
28 glDeleteBuffers(1, &m_cubeVBO);
29 glDeleteBuffers(1, &m_planeVBO);
32void SEnvironmentMgr::RenderPBREnvironment() {
34 std::string cubemap_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() +
"Shader/PBR/IBL/cubemap.vert");
35 std::string etc_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() +
"Shader/PBR/IBL/equirectangular_to_cubemap.frag");
36 std::string irr_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() +
"Shader/PBR/IBL/irradiance_convolution.frag");
37 std::string pre_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() +
"Shader/PBR/IBL/prefilter.frag");
45 glDisable(GL_CULL_FACE);
47 glGenRenderbuffers(1, &m_captureRBO);
48 glBindRenderbuffer(GL_RENDERBUFFER, m_captureRBO);
49 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 512, 512);
51 glGenFramebuffers(1, &m_captureFBO);
52 glBindFramebuffer(GL_FRAMEBUFFER, m_captureFBO);
53 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
54 GL_RENDERBUFFER, m_captureRBO);
58 stbi_set_flip_vertically_on_load(
true);
59 std::string hdr_path = CSE::AssetsPath() +
"Texture/hdr/newport_loft.hdr";
60 m_hdrTexture = SResource::Create<STexture>(hdr_path);
61 stbi_set_flip_vertically_on_load(
false);
65 m_envCubemap =
new STexture(STexture::TEX_CUBE);
66 m_envCubemap->SetName(
"envCubemap.textureCubeMap");
67 m_envCubemap->SetAbsoluteID(
"envCubemap.textureCubeMap");
68 std::string hash =
"CSEENV0000000001";
69 m_envCubemap->SetHash(hash);
70 m_envCubemap->InitTextureMipmap(512, 512);
75 mat4 captureProjection = mat4::Perspective(90.0f, 1.0f, 0.1f, 10.0f);
78 mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f),
vec3(1.0f, 0.0f, 0.0f),
vec3(0.0f, -1.0f, 0.0f)),
79 mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f),
vec3(-1.0f, 0.0f, 0.0f),
vec3(0.0f, -1.0f, 0.0f)),
80 mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f),
vec3(0.0f, 1.0f, 0.0f),
vec3(0.0f, 0.0f, 1.0f)),
81 mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f),
vec3(0.0f, -1.0f, 0.0f),
vec3(0.0f, 0.0f, -1.0f)),
82 mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f),
vec3(0.0f, 0.0f, 1.0f),
vec3(0.0f, -1.0f, 0.0f)),
83 mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f),
vec3(0.0f, 0.0f, -1.0f),
vec3(0.0f, -1.0f, 0.0f))
88 glUseProgram(m_equirectangularToCubemapShader->Program);
89 int hdrTextureLocation = m_equirectangularToCubemapShader->UniformLocation(
"EquirectangularMap")->id;
90 m_equirectangularToCubemapShader->SetUniformMat4(
"PROJECTION_MATRIX", captureProjection);
92 m_hdrTexture->Bind(hdrTextureLocation, 0);
94 if(m_cubeVAO <= 0) LoadCubeVAO();
96 glViewport(0, 0, 512, 512);
97 glBindFramebuffer(GL_FRAMEBUFFER, m_captureFBO);
98 std::cout <<
"[PBR] Generating Environment Cubemap...";
99 for (
unsigned int i = 0; i < 6; ++i) {
100 m_equirectangularToCubemapShader->SetUniformMat4(
"VIEW_MATRIX", captureViews[i]);
102 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
103 m_envCubemap->GetTextureID(), 0);
105 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
110 m_envCubemap->GenerateMipmap();
112 std::cout <<
" finished!\n";
116 m_irradianceMap =
new STexture(STexture::TEX_CUBE);
117 m_irradianceMap->SetName(
"irradiance.textureCubeMap");
118 m_irradianceMap->SetAbsoluteID(
"irradiance.textureCubeMap");
119 hash =
"CSEENV0000000002";
120 m_irradianceMap->SetHash(hash);
121 m_irradianceMap->InitTexture(32, 32);
123 glBindFramebuffer(GL_FRAMEBUFFER, m_captureFBO);
124 glBindRenderbuffer(GL_RENDERBUFFER, m_captureRBO);
125 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 32, 32);
129 glUseProgram(m_irradianceShader->Program);
130 int envTextureLocation = m_irradianceShader->UniformLocation(
"EnvironmentMap")->id;
131 m_irradianceShader->SetUniformMat4(
"PROJECTION_MATRIX", captureProjection);
132 m_envCubemap->Bind(envTextureLocation, 0);
134 glViewport(0, 0, 32, 32);
135 glBindFramebuffer(GL_FRAMEBUFFER, m_captureFBO);
136 std::cout <<
"[PBR] Generating Irradiance Cubemap...";
137 for (
unsigned int i = 0; i < 6; ++i) {
138 m_irradianceShader->SetUniformMat4(
"VIEW_MATRIX", captureViews[i]);
140 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
141 m_irradianceMap->GetTextureID(), 0);
143 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
147 std::cout <<
" finished!\n";
151 m_prefilterMap =
new STexture(STexture::TEX_CUBE);
152 m_prefilterMap->SetName(
"prefilter.textureCubeMap");
153 m_prefilterMap->SetAbsoluteID(
"prefilter.textureCubeMap");
154 hash =
"CSEENV0000000003";
155 m_prefilterMap->SetHash(hash);
156 m_prefilterMap->InitTextureMipmap(128, 128);
159 m_prefilterMap->GenerateMipmap();
163 glUseProgram(m_prefilterShader->Program);
164 envTextureLocation = m_prefilterShader->UniformLocation(
"EnvironmentMap")->id;
165 m_prefilterShader->SetUniformMat4(
"PROJECTION_MATRIX", captureProjection);
166 m_envCubemap->Bind(envTextureLocation, 0);
169 glBindFramebuffer(GL_FRAMEBUFFER, m_captureFBO);
170 unsigned int maxMipLevels = 5;
172 std::cout <<
"[PBR] Backing Prefiltering Textures...";
173 for (
unsigned int mip = 0; mip < maxMipLevels; ++mip) {
175 unsigned int mipWidth = 128 * std::pow(0.5, mip);
176 unsigned int mipHeight = 128 * std::pow(0.5, mip);
177 glBindRenderbuffer(GL_RENDERBUFFER, m_captureRBO);
178 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mipWidth, mipHeight);
179 glViewport(0, 0, mipWidth, mipHeight);
181 float roughness = (float) mip / (
float) (maxMipLevels - 1);
182 m_prefilterShader->SetUniformFloat(
"FLOAT_ROUGHNESS", roughness);
183 for (
unsigned int i = 0; i < 6; ++i) {
184 m_prefilterShader->SetUniformMat4(
"VIEW_MATRIX", captureViews[i]);
185 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
186 m_prefilterMap->GetTextureID(), mip);
189 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
194 std::cout <<
"Level " << mip <<
"..";
196 std::cout <<
" finished!\n";
199void SEnvironmentMgr::LoadCubeVAO() {
202 -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
203 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
204 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
205 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
206 -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
207 -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
209 -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
210 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
211 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
212 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
213 -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
214 -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
216 -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
217 -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
218 -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
219 -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
220 -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
221 -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
223 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
224 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
225 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
226 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
227 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
228 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
230 -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
231 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
232 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
233 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
234 -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
235 -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
237 -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
238 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
239 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
240 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
241 -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
242 -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f
244 glGenVertexArrays(1, &m_cubeVAO);
245 glGenBuffers(1, &m_cubeVBO);
247 glBindBuffer(GL_ARRAY_BUFFER, m_cubeVBO);
248 glBufferData(GL_ARRAY_BUFFER,
sizeof(vertices), vertices, GL_STATIC_DRAW);
250 glBindVertexArray(m_cubeVAO);
251 glEnableVertexAttribArray(0);
252 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 *
sizeof(
float), (
void*) 0);
253 glEnableVertexAttribArray(1);
254 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 *
sizeof(
float), (
void*)(3 *
sizeof(
float)));
255 glEnableVertexAttribArray(2);
256 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 *
sizeof(
float), (
void*)(6 *
sizeof(
float)));
257 glBindBuffer(GL_ARRAY_BUFFER, 0);
258 glBindVertexArray(0);
261void SEnvironmentMgr::RenderCubeVAO() {
263 glBindVertexArray(m_cubeVAO);
264 glDrawArrays(GL_TRIANGLES, 0, 36);
265 glBindVertexArray(0);
268void SEnvironmentMgr::LoadPlaneVAO() {
269 float quadVertices[] = {
271 -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
272 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
273 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
274 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
277 glGenVertexArrays(1, &m_planeVAO);
278 glGenBuffers(1, &m_planeVBO);
279 glBindVertexArray(m_planeVAO);
280 glBindBuffer(GL_ARRAY_BUFFER, m_planeVBO);
281 glBufferData(GL_ARRAY_BUFFER,
sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
282 glEnableVertexAttribArray(0);
283 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 *
sizeof(
float), (
void*) 0);
284 glEnableVertexAttribArray(1);
285 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 *
sizeof(
float), (
void*) (3 *
sizeof(
float)));
288void SEnvironmentMgr::RenderPlaneVAO() {
289 glBindVertexArray(m_planeVAO);
290 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
291 glBindVertexArray(0);
294unsigned int SEnvironmentMgr::GetWidth() {
298void SEnvironmentMgr::SetWidth(
unsigned int width) {
302unsigned int SEnvironmentMgr::GetHeight() {
306void SEnvironmentMgr::SetHeight(
unsigned int height) {
310unsigned int* SEnvironmentMgr::GetPointerWidth() {
314unsigned int* SEnvironmentMgr::GetPointerHeight() {
318int SEnvironmentMgr::BindPBREnvironmentMap(
const GLProgramHandle* handle,
int textureLayout)
const {
319 if(handle ==
nullptr)
return 0;
321 if(handle->Uniforms.LightIrradiance != HANDLE_NULL)
322 m_irradianceMap->Bind(handle->Uniforms.LightIrradiance, textureLayout + steps++);
323 if(handle->Uniforms.LightPrefilter != HANDLE_NULL)
324 m_prefilterMap->Bind(handle->Uniforms.LightPrefilter, textureLayout + steps++);
328int SEnvironmentMgr::BindBRDFLUT(
const GLProgramHandle* handle,
int textureLayout)
const {
329 if(handle ==
nullptr)
return 0;
330 if(handle->Uniforms.LightBrdfLut != HANDLE_NULL) {
331 m_brdfMap->Bind(handle->Uniforms.LightBrdfLut, textureLayout);
337void SEnvironmentMgr::RenderBRDFLUT() {
338 std::cout <<
"[PBR] Backing a 2D LUT from the BRDF equations used...";
340 std::string brdf_v_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() +
"Shaders/IBL/brdf.vert");
341 std::string brdf_f_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() +
"Shaders/IBL/brdf.frag");
348 m_brdfMap->SetName(
"brdfLUT.texture");
349 m_brdfMap->SetAbsoluteID(
"brdfLUT.texture");
350 std::string hash =
"CSEENV0000000004";
351 m_brdfMap->SetHash(hash);
352 m_brdfMap->InitTexture(512, 512, GL_RG, GL_RG16F, GL_FLOAT);
355 glBindFramebuffer(GL_FRAMEBUFFER, m_captureFBO);
356 glBindRenderbuffer(GL_RENDERBUFFER, m_captureRBO);
357 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 512, 512);
358 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_brdfMap->GetTextureID(), 0);
361 glViewport(0, 0, 512, 512);
362 glUseProgram(m_brdfShader->Program);
363 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
364 if(m_planeVAO <= 0) LoadPlaneVAO();
367 std::cout <<
" finished!\n";
370void SEnvironmentMgr::ReleaseRenderingResources() {
372 glDeleteFramebuffers(1, &m_captureFBO);
373 glDeleteRenderbuffers(1, &m_captureRBO);
378 glBindFramebuffer(GL_FRAMEBUFFER, 0);
379 glEnable(GL_CULL_FACE);
382void SEnvironmentMgr::ReleaseVAO() {
383 glDeleteVertexArrays(1, &m_cubeVAO);
384 glDeleteVertexArrays(1, &m_planeVAO);
static GLProgramHandle * CreateProgramHandle(const GLchar *vertexSource, const GLchar *fragmentSource, GLProgramHandle *handle=nullptr)
Creates a program handle.