summaryrefslogtreecommitdiffhomepage
path: root/examples/models
diff options
context:
space:
mode:
Diffstat (limited to 'examples/models')
-rw-r--r--examples/models/models_material_pbr.c195
-rw-r--r--examples/models/resources/shaders/pbr.fs3
-rw-r--r--examples/models/rlights.h177
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