From 783c187ea8705c9aa367b33b2b9569063071e81f Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 1 Jul 2017 19:57:25 +0200 Subject: [PATCH] LoadMaterialEnv: Working on PBR materials support --- src/models.c | 164 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 107 insertions(+), 57 deletions(-) diff --git a/src/models.c b/src/models.c index b6e81bac4..e73be4426 100644 --- a/src/models.c +++ b/src/models.c @@ -722,32 +722,35 @@ Material LoadMaterialPBR(Texture2D cubemap, Color albedo, int metalness, int rou mat.shader = LoadShader(PATH_PBR_VS, PATH_PBR_FS); // Set up environment shader texture units - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "irradianceMap"), (int[1]){ 0 }, 1); - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "prefilterMap"), (int[1]){ 1 }, 1); - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "brdfLUT"), (int[1]){ 2 }, 1); + SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "irradianceMap"), (int[1]){ 0 }, 1); // GL_TEXTURE0 + SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "prefilterMap"), (int[1]){ 1 }, 1); // GL_TEXTURE1 + SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "brdfLUT"), (int[1]){ 2 }, 1); // GL_TEXTURE2 // Set up PBR shader material texture units - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "albedo.sampler"), (int[1]){ 3 }, 1); - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "normals.sampler"), (int[1]){ 4 }, 1); - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "metalness.sampler"), (int[1]){ 5 }, 1); - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "roughness.sampler"), (int[1]){ 6 }, 1); - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "occlusion.sampler"), (int[1]){ 7 }, 1); - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "emission.sampler"), (int[1]){ 8 }, 1); - SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "height.sampler"), (int[1]){ 9 }, 1); + SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "albedo.sampler"), (int[1]){ 3 }, 1); // GL_TEXTURE3 + SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "normals.sampler"), (int[1]){ 4 }, 1); // GL_TEXTURE4 + SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "metalness.sampler"), (int[1]){ 5 }, 1); // GL_TEXTURE5 + SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "roughness.sampler"), (int[1]){ 6 }, 1); // GL_TEXTURE6 + SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "occlusion.sampler"), (int[1]){ 7 }, 1); // GL_TEXTURE7 + SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "emission.sampler"), (int[1]){ 8 }, 1); // GL_TEXTURE8 + SetShaderValuei(mat.shader, GetShaderLocation(mat.shader, "height.sampler"), (int[1]){ 9 }, 1); // GL_TEXTURE9 mat.shader.locs[LOC_MATRIX_VIEW] = GetShaderLocation(mat.shader, "viewPos"); // Set up material properties color mat.maps[TEXMAP_ALBEDO].color = albedo; mat.maps[TEXMAP_NORMAL].color = (Color){ 128, 128, 255, 255 }; - mat.maps[TEXMAP_METALNESS].color = (Color){ metalness, 0, 0, 0 }; - mat.maps[TEXMAP_ROUGHNESS].color = (Color){ roughness, 0, 0, 0 }; - mat.maps[TEXMAP_OCCLUSION].color = (Color){ 255, 255, 255, 255 }; - mat.maps[TEXMAP_EMISSION].color = (Color){ 0, 0, 0, 0 }; - mat.maps[TEXMAP_HEIGHT].color = (Color){ 0, 0, 0, 0 }; + mat.maps[TEXMAP_METALNESS].value = metalness; //(Color){ metalness, 0, 0, 0 }; + mat.maps[TEXMAP_ROUGHNESS].value = roughness; //(Color){ roughness, 0, 0, 0 }; + mat.maps[TEXMAP_OCCLUSION].value = 1.0f; //(Color){ 255, 255, 255, 255 }; + mat.maps[TEXMAP_EMISSION].value = 0.0f; //(Color){ 0, 0, 0, 0 }; + mat.maps[TEXMAP_HEIGHT].value = 0.0f; //(Color){ 0, 0, 0, 0 }; - // Set up material cubemap + // Set up environment materials cubemap mat.maps[TEXMAP_CUBEMAP].tex = cubemap; + //mat.maps[TEXMAP_IRRADIANCE] = env.maps[TEXMAP_IRRADIANCE]; + //mat.maps[TEXMAP_PREFILTER] = env.maps[TEXMAP_PREFILTER]; + //mat.maps[TEXMAP_BRDF] = env.maps[TEXMAP_BRDF]; // NOTE: All maps textures are set to { 0 } @@ -760,10 +763,11 @@ Material LoadMaterialEnv(const char *filename, int cubemapSize, int irradianceSi { Material env = { 0 }; - #define PATH_CUBE_VS "resources/shaders/cubemap.vs" // Path to equirectangular to cubemap vertex shader - #define PATH_CUBE_FS "resources/shaders/cubemap.fs" // Path to equirectangular to cubemap fragment shader #define PATH_SKYBOX_VS "resources/shaders/skybox.vs" // Path to skybox vertex shader #define PATH_SKYBOX_FS "resources/shaders/skybox.fs" // Path to skybox vertex shader + + #define PATH_CUBEMAP_VS "resources/shaders/cubemap.vs" // Path to equirectangular to cubemap vertex shader + #define PATH_CUBEMAP_FS "resources/shaders/cubemap.fs" // Path to equirectangular to cubemap fragment shader #define PATH_IRRADIANCE_FS "resources/shaders/irradiance.fs" // Path to irradiance (GI) calculation fragment shader #define PATH_PREFILTER_FS "resources/shaders/prefilter.fs" // Path to reflection prefilter calculation fragment shader #define PATH_BRDF_VS "resources/shaders/brdf.vs" // Path to bidirectional reflectance distribution function vertex shader @@ -773,35 +777,24 @@ Material LoadMaterialEnv(const char *filename, int cubemapSize, int irradianceSi env.shader = LoadShader(PATH_SKYBOX_VS, PATH_SKYBOX_FS); - // Load cubemap required shaders - Shader cubeShader = LoadShader(PATH_CUBE_VS, PATH_CUBE_FS); - Shader irradianceShader = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS); - Shader prefilterShader = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS); - Shader brdfShader = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS); - - // Get cubemap shader locations - int cubeProjectionLoc = GetShaderLocation(cubeShader, "projection"); - int cubeViewLoc = GetShaderLocation(cubeShader, "view"); - // Get skybox shader locations int skyProjectionLoc = GetShaderLocation(env.shader, "projection"); env.shader.locs[LOC_MATRIX_VIEW] = GetShaderLocation(env.shader, "view"); env.shader.locs[LOC_CUSTOM_SKYRESOLUTION] = GetShaderLocation(env.shader, "resolution"); - - // Get irradiance shader locations - int irradianceProjectionLoc = GetShaderLocation(irradianceShader, "projection"); - int irradianceViewLoc = GetShaderLocation(irradianceShader, "view"); - - // Get prefilter shader locations - int prefilterProjectionLoc = GetShaderLocation(prefilterShader, "projection"); - int prefilterViewLoc = GetShaderLocation(prefilterShader, "view"); - int prefilterRoughnessLoc = GetShaderLocation(prefilterShader, "roughness"); - + // Set up shaders constant values - SetShaderValuei(cubeShader, GetShaderLocation(cubeShader, "equirectangularMap"), (int[1]){ 0 }, 1); - SetShaderValuei(irradianceShader, GetShaderLocation(irradianceShader, "environmentMap"), (int[1]){ 0 }, 1); - SetShaderValuei(prefilterShader, GetShaderLocation(prefilterShader, "environmentMap"), (int[1]){ 0 }, 1); - SetShaderValuei(env.shader, GetShaderLocation(env.shader, "environmentMap"), (int[1]){ 0 }, 1); + SetShaderValuei(env.shader, GetShaderLocation(env.shader, "cubeMap"), (int[1]){ 0 }, 1); + + + // Generate texture: CUBEMAP + //---------------------------------------- + Shader cubemapShader = LoadShader(PATH_CUBEMAP_VS, PATH_CUBEMAP_FS); + + // Get cubemap shader locations + int cubeProjectionLoc = GetShaderLocation(cubemapShader, "projection"); + int cubeViewLoc = GetShaderLocation(cubemapShader, "view"); + + SetShaderValuei(cubemapShader, GetShaderLocation(cubemapShader, "equirectangularMap"), (int[1]){ 0 }, 1); /* // Set up depth face culling and cube map seamless @@ -846,10 +839,10 @@ Material LoadMaterialEnv(const char *filename, int cubemapSize, int irradianceSi }; // Convert HDR equirectangular environment map to cubemap equivalent - glUseProgram(cubeShader.id); + glUseProgram(cubemapShader.id); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, skyTex.id); - SetShaderValueMatrix(cubeShader, cubeProjectionLoc, captureProjection); + SetShaderValueMatrix(cubemapShader, cubeProjectionLoc, captureProjection); // Note: don't forget to configure the viewport to the capture dimensions rlViewport(0, 0, cubemapSize, cubemapSize); @@ -857,7 +850,7 @@ Material LoadMaterialEnv(const char *filename, int cubemapSize, int irradianceSi for (unsigned int i = 0; i < 6; i++) { - SetShaderValueMatrix(cubeShader, cubeViewLoc, captureViews[i]); + SetShaderValueMatrix(cubemapShader, cubeViewLoc, captureViews[i]); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, env.maps[TEXMAP_CUBEMAP].tex.id, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); RenderCube(); @@ -865,7 +858,24 @@ Material LoadMaterialEnv(const char *filename, int cubemapSize, int irradianceSi // Unbind framebuffer and textures rlEnableRenderTexture(0); + */ + + UnloadShader(cubemapShader); + //---------------------------------------- + + // Generate texture: IRRADIANCE + //---------------------------------------- + Shader irradianceShader = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS); + + // Get irradiance shader locations + int irradianceProjectionLoc = GetShaderLocation(irradianceShader, "projection"); + int irradianceViewLoc = GetShaderLocation(irradianceShader, "view"); + + // Set up shaders constant values + SetShaderValuei(irradianceShader, GetShaderLocation(irradianceShader, "environmentMap"), (int[1]){ 0 }, 1); + + /* // Create an irradiance cubemap, and re-scale capture FBO to irradiance scale glGenTextures(1, &env.maps[TEXMAP_IRRADIANCE].tex.id); glBindTexture(GL_TEXTURE_CUBE_MAP, env.maps[TEXMAP_IRRADIANCE].tex.id); @@ -900,7 +910,24 @@ Material LoadMaterialEnv(const char *filename, int cubemapSize, int irradianceSi // Unbind framebuffer and textures glBindFramebuffer(GL_FRAMEBUFFER, 0); + */ + + UnloadShader(irradianceShader); + //---------------------------------------- + + // Generate texture: PREFILTER + //---------------------------------------- + Shader prefilterShader = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS); + + // Get prefilter shader locations + int prefilterProjectionLoc = GetShaderLocation(prefilterShader, "projection"); + int prefilterViewLoc = GetShaderLocation(prefilterShader, "view"); + int prefilterRoughnessLoc = GetShaderLocation(prefilterShader, "roughness"); + + SetShaderValuei(prefilterShader, GetShaderLocation(prefilterShader, "environmentMap"), (int[1]){ 0 }, 1); + + /* // Create a prefiltered HDR environment map glGenTextures(1, &env.maps[TEXMAP_PREFILTER].tex.id); glBindTexture(GL_TEXTURE_CUBE_MAP, env.maps[TEXMAP_PREFILTER].tex.id); @@ -945,7 +972,31 @@ Material LoadMaterialEnv(const char *filename, int cubemapSize, int irradianceSi // Unbind framebuffer and textures glBindFramebuffer(GL_FRAMEBUFFER, 0); - + */ + + UnloadShader(prefilterShader); + //---------------------------------------- + + + // Generate texture: BRDF + //---------------------------------------- + Shader brdfShader = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS); + + RenderTexture2D brdfMap = LoadRenderTexture(brdfSize, brdfSize); + + BeginDrawing(); + BeginTextureMode(brdfMap); + rlViewport(0, 0, brdfSize, brdfSize); + BeginShaderMode(brdfShader); + + RenderQuad(); + + EndShaderMode(); + EndTextureMode(); + EndDrawing(); + + UnloadRenderTexture(brdfMap); + /* // Generate BRDF convolution texture glGenTextures(1, &env.maps[TEXMAP_BRDF].tex.id); glBindTexture(GL_TEXTURE_2D, env.maps[TEXMAP_BRDF].tex.id); @@ -968,23 +1019,22 @@ Material LoadMaterialEnv(const char *filename, int cubemapSize, int irradianceSi // Unbind framebuffer and textures glBindFramebuffer(GL_FRAMEBUFFER, 0); - + */ + // Then before rendering, configure the viewport to the actual screen dimensions Matrix defaultProjection = MatrixPerspective(60.0, (double)GetScreenWidth()/(double)GetScreenHeight(), 0.01, 1000.0); MatrixTranspose(&defaultProjection); - SetShaderValueMatrix(cubeShader, cubeProjectionLoc, defaultProjection); + SetShaderValueMatrix(env.shader, skyProjectionLoc, defaultProjection); - SetShaderValueMatrix(irradianceShader, irradianceProjectionLoc, defaultProjection); - SetShaderValueMatrix(prefilterShader, prefilterProjectionLoc, defaultProjection); - */ + //SetShaderValueMatrix(cubemapShader, cubeProjectionLoc, defaultProjection); // Not required any more + //SetShaderValueMatrix(irradianceShader, irradianceProjectionLoc, defaultProjection); // Not required any more + //SetShaderValueMatrix(prefilterShader, prefilterProjectionLoc, defaultProjection); // Not required any more + + UnloadShader(brdfShader); + //---------------------------------------- // Reset viewport dimensions to default - rlViewport(0, 0, GetScreenWidth(), GetScreenHeight()); - - UnloadShader(cubeShader); - UnloadShader(irradianceShader); - UnloadShader(prefilterShader); - UnloadShader(brdfShader); + rlViewport(0, 0, GetScreenWidth(), GetScreenHeight()); return env; }