Ver Fonte

new example: shaders_fog

Ray há 6 anos atrás
pai
commit
4b79f63d07

+ 99 - 0
examples/shaders/resources/shaders/glsl330/fog.fs

@@ -0,0 +1,99 @@
+#version 330
+
+// Input vertex attributes (from vertex shader)
+in vec2 fragTexCoord;
+in vec4 fragColor;
+in vec3 fragPosition;
+in vec3 fragNormal;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// Output fragment color
+out vec4 finalColor;
+
+// NOTE: Add here your custom variables
+
+#define     MAX_LIGHTS              4
+#define     LIGHT_DIRECTIONAL       0
+#define     LIGHT_POINT             1
+
+struct MaterialProperty {
+    vec3 color;
+    int useSampler;
+    sampler2D sampler;
+};
+
+struct Light {
+    int enabled;
+    int type;
+    vec3 position;
+    vec3 target;
+    vec4 color;
+};
+
+// Input lighting values
+uniform Light lights[MAX_LIGHTS];
+uniform vec4 ambient;
+uniform vec3 viewPos;
+uniform float fogDensity;
+
+void main()
+{
+    // Texel color fetching from texture sampler
+    vec4 texelColor = texture(texture0, fragTexCoord);
+    vec3 lightDot = vec3(0.0);
+    vec3 normal = normalize(fragNormal);
+    vec3 viewD = normalize(viewPos - fragPosition);
+    vec3 specular = vec3(0.0);
+
+    // NOTE: Implement here your fragment shader code
+
+    for (int i = 0; i < MAX_LIGHTS; i++)
+    {
+        if (lights[i].enabled == 1)
+        {
+            vec3 light = vec3(0.0);
+            if (lights[i].type == LIGHT_DIRECTIONAL) {
+                light = -normalize(lights[i].target - lights[i].position);
+            }
+            if (lights[i].type == LIGHT_POINT) {
+                light = normalize(lights[i].position - fragPosition);
+            }
+            float NdotL = max(dot(normal, light), 0.0);
+            lightDot += lights[i].color.rgb * NdotL;
+
+            float specCo = 0.0;
+            if(NdotL > 0.0)
+                specCo = pow(max(0.0, dot(viewD, reflect(-(light), normal))), 16);//16 =shine
+            specular += specCo;
+
+        }
+    }
+
+    finalColor =  (texelColor * ((colDiffuse+vec4(specular,1)) * vec4(lightDot, 1.0)));
+    finalColor += texelColor * (ambient/10.0);
+    
+    // Gamma correction
+    finalColor = pow(finalColor, vec4(1.0/2.2));
+    
+    // Fog calculation
+    float dist = length(viewPos - fragPosition);
+
+    // these could be parameters...
+    const vec4 fogColor = vec4(0.5, 0.5, 0.5, 1.0);
+    //const float fogDensity = 0.16;
+
+    // Exponential fog
+    float fogFactor = 1.0/exp((dist*fogDensity)*(dist*fogDensity));
+
+    // Linear fog (less nice)
+    //const float fogStart = 2.0;
+    //const float fogEnd = 10.0;
+    //float fogFactor = (fogEnd - dist)/(fogEnd - fogStart);
+
+    fogFactor = clamp(fogFactor, 0.0, 1.0);
+
+    finalColor = mix(fogColor, finalColor, fogFactor);
+}

+ 32 - 0
examples/shaders/resources/shaders/glsl330/fog.vs

@@ -0,0 +1,32 @@
+#version 330
+
+// Input vertex attributes
+in vec3 vertexPosition;
+in vec2 vertexTexCoord;
+in vec3 vertexNormal;
+in vec4 vertexColor;
+
+// Input uniform values
+uniform mat4 mvp;
+uniform mat4 matModel;
+
+// Output vertex attributes (to fragment shader)
+out vec2 fragTexCoord;
+out vec4 fragColor;
+out vec3 fragPosition;
+out vec3 fragNormal;
+
+// NOTE: Add here your custom variables
+
+void main()
+{
+    // Send vertex attributes to fragment shader
+    fragTexCoord = vertexTexCoord;
+    fragColor = vertexColor;
+    fragPosition = vec3(matModel*vec4(vertexPosition, 1.0f));
+    mat3 normalMatrix = transpose(inverse(mat3(matModel)));
+    fragNormal = normalize(normalMatrix*vertexNormal);
+
+    // Calculate final vertex position
+    gl_Position = mvp*vec4(vertexPosition, 1.0);
+}

+ 153 - 0
examples/shaders/shaders_fog.c

