diff options
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/models/models_material_pbr.c | 195 | ||||
| -rw-r--r-- | examples/models/resources/shaders/pbr.fs | 3 | ||||
| -rw-r--r-- | examples/models/rlights.h | 177 |
3 files changed, 274 insertions, 101 deletions
diff --git a/examples/models/models_material_pbr.c b/examples/models/models_material_pbr.c index 5761b2af..49a905a8 100644 --- a/examples/models/models_material_pbr.c +++ b/examples/models/models_material_pbr.c @@ -12,32 +12,16 @@ #include "raylib.h" #include "raymath.h" -#define MAX_LIGHTS 4 // Max lights supported by shader -#define LIGHT_DISTANCE 3.5f // Light distance from world center -#define LIGHT_HEIGHT 1.0f // Light height position - -typedef enum { - LIGHT_DIRECTIONAL, - LIGHT_POINT -} LightType; - -typedef struct { - bool enabled; - LightType type; - Vector3 position; - Vector3 target; - Color color; - int enabledLoc; - int typeLoc; - int posLoc; - int targetLoc; - int colorLoc; -} Light; - -int lightsCount = 0; // Current amount of created lights - -Light CreateLight(int type, Vector3 pos, Vector3 targ, Color color, Shader shader); // Defines a light and get locations from PBR shader -void UpdateLightValues(Shader shader, Light light); // Send to PBR shader light values +#define RLIGHTS_IMPLEMENTATION +#include "rlights.h" + +#define CUBEMAP_SIZE 512 // Cubemap texture size +#define IRRADIANCE_SIZE 32 // Irradiance texture size +#define PREFILTERED_SIZE 256 // Prefiltered HDR environment texture size +#define BRDF_SIZE 512 // BRDF LUT texture size + +// PBR material loading +static Material LoadMaterialPBR(Color albedo, float metalness, float roughness); int main() { @@ -54,33 +38,15 @@ int main() // Load model and PBR material Model model = LoadModel("resources/pbr/trooper.obj"); - - Texture2D texHDR = LoadTexture("resources/pinetree.hdr"); - model.material = LoadMaterialPBR(texHDR, (Color){ 255, 255, 255, 255 }, 1.0f, 1.0f); - - SetMaterialTexture(&model.material, MAP_ALBEDO, LoadTexture("resources/pbr/trooper_albedo.png")); - SetMaterialTexture(&model.material, MAP_NORMAL, LoadTexture("resources/pbr/trooper_normals.png")); - SetMaterialTexture(&model.material, MAP_METALNESS, LoadTexture("resources/pbr/trooper_metalness.png")); - SetMaterialTexture(&model.material, MAP_ROUGHNESS, LoadTexture("resources/pbr/trooper_roughness.png")); - SetMaterialTexture(&model.material, MAP_OCCLUSION, LoadTexture("resources/pbr/trooper_ao.png")); - - // Set textures filtering for better quality - SetTextureFilter(model.material.maps[MAP_ALBEDO].texture, FILTER_BILINEAR); - SetTextureFilter(model.material.maps[MAP_NORMAL].texture, FILTER_BILINEAR); - SetTextureFilter(model.material.maps[MAP_METALNESS].texture, FILTER_BILINEAR); - SetTextureFilter(model.material.maps[MAP_ROUGHNESS].texture, FILTER_BILINEAR); - SetTextureFilter(model.material.maps[MAP_OCCLUSION].texture, FILTER_BILINEAR); - - int renderModeLoc = GetShaderLocation(model.material.shader, "renderMode"); - SetShaderValuei(model.material.shader, renderModeLoc, (int[1]){ 0 }, 1); + model.material = LoadMaterialPBR((Color){ 255, 255, 255, 255 }, 1.0f, 1.0f); - SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode - // Define lights attributes Light lights[MAX_LIGHTS] = { CreateLight(LIGHT_POINT, (Vector3){ LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 0, 255 }, model.material.shader), CreateLight(LIGHT_POINT, (Vector3){ 0.0f, LIGHT_HEIGHT, LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 255, 0, 255 }, model.material.shader), CreateLight(LIGHT_POINT, (Vector3){ -LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0f }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 0, 0, 255, 255 }, model.material.shader), CreateLight(LIGHT_DIRECTIONAL, (Vector3){ 0.0f, LIGHT_HEIGHT*2.0f, -LIGHT_DISTANCE }, (Vector3){ 0.0f, 0.0f, 0.0f }, (Color){ 255, 0, 255, 255 }, model.material.shader) }; + + SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -127,59 +93,88 @@ int main() return 0; } -// Defines a light and get locations from PBR shader -Light CreateLight(int type, Vector3 pos, Vector3 targ, Color color, Shader shader) +// Load PBR material (Supports: ALBEDO, NORMAL, METALNESS, ROUGHNESS, AO, EMMISIVE, HEIGHT maps) +// NOTE: PBR shader is loaded inside this function +static Material LoadMaterialPBR(Color albedo, float metalness, float roughness) { - Light light = { 0 }; - - if (lightsCount < MAX_LIGHTS) - { - light.enabled = true; - light.type = type; - light.position = pos; - light.target = targ; - light.color = color; - - char enabledName[32] = "lights[x].enabled\0"; - char typeName[32] = "lights[x].type\0"; - char posName[32] = "lights[x].position\0"; - char targetName[32] = "lights[x].target\0"; - char colorName[32] = "lights[x].color\0"; - enabledName[7] = '0' + lightsCount; - typeName[7] = '0' + lightsCount; - posName[7] = '0' + lightsCount; - targetName[7] = '0' + lightsCount; - colorName[7] = '0' + lightsCount; - - light.enabledLoc = GetShaderLocation(shader, enabledName); - light.typeLoc = GetShaderLocation(shader, typeName); - light.posLoc = GetShaderLocation(shader, posName); - light.targetLoc = GetShaderLocation(shader, targetName); - light.colorLoc = GetShaderLocation(shader, colorName); - - UpdateLightValues(shader, light); - lightsCount++; - } - - return light; -} - -// Send to PBR shader light values -void UpdateLightValues(Shader shader, Light light) -{ - // Send to shader light enabled state and type - SetShaderValuei(shader, light.enabledLoc, (int[1]){ light.enabled }, 1); - SetShaderValuei(shader, light.typeLoc, (int[1]){ light.type }, 1); - - // Send to shader light position values - float position[3] = { light.position.x, light.position.y, light.position.z }; - SetShaderValue(shader, light.posLoc, position, 3); - - // Send to shader light target position values - float target[3] = { light.target.x, light.target.y, light.target.z }; - SetShaderValue(shader, light.targetLoc, target, 3); + Material mat = { 0 }; // NOTE: All maps textures are set to { 0 } + + #define PATH_PBR_VS "resources/shaders/pbr.vs" // Path to physically based rendering vertex shader + #define PATH_PBR_FS "resources/shaders/pbr.fs" // Path to physically based rendering fragment shader + + mat.shader = LoadShader(PATH_PBR_VS, PATH_PBR_FS); + + // Get required locations points for PBR material + // NOTE: Those location names must be available and used in the shader code + mat.shader.locs[LOC_MAP_ALBEDO] = GetShaderLocation(mat.shader, "albedo.sampler"); + mat.shader.locs[LOC_MAP_METALNESS] = GetShaderLocation(mat.shader, "metalness.sampler"); + mat.shader.locs[LOC_MAP_NORMAL] = GetShaderLocation(mat.shader, "normals.sampler"); + mat.shader.locs[LOC_MAP_ROUGHNESS] = GetShaderLocation(mat.shader, "roughness.sampler"); + mat.shader.locs[LOC_MAP_OCCUSION] = GetShaderLocation(mat.shader, "occlusion.sampler"); + mat.shader.locs[LOC_MAP_EMISSION] = GetShaderLocation(mat.shader, "emission.sampler"); + mat.shader.locs[LOC_MAP_HEIGHT] = GetShaderLocation(mat.shader, "height.sampler"); + mat.shader.locs[LOC_MAP_IRRADIANCE] = GetShaderLocation(mat.shader, "irradianceMap"); + mat.shader.locs[LOC_MAP_PREFILTER] = GetShaderLocation(mat.shader, "prefilterMap"); + mat.shader.locs[LOC_MAP_BRDF] = GetShaderLocation(mat.shader, "brdfLUT"); + + // Set view matrix location + mat.shader.locs[LOC_MATRIX_MODEL] = GetShaderLocation(mat.shader, "mMatrix"); + mat.shader.locs[LOC_MATRIX_VIEW] = GetShaderLocation(mat.shader, "view"); + mat.shader.locs[LOC_VECTOR_VIEW] = GetShaderLocation(mat.shader, "viewPos"); + + // Set PBR standard maps + SetMaterialTexture(&mat, MAP_ALBEDO, LoadTexture("resources/pbr/trooper_albedo.png")); + SetMaterialTexture(&mat, MAP_NORMAL, LoadTexture("resources/pbr/trooper_normals.png")); + SetMaterialTexture(&mat, MAP_METALNESS, LoadTexture("resources/pbr/trooper_metalness.png")); + SetMaterialTexture(&mat, MAP_ROUGHNESS, LoadTexture("resources/pbr/trooper_roughness.png")); + SetMaterialTexture(&mat, MAP_OCCLUSION, LoadTexture("resources/pbr/trooper_ao.png")); + + // Set environment maps + #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_SKYBOX_VS "resources/shaders/skybox.vs" // Path to skybox vertex shader + #define PATH_IRRADIANCE_FS "resources/shaders/irradiance.fs" // Path to irradiance (GI) calculation fragment shader + #define PATH_SKYBOX_VS "resources/shaders/skybox.vs" // Path to skybox vertex 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 + #define PATH_BRDF_FS "resources/shaders/brdf.fs" // Path to bidirectional reflectance distribution function fragment shader + + Shader shdrCubemap = LoadShader(PATH_CUBEMAP_VS, PATH_CUBEMAP_FS); + Shader shdrIrradiance = LoadShader(PATH_SKYBOX_VS, PATH_IRRADIANCE_FS); + Shader shdrPrefilter = LoadShader(PATH_SKYBOX_VS, PATH_PREFILTER_FS); + Shader shdrBRDF = LoadShader(PATH_BRDF_VS, PATH_BRDF_FS); - // Send to shader light color values - float diff[4] = { (float)light.color.r/(float)255, (float)light.color.g/(float)255, (float)light.color.b/(float)255, (float)light.color.a/(float)255 }; - SetShaderValue(shader, light.colorLoc, diff, 4); + Texture2D texHDR = LoadTexture("resources/pinetree.hdr"); + Texture2D cubemap = GenTextureCubemap(shdrCubemap, texHDR, CUBEMAP_SIZE); + SetMaterialTexture(&mat, MAP_IRRADIANCE, GenTextureIrradiance(shdrIrradiance, cubemap, IRRADIANCE_SIZE)); + SetMaterialTexture(&mat, MAP_PREFILTER, GenTexturePrefilter(shdrPrefilter, cubemap, PREFILTERED_SIZE)); + SetMaterialTexture(&mat, MAP_BRDF, GenTextureBRDF(shdrBRDF, cubemap, BRDF_SIZE)); + UnloadTexture(cubemap); + UnloadTexture(texHDR); + + UnloadShader(shdrCubemap); + UnloadShader(shdrIrradiance); + UnloadShader(shdrPrefilter); + UnloadShader(shdrBRDF); + + // Set textures filtering for better quality + SetTextureFilter(mat.maps[MAP_ALBEDO].texture, FILTER_BILINEAR); + SetTextureFilter(mat.maps[MAP_NORMAL].texture, FILTER_BILINEAR); + SetTextureFilter(mat.maps[MAP_METALNESS].texture, FILTER_BILINEAR); + SetTextureFilter(mat.maps[MAP_ROUGHNESS].texture, FILTER_BILINEAR); + SetTextureFilter(mat.maps[MAP_OCCLUSION].texture, FILTER_BILINEAR); + + int renderModeLoc = GetShaderLocation(mat.shader, "renderMode"); + SetShaderValuei(mat.shader, renderModeLoc, (int[1]){ 0 }, 1); + + // Set up material properties color + mat.maps[MAP_ALBEDO].color = albedo; + mat.maps[MAP_NORMAL].color = (Color){ 128, 128, 255, 255 }; + mat.maps[MAP_METALNESS].value = metalness; + mat.maps[MAP_ROUGHNESS].value = roughness; + mat.maps[MAP_OCCLUSION].value = 1.0f; + mat.maps[MAP_EMISSION].value = 0.5f; + mat.maps[MAP_HEIGHT].value = 0.5f; + + return mat; } diff --git a/examples/models/resources/shaders/pbr.fs b/examples/models/resources/shaders/pbr.fs index 06814823..38d56c5d 100644 --- a/examples/models/resources/shaders/pbr.fs +++ b/examples/models/resources/shaders/pbr.fs @@ -8,10 +8,11 @@ #version 330 -#define MAX_LIGHTS 4 #define MAX_REFLECTION_LOD 4.0 #define MAX_DEPTH_LAYER 20 #define MIN_DEPTH_LAYER 10 + +#define MAX_LIGHTS 4 #define LIGHT_DIRECTIONAL 0 #define LIGHT_POINT 1 diff --git a/examples/models/rlights.h b/examples/models/rlights.h new file mode 100644 index 00000000..0da3e2cb --- /dev/null +++ b/examples/models/rlights.h @@ -0,0 +1,177 @@ +/********************************************************************************************** +* +* raylib.lights - Some useful functions to deal with lights data +* +* CONFIGURATION: +* +* #define RLIGHTS_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation. +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2017 Victor Fisac and Ramon Santamaria +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef RLIGHTS_H +#define RLIGHTS_H + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +#define MAX_LIGHTS 4 // Max lights supported by shader +#define LIGHT_DISTANCE 3.5f // Light distance from world center +#define LIGHT_HEIGHT 1.0f // Light height position + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef enum { + LIGHT_DIRECTIONAL, + LIGHT_POINT +} LightType; + +typedef struct { + bool enabled; + LightType type; + Vector3 position; + Vector3 target; + Color color; + int enabledLoc; + int typeLoc; + int posLoc; + int targetLoc; + int colorLoc; +} Light; + +#ifdef __cplusplus +extern "C" { // Prevents name mangling of functions +#endif + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +int lightsCount = 0; // Current amount of created lights + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- +Light CreateLight(int type, Vector3 pos, Vector3 targ, Color color, Shader shader); // Defines a light and get locations from PBR shader +void UpdateLightValues(Shader shader, Light light); // Send to PBR shader light values + +#ifdef __cplusplus +} +#endif + +#endif // RLIGHTS_H + + +/*********************************************************************************** +* +* RLIGHTS IMPLEMENTATION +* +************************************************************************************/ + +#if defined(RLIGHTS_IMPLEMENTATION) + +#include "raylib.h" + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +// ... + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +// ... + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +// ... + +//---------------------------------------------------------------------------------- +// Module specific Functions Declaration +//---------------------------------------------------------------------------------- +// ... + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- + +// Defines a light and get locations from PBR shader +Light CreateLight(int type, Vector3 pos, Vector3 targ, Color color, Shader shader) +{ + Light light = { 0 }; + + if (lightsCount < MAX_LIGHTS) + { + light.enabled = true; + light.type = type; + light.position = pos; + light.target = targ; + light.color = color; + + char enabledName[32] = "lights[x].enabled\0"; + char typeName[32] = "lights[x].type\0"; + char posName[32] = "lights[x].position\0"; + char targetName[32] = "lights[x].target\0"; + char colorName[32] = "lights[x].color\0"; + enabledName[7] = '0' + lightsCount; + typeName[7] = '0' + lightsCount; + posName[7] = '0' + lightsCount; + targetName[7] = '0' + lightsCount; + colorName[7] = '0' + lightsCount; + + light.enabledLoc = GetShaderLocation(shader, enabledName); + light.typeLoc = GetShaderLocation(shader, typeName); + light.posLoc = GetShaderLocation(shader, posName); + light.targetLoc = GetShaderLocation(shader, targetName); + light.colorLoc = GetShaderLocation(shader, colorName); + + UpdateLightValues(shader, light); + lightsCount++; + } + + return light; +} + +// Send to PBR shader light values +void UpdateLightValues(Shader shader, Light light) +{ + // Send to shader light enabled state and type + SetShaderValuei(shader, light.enabledLoc, (int[1]){ light.enabled }, 1); + SetShaderValuei(shader, light.typeLoc, (int[1]){ light.type }, 1); + + // Send to shader light position values + float position[3] = { light.position.x, light.position.y, light.position.z }; + SetShaderValue(shader, light.posLoc, position, 3); + + // Send to shader light target position values + float target[3] = { light.target.x, light.target.y, light.target.z }; + SetShaderValue(shader, light.targetLoc, target, 3); + + // Send to shader light color values + float diff[4] = { (float)light.color.r/(float)255, (float)light.color.g/(float)255, (float)light.color.b/(float)255, (float)light.color.a/(float)255 }; + SetShaderValue(shader, light.colorLoc, diff, 4); +} + +#endif // RLIGHTS_IMPLEMENTATION
\ No newline at end of file |
