diff --git a/examples/models/models_material_pbr.c b/examples/models/models_material_pbr.c index fe610d8fb..8423037dd 100644 --- a/examples/models/models_material_pbr.c +++ b/examples/models/models_material_pbr.c @@ -12,6 +12,33 @@ #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 + int main() { // Initialization @@ -19,6 +46,7 @@ int main() int screenWidth = 800; int screenHeight = 450; + SetConfigFlags(FLAG_MSAA_4X_HINT); InitWindow(screenWidth, screenHeight, "raylib [models] example - pbr material"); // Define the camera to look into our 3d world @@ -30,15 +58,12 @@ int main() Texture2D texHDR = LoadTexture("resources/pinetree.hdr"); model.material = LoadMaterialPBR(texHDR, (Color){ 255, 255, 255, 255 }, 1.0f, 1.0f); - //model.material.maps[TEXMAP_ALBEDO].tex = LoadTexture("resources/pbr/trooper_albedo.png"); SetMaterialTexture(&model.material, TEXMAP_ALBEDO, LoadTexture("resources/pbr/trooper_albedo.png")); SetMaterialTexture(&model.material, TEXMAP_NORMAL, LoadTexture("resources/pbr/trooper_normals.png")); SetMaterialTexture(&model.material, TEXMAP_METALNESS, LoadTexture("resources/pbr/trooper_metalness.png")); SetMaterialTexture(&model.material, TEXMAP_ROUGHNESS, LoadTexture("resources/pbr/trooper_roughness.png")); SetMaterialTexture(&model.material, TEXMAP_OCCLUSION, LoadTexture("resources/pbr/trooper_ao.png")); - SetShaderValuei(model.material.shader, GetShaderLocation(model.material.shader, "normals.enabled"), (int[1]){ 1 }, 1); - // Set textures filtering for better quality SetTextureFilter(model.material.maps[TEXMAP_ALBEDO].tex, FILTER_BILINEAR); SetTextureFilter(model.material.maps[TEXMAP_NORMAL].tex, FILTER_BILINEAR); @@ -46,9 +71,16 @@ int main() SetTextureFilter(model.material.maps[TEXMAP_ROUGHNESS].tex, FILTER_BILINEAR); SetTextureFilter(model.material.maps[TEXMAP_OCCLUSION].tex, FILTER_BILINEAR); - int viewPosLoc = GetShaderLocation(model.material.shader, "viewPos"); + int renderModeLoc = GetShaderLocation(model.material.shader, "renderMode"); + SetShaderValuei(model.material.shader, renderModeLoc, (int[1]){ 0 }, 1); 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) }; SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -62,7 +94,7 @@ int main() // Send to material PBR shader camera view position float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z }; - SetShaderValue(model.material.shader, viewPosLoc, cameraPos, 3); + SetShaderValue(model.material.shader, model.material.shader.locs[LOC_MATRIX_VIEW], cameraPos, 3); //---------------------------------------------------------------------------------- // Draw @@ -94,3 +126,60 @@ 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) +{ + 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); +} diff --git a/examples/models/models_material_pbr.png b/examples/models/models_material_pbr.png new file mode 100644 index 000000000..cde171b96 Binary files /dev/null and b/examples/models/models_material_pbr.png differ diff --git a/examples/models/models_skybox.c b/examples/models/models_skybox.c index a3b9b2583..1c5f62492 100644 --- a/examples/models/models_skybox.c +++ b/examples/models/models_skybox.c @@ -24,17 +24,23 @@ int main() // Define the camera to look into our 3d world Camera camera = {{ 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f }; + // Load skybox model and 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_TEXTURES_HDR "resources/pinetree.hdr" + #define LOC_CUSTOM_SKYRESOLUTION 15 + Mesh cube = GenMeshCube(1.0f, 1.0f, 1.0f); Model skybox = LoadModelFromMesh(cube, false); - skybox.material.shader = LoadShader("resources/shaders/skybox.vs", "resources/shaders/skybox.fs"); + skybox.material.shader = LoadShader(PATH_SKYBOX_VS, PATH_SKYBOX_FS); - Texture2D texHDR = LoadTexture("resources/pinetree.hdr"); + Texture2D texHDR = LoadTexture(PATH_TEXTURES_HDR); skybox.material.maps[TEXMAP_CUBEMAP].tex = rlGenMapCubemap(texHDR, 512); SetShaderValuei(skybox.material.shader, GetShaderLocation(skybox.material.shader, "environmentMap"), (int[1]){ TEXMAP_CUBEMAP }, 1); // Get skybox shader locations int skyProjectionLoc = GetShaderLocation(skybox.material.shader, "projection"); - int skyViewLoc = GetShaderLocation(skybox.material.shader, "view"); + skybox.material.shader.locs[LOC_MATRIX_VIEW] = GetShaderLocation(skybox.material.shader, "view"); // Then before rendering, configure the viewport to the actual screen dimensions Matrix proj = MatrixPerspective(60.0, (double)GetScreenWidth()/(double)GetScreenHeight(), 0.01, 1000.0); @@ -54,7 +60,7 @@ int main() UpdateCamera(&camera); // Update camera Matrix view = MatrixLookAt(camera.position, camera.target, camera.up); - SetShaderValueMatrix(skybox.material.shader, skyViewLoc, view); + SetShaderValueMatrix(skybox.material.shader, skybox.material.shader.locs[LOC_MATRIX_VIEW], view); //---------------------------------------------------------------------------------- // Draw diff --git a/examples/models/models_skybox.png b/examples/models/models_skybox.png new file mode 100644 index 000000000..31694fa5a Binary files /dev/null and b/examples/models/models_skybox.png differ