@@ -0,0 +1,153 @@
+/*******************************************************************************************
+*
+*   raylib [shaders] example - fog
+*
+*   NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
+*         OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
+*
+*   NOTE: Shaders used in this example are #version 330 (OpenGL 3.3).
+*
+*   This example has been created using raylib 2.5 (www.raylib.com)
+*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+*   Example contributed by Chris Camacho (@codifies) and reviewed by Ramon Santamaria (@raysan5)
+*
+*   Chris Camacho (@codifies -  http://bedroomcoders.co.uk/) notes:
+*
+*   This is based on the PBR lighting example, but greatly simplified to aid learning...
+*   actually there is very little of the PBR example left!
+*   When I first looked at the bewildering complexity of the PBR example I feared
+*   I would never understand how I could do simple lighting with raylib however its
+*   a testement to the authors of raylib (including rlights.h) that the example
+*   came together fairly quickly.
+*
+*   Copyright (c) 2019 Chris Camacho (@codifies) and Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include "raymath.h"
+
+#define RLIGHTS_IMPLEMENTATION
+#include "rlights.h"
+
+int main(void)
+{
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    const int screenWidth = 800;
+    const int screenHeight = 450;
+
+    SetConfigFlags(FLAG_MSAA_4X_HINT);  // Enable Multi Sampling Anti Aliasing 4x (if available)
+    InitWindow(screenWidth, screenHeight, "raylib [shaders] example - fog");
+
+    // Define the camera to look into our 3d world
+    Camera camera = { 
+        (Vector3){ 2.0f, 2.0f, 6.0f },      // position
+        (Vector3){ 0.0f, 0.5f, 0.0f },      // target
+        (Vector3){ 0.0f, 1.0f, 0.0f },      // up
+        45.0f, CAMERA_PERSPECTIVE };        // fov, type
+
+    // Load models and texture
+    Model modelA = LoadModelFromMesh(GenMeshTorus(0.4f, 1.0f, 16, 32));
+    Model modelB = LoadModelFromMesh(GenMeshCube(1.0f, 1.0f, 1.0f));
+    Model modelC = LoadModelFromMesh(GenMeshSphere(0.5f, 32, 32));
+    Texture texture = LoadTexture("resources/texel_checker.png");
+
+    // Assign texture to default model material
+    modelA.materials[0].maps[MAP_DIFFUSE].texture = texture;
+    modelB.materials[0].maps[MAP_DIFFUSE].texture = texture;
+    modelC.materials[0].maps[MAP_DIFFUSE].texture = texture;
+
+    // Load shader and set up some uniforms
+    Shader shader = LoadShader("resources/shaders/glsl330/fog.vs", "resources/shaders/glsl330/fog.fs");
+    shader.locs[LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel");
+    shader.locs[LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
+
+    // Ambient light level
+    int ambientLoc = GetShaderLocation(shader, "ambient");
+    SetShaderValue(shader, ambientLoc, (float[4]){ 0.2f, 0.2f, 0.2f, 1.0f }, UNIFORM_VEC4);
+    
+    float fogDensity = 0.15f;
+    int fogDensityLoc = GetShaderLocation(shader, "fogDensity");
+    SetShaderValue(shader, fogDensityLoc, &fogDensity, UNIFORM_FLOAT);
+
+    // NOTE: All models share the same shader
+    modelA.materials[0].shader = shader;
+    modelB.materials[0].shader = shader;
+    modelC.materials[0].shader = shader;
+
+    // Using just 1 point lights
+    CreateLight(LIGHT_POINT, (Vector3){ 0, 2, 6 }, Vector3Zero(), WHITE, shader);
+
+    SetCameraMode(camera, CAMERA_ORBITAL);  // Set an orbital camera mode
+
+    SetTargetFPS(60);                       // Set our game to run at 60 frames-per-second
+    //--------------------------------------------------------------------------------------
+
+    // Main game loop
+    while (!WindowShouldClose())            // Detect window close button or ESC key
+    {
+        // Update
+        //----------------------------------------------------------------------------------
+        UpdateCamera(&camera);              // Update camera
+
+        if (IsKeyDown(KEY_UP)) 
+        {
+            fogDensity += 0.001;
+            if (fogDensity > 1.0) fogDensity = 1.0;
+        }
+        
+        if (IsKeyDown(KEY_DOWN))
+        {
+            fogDensity -= 0.001;
+            if (fogDensity < 0.0) fogDensity = 0.0;
+        }
+        
+        SetShaderValue(shader, fogDensityLoc, &fogDensity, UNIFORM_FLOAT);
+
+        // Rotate the torus
+        modelA.transform = MatrixMultiply(modelA.transform, MatrixRotateX(-0.025));
+        modelA.transform = MatrixMultiply(modelA.transform, MatrixRotateZ(0.012));
+
+        // Update the light shader with the camera view position
+        SetShaderValue(shader, shader.locs[LOC_VECTOR_VIEW], &camera.position.x, UNIFORM_VEC3);
+        //----------------------------------------------------------------------------------
+
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
+
+            ClearBackground(GRAY);
+
+            BeginMode3D(camera);
+
+                // Draw the three models
+                DrawModel(modelA, Vector3Zero(), 1.0f, WHITE);
+                DrawModel(modelB, (Vector3){ -2.6, 0, 0 }, 1.0f, WHITE);
+                DrawModel(modelC, (Vector3){ 2.6, 0, 0 }, 1.0f, WHITE);
+
+                for (int i = -20; i < 20; i += 2) DrawModel(modelA,(Vector3){ i, 0, 2 }, 1.0f, WHITE);
+
+            EndMode3D();
+
+            DrawText(TextFormat("Use KEY_UP/KEY_DOWN to change fog density [%.2f]", fogDensity), 10, 10, 20, RAYWHITE);
+
+        EndDrawing();
+        //----------------------------------------------------------------------------------
+    }
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+    UnloadModel(modelA);        // Unload the model A
+    UnloadModel(modelB);        // Unload the model B
+    UnloadModel(modelC);        // Unload the model C
+    UnloadTexture(texture);     // Unload the texture
+    UnloadShader(shader);       // Unload shader
+
+    CloseWindow();              // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+
+    return 0;
+}

BIN
examples/shaders/shaders_fog.png