├── .gitignore
├── README.md
├── ambient_occlusion
├── CMakeLists.txt
├── README.md
├── _AO
│ ├── AO_framebuffer.hpp
│ ├── AO_fshader.glsl
│ ├── AO_vshader.glsl
│ ├── normal_framebuffer.hpp
│ ├── normal_map_fshader.glsl
│ └── normal_map_vshader.glsl
├── glsl
│ ├── cube_fshader.glsl
│ ├── cube_vshader.glsl
│ ├── quad_screen_fshader.glsl
│ └── quad_screen_vshader.glsl
└── main.cpp
├── atmospheric_scattering
├── CMakeLists.txt
├── README.md
├── glsl
│ ├── base_sphere_fshader.glsl
│ ├── base_sphere_vshader.glsl
│ ├── quad_screen_fshader.glsl
│ ├── quad_screen_vshader.glsl
│ ├── sky_sphere_fshader.glsl
│ └── sky_sphere_vshader.glsl
└── main.cpp
├── build
├── bumpmapping
├── CMakeLists.txt
├── README.md
├── _plane
│ ├── plane_float.h
│ ├── plane_tex_fshader.glsl
│ └── plane_tex_vshader.glsl
├── main.cpp
└── texture_float.h
├── common
├── _cube
│ └── cube.h
├── _plane
│ └── plane.h
├── _quad_screen
│ └── quad_screen.h
├── _sphere
│ └── sphere.h
├── camera.h
├── camera_free.h
├── camera_rotate.h
├── depth_framebuffer.hpp
├── drawable.h
├── framebuffer.h
├── noise_generator.hpp
├── shader_helper.h
├── texture.h
└── transform.h
├── framebuffer
├── CMakeLists.txt
├── README.md
├── glsl
│ ├── cube_fshader.glsl
│ ├── cube_vshader.glsl
│ ├── plane_fshader.glsl
│ ├── plane_vshader.glsl
│ ├── quad_screen_fshader.glsl
│ └── quad_screen_vshader.glsl
└── main.cpp
├── grass
├── CMakeLists.txt
├── README.md
├── _grass
│ ├── grass_blades_fshader.glsl
│ ├── grass_blades_vshader.glsl
│ ├── grass_element.h
│ ├── grass_geom_gshader.glsl
│ ├── grass_geom_vshader.glsl
│ ├── grass_manager.h
│ └── grass_manager_geom.h
├── _plane
│ ├── plane_fshader.glsl
│ ├── plane_sine.h
│ └── plane_vshader.glsl
├── _quad_screen
│ ├── quad_screen_fshader.glsl
│ └── quad_screen_vshader.glsl
├── main.cpp
└── texture_float.h
├── lod_terrain
├── CMakeLists.txt
├── README.md
├── _terrain
│ ├── terrain.h
│ ├── terrain_fshader.glsl
│ └── terrain_vshader.glsl
├── _terrain_quad
│ ├── qterrain.h
│ ├── qtree.h
│ └── qtree_test.hpp
├── camera_fps.h
├── glsl
│ ├── quad_screen_fshader.glsl
│ └── quad_screen_vshader.glsl
└── main.cpp
├── mouse_control
├── CMakeLists.txt
├── glsl
│ ├── cube_fshader.glsl
│ ├── cube_vshader.glsl
│ ├── plane_fshader.glsl
│ └── plane_vshader.glsl
└── main.cpp
├── particles
├── CMakeLists.txt
├── README.md
├── _particles_manager
│ ├── fire_particles_fshader.glsl
│ ├── fire_particles_vshader.glsl
│ ├── particles_manager.h
│ ├── snow_particles_fshader.glsl
│ └── snow_particles_vshader.glsl
├── glsl
│ ├── cube_fshader.glsl
│ ├── cube_vshader.glsl
│ ├── quad_screen_fshader.glsl
│ └── quad_screen_vshader.glsl
└── main.cpp
├── rotating_cube
├── CMakeLists.txt
├── glsl
│ ├── cube_fshader.glsl
│ ├── cube_vshader.glsl
│ ├── plane_fshader.glsl
│ └── plane_vshader.glsl
└── main.cpp
├── screenshots
├── ambient_occlusion.gif
├── atmosphere_1.png
├── atmosphere_2.png
├── bumpmapping_1.png
├── bumpmapping_2.png
├── clouds_1.png
├── clouds_2.png
├── framebuffer_1.png
├── framebuffer_2.png
├── framebuffer_3.png
├── grass_1.png
├── lod_terrain_1.png
├── lod_terrain_2.png
├── particles_example.png
├── rotating_cube.png
├── shadow_mapping_1.png
├── shadow_mapping_2.png
├── sky_1.png
├── sky_2.png
├── sphere_light_1.png
├── sphere_light_2.png
├── terrain_camera_1.png
├── terrain_camera_2.png
├── tessellation.png
├── texfiltering_anisotropic.png
├── texfiltering_bilinear.png
├── texfiltering_nearest.png
├── texfiltering_trilinear.png
├── texture_plane_1.png
├── texture_plane_2.png
├── tree_1.png
├── tree_2.png
├── tree_3.png
├── tree_4.png
├── triangle.png
├── volumetric_light_1.png
├── volumetric_light_2.png
├── water_1.png
└── water_2.png
├── shadow_mapping
├── CMakeLists.txt
├── README.md
├── glsl
│ ├── cube_fshader.glsl
│ ├── cube_vshader.glsl
│ ├── quad_screen_fshader.glsl
│ ├── quad_screen_vshader.glsl
│ ├── sphere_fshader.glsl
│ └── sphere_vshader.glsl
└── main.cpp
├── sky
├── CMakeLists.txt
├── README.md
├── _sky
│ ├── sky_fshader.glsl
│ ├── sky_sphere.h
│ └── sky_vshader.glsl
├── glsl
│ ├── cube_fshader.glsl
│ ├── cube_vshader.glsl
│ ├── quad_screen_fshader.glsl
│ ├── quad_screen_vshader.glsl
│ ├── sphere_fshader.glsl
│ └── sphere_vshader.glsl
└── main.cpp
├── sphere_light
├── CMakeLists.txt
├── README.md
├── glsl
│ ├── plane_fshader.glsl
│ ├── plane_vshader.glsl
│ ├── sphere_fshader.glsl
│ └── sphere_vshader.glsl
└── main.cpp
├── terrain_camera
├── CMakeLists.txt
├── README.md
├── _terrain
│ ├── terrain.h
│ ├── terrain_fshader.glsl
│ └── terrain_vshader.glsl
├── camera_fps.h
├── main.cpp
└── transform.h
├── tessellation_shader
├── CMakeLists.txt
├── README.md
├── glsl
│ ├── plane_fshader.glsl
│ ├── plane_tcshader.glsl
│ ├── plane_teshader.glsl
│ ├── plane_vshader.glsl
│ ├── quad_screen_fshader.glsl
│ └── quad_screen_vshader.glsl
└── main.cpp
├── texture_filtering
├── CMakeLists.txt
├── README.md
├── glsl
│ ├── plane_fshader.glsl
│ ├── plane_vshader.glsl
│ ├── quad_screen_fshader.glsl
│ └── quad_screen_vshader.glsl
├── main.cpp
└── texture_checkers.h
├── texture_plane
├── CMakeLists.txt
├── README.md
├── glsl
│ ├── plane_fshader.glsl
│ └── plane_vshader.glsl
├── main.cpp
├── texture_checkers.h
└── the_red_pepper.png
├── tree
├── CMakeLists.txt
├── README.md
├── _trees
│ ├── individual_leaves.h
│ ├── leaves_individual_fshader.glsl
│ ├── leaves_individual_vshader.glsl
│ ├── texture_float.h
│ ├── tree.h
│ ├── trunk.h
│ ├── trunk_fshader.glsl
│ └── trunk_vshader.glsl
├── glsl
│ ├── cube_fshader.glsl
│ ├── cube_vshader.glsl
│ ├── quad_screen_fshader.glsl
│ └── quad_screen_vshader.glsl
└── main.cpp
├── triangle
├── CMakeLists.txt
├── glsl
│ ├── fshader.glsl
│ └── vshader.glsl
└── main.cpp
├── volumetric_clouds
├── CMakeLists.txt
├── README.md
├── cloud_particles_manager.hpp
├── glsl
│ ├── cloud_particles_fshader.glsl
│ ├── cloud_particles_vshader.glsl
│ ├── cube_fshader.glsl
│ ├── cube_vshader.glsl
│ ├── quad_screen_fshader.glsl
│ ├── quad_screen_vshader.glsl
│ ├── sphere_fshader.glsl
│ └── sphere_vshader.glsl
├── main.cpp
└── noise_generator_3d.hpp
├── volumetric_light
├── CMakeLists.txt
├── README.md
├── glsl
│ ├── cube_fshader.glsl
│ ├── cube_vshader.glsl
│ ├── quad_screen_fshader.glsl
│ ├── quad_screen_vshader.glsl
│ ├── sphere_fshader.glsl
│ └── sphere_vshader.glsl
└── main.cpp
└── water
├── CMakeLists.txt
├── README.md
├── _water
├── water.h
├── water_fshader.glsl
└── water_vshader.glsl
├── glsl
├── cube_fshader.glsl
├── cube_vshader.glsl
├── quad_screen_fshader.glsl
├── quad_screen_vshader.glsl
├── sphere_fshader.glsl
└── sphere_vshader.glsl
└── main.cpp
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OpenGL examples
2 |
3 |
4 |
5 |
6 | This is a list of examples done a few years ago after taking a computer graphic course to better understand opengl and apply some of the techniques read in the litterature.
7 |
8 | Content of the repo:
9 |
10 | - Triangle: hello world program, tests the display and the buffers
11 | - Rotating cube: Add movement in the scene and transormation matrices
12 | - Mouse control: Ability to move an object with the mouse similarly to an arcball camera
13 | - Texture plane: Tests textures, both from an image and generated
14 | - Sphere light: Different lightings on a sphere: Flat Goureaud and Phong with interacitvity to select the lighting type
15 | - Terrain camera: A terrain generated with a Perlin noise in which we can navigate with either a free moving camera or a FPS-style one
16 | - Bumpmapping: Simulates bumps on a flat surface using random Perlin noise and pixel shader
17 | - Framebuffer: Displays the scene in a framebuffer, allowing post processing effects: gaussian blur, edge detection, etc.
18 | - LOD Terrain: Implementation of a perlin noise terrain with simple CPU LOD implementation (using quad tree), which is dynamically updated with camera position
19 | - Shadow mapping: Implementation of a dynamic shadow mapping using a depth buffer from the point of view of the light, smoothing techniques are applied on the shadow to make it less pixelated
20 | - Ambient occlusion: Deferred SSAO algorithm done in the shaders which give depth in a scene, a few different algorithms are implemented
21 | - Grass: Display 100k individual grass elements using instanced drawing and geometry shaders and make them move in the wind with a perlin noise
22 | - Water: Reflects objects on a water surface with waves distorting the reflexion
23 | - Sky: Displays a moving sun on a sky-sphere
24 | - Particles: A simple particles system using instanced drawing
25 | - Tree: Procedural generation of realistic trees using L-System
26 | - Atmospheric scattering: implemented in a similar way as in the [GPU Gems 2 book](https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter16.html)
27 | - Volumetric clouds: using combination of 3d and 2d noises and particles
28 | - Texture filtering: use opengl to smooth textures
29 | - Tessellation shader: implement the level of detail directly in a shader
30 | - Volumetric light: post-processing volumetric light using ray casting as in the [GPU Gems 3 book](https://developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-13-volumetric-light-scattering-post-process)
31 |
32 | ## How to build
33 |
34 | Run the `./build` script, it will build each example and the executables will be found in each example folder in the build subfolder. For example `./lod_terrain/build/lod_terrain`
35 |
36 | Alternatively, if you want to do it manually, create a `build` folder in the example you want to build, then from the `build` folder, `cmake ..` to populate it and `make` to build the example
37 |
38 | All of these examples have been tested on the following hardware:
39 |
40 | - Intel HD graphics 620
41 | - Nvidia GeForce 940MX
42 | - Nvidia GeForce RTX 3050 Ti Mobile
43 |
44 | There were compiled on a Linux Mint 20, the needed libraries are the following:
45 |
46 | - glfw 3.3.2
47 | - glew 2.1.0
48 | - devIl 1.7.8
49 | - glm 0.9.9.7
50 |
51 |
52 |
--------------------------------------------------------------------------------
/ambient_occlusion/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME ambient_occlusion)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 |
26 | foreach(glsl_file ${GLSL_FILES})
27 | configure_file(${glsl_file} . COPYONLY)
28 | endforeach(glsl_file)
29 |
30 | #configure_file(${GLSL_FILES} . COPYONLY)
31 |
32 |
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
34 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
35 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
36 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
37 |
--------------------------------------------------------------------------------
/ambient_occlusion/README.md:
--------------------------------------------------------------------------------
1 | # Ambient Occlusion
2 |
3 | 
4 |
5 | This is an implementation of the SSAO algorithm (screen space ambient occlusion) which is done deferred from other processing in a AO shader.
6 |
7 | The SSAO is done for each pixel, using a depth buffer, rays are sent from the given pixel randomly on a short distance, if the ray intercepts
8 | an object, the current pixel will be darker, if not, it won't be shadowed. This has the goal to give edges and corners a darker look which give
9 | a sensation of depth in the scene. A few dozen of these rays/samples have to be averaged to give a decent AO effect. A few additional processing
10 | were evaluated.
11 |
12 | This implementation use a random vector depending on the pixel position in the screen (avoid giving a random vector from the cpp).
13 |
14 | The algorithm finds positions of pixels from the depth buffer in the 3d world using the inverse perspective matrix. Rays are then casted from
15 | this 3d points randomly on a short distance, the resulting vector is then transformed back into a depth using the perspective matrix,
16 | if is the depth value is roughly the same as the depth buffer, it hasn't gone through an object. The number of rays interescting object
17 | give the amount of AO for this pixel.
18 |
19 | Due to the random nature of the algorithm, a post processing gaussian blur is applied on the AO to avoid having noise (which would have to be
20 | mitigated by a lot of sampling).
21 |
22 | In order to improve the visual quality without using too many samples, it is possible to add a few techiniques:
23 | - use a distribution to concentrate the rays near the origin
24 | - send the rays on an hemisphere on the normal of the pixel instead of a sphere (this needs a normal framebuffer). This is really the best for surfaces
25 | because sphere sampling will give a normal value centered on 0.5, whereas hemisphere should give an AO value of 0.
26 |
27 | # Controls
28 |
29 | - WASD: moves the camera
30 | - IJKL: change camera view direction
31 | - E: is no SSAO to see how dull the scene looks
32 | - R: is SSAO without randomisation, which gives "stripes" and glitches
33 | - T: is SSAO with randomisation
34 | - Y: is SSAO with randomisation and a smart distribution which concentrate samples around the origin of the sampling sphere
35 | - U: is SSAO with rand. but using an hemisphere instead of a sphere, allowing to have better results on surfaces
36 |
--------------------------------------------------------------------------------
/ambient_occlusion/_AO/AO_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/ambient_occlusion/_AO/normal_framebuffer.hpp:
--------------------------------------------------------------------------------
1 | #ifndef NORMAL_FRAMEBUFFER_HPP
2 | #define NORMAL_FRAMEBUFFER_HPP
3 |
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include "shader_helper.h"
13 | #include "drawable.h"
14 | #include "camera.h"
15 |
16 | //keeps normals in a framebuffer
17 | class Normal_framebuffer{
18 | public:
19 | void init(unsigned tex_width, unsigned tex_height){
20 |
21 | camera = NULL;
22 |
23 | _pid_normal = load_shaders("normal_map_vshader.glsl", "normal_map_fshader.glsl");
24 |
25 | this->tex_width = tex_width;
26 | this->tex_height = tex_height;
27 |
28 | // The framebuffer, which regroups 0, 1, or more textures, and 0 or 1 depth buffer.
29 | glGenFramebuffers(1, &fbo);
30 | glBindFramebuffer(GL_FRAMEBUFFER, fbo);
31 |
32 | // Depth texture. Slower than a depth buffer, but you can sample it later in your shader
33 | glGenTextures(1, &texture_id);
34 | glBindTexture(GL_TEXTURE_2D, texture_id);
35 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
36 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
37 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
38 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
39 |
40 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, tex_width, tex_height, 0, GL_RGB, GL_FLOAT, 0);
41 |
42 | glBindTexture(GL_TEXTURE_2D, 0);
43 |
44 | //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, texture_id, 0);
45 | glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0);
46 |
47 | glGenRenderbuffers(1, &_depth_rb);
48 | glBindRenderbuffer(GL_RENDERBUFFER, _depth_rb);
49 |
50 | glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, tex_width, tex_height);
51 | glBindRenderbuffer(GL_RENDERBUFFER, 0);
52 |
53 | glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depth_rb);
54 |
55 | if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
56 | std::cerr << "!!!ERROR: depth Framebuffer not OK :(" << std::endl;
57 |
58 | glBindFramebuffer(GL_FRAMEBUFFER, 0);
59 | }
60 |
61 | void set_camera(Camera *cam){
62 | this->camera = cam;
63 | }
64 |
65 | void draw_fb(std::vector *lst_drawable){
66 |
67 | glm::mat4x4 view_mat;
68 | glm::mat4x4 projection_mat;
69 |
70 | if(this->camera != NULL){
71 | view_mat = camera->getMatrix();
72 | projection_mat = camera->get_perspective_mat();
73 | }
74 |
75 | glBindFramebuffer(GL_FRAMEBUFFER, fbo);
76 | glViewport(0, 0, tex_width, tex_height);
77 |
78 | glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
79 |
80 | // Draw from the light’s point of view
81 | for (size_t i = 0; i < lst_drawable->size(); i++) {
82 | //update the view and projection matrices
83 |
84 | GLuint shader_before = lst_drawable->at(i)->get_shader();
85 | lst_drawable->at(i)->set_view_matrix(view_mat);
86 | lst_drawable->at(i)->set_projection_matrix(projection_mat);
87 | lst_drawable->at(i)->set_shader(_pid_normal);
88 |
89 | lst_drawable->at(i)->draw();
90 | lst_drawable->at(i)->set_shader(shader_before);
91 | }
92 |
93 | glBindFramebuffer(GL_FRAMEBUFFER, 0);
94 | }
95 |
96 | GLuint get_texture_id(){
97 | return texture_id;
98 | }
99 |
100 | protected:
101 | GLuint texture_id;
102 | unsigned int tex_width;
103 | unsigned int tex_height;
104 | GLuint fbo;
105 | GLuint _pid_normal;
106 | GLuint _depth_rb;
107 |
108 | Camera *camera;
109 | };
110 |
111 | #endif
112 |
--------------------------------------------------------------------------------
/ambient_occlusion/_AO/normal_map_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 normal;
4 | in vec3 view_normal;
5 |
6 | out vec4 color;
7 |
8 | void main(void){
9 | color = vec4(normal, 1.0);
10 | color = vec4(view_normal, 1.0);
11 | }
12 |
--------------------------------------------------------------------------------
/ambient_occlusion/_AO/normal_map_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec3 surface_normal;
5 | uniform mat4 model;
6 | uniform mat4 view;
7 | uniform mat4 projection;
8 |
9 | out vec3 normal;
10 | out vec3 view_normal;
11 |
12 | void main(){
13 | gl_Position = projection*view*model*vec4(position, 1.0);
14 | normal = vec3( transpose(inverse(model))*vec4(surface_normal, 1.0) );
15 | normal = normalize(normal);
16 | view_normal = vec3( transpose(inverse(view))*vec4(normal, 1.0) );
17 | view_normal = normalize(view_normal);
18 | }
19 |
--------------------------------------------------------------------------------
/ambient_occlusion/glsl/cube_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 | uniform vec3 light_position;
8 | in vec3 surface_normal;
9 |
10 | uniform mat4 shadow_matrix; //bias*P*V
11 |
12 | out vec3 frag_surface_normal_color;
13 | out vec3 frag_position;
14 | out vec3 frag_normal;
15 | out float red;
16 | out float green;
17 | out float blue;
18 |
19 | out vec4 shadow_coord;
20 |
21 | void main(){
22 | gl_Position = projection*view*model*vec4(position, 1.0);
23 | frag_position = position;
24 |
25 | mat3 normalMat = mat3(model);
26 | normalMat = transpose(inverse(normalMat));
27 |
28 | vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
29 |
30 | vec3 normal_transformed = vec3(0.0);
31 | normal_transformed = normalize(normalMat*surface_normal);
32 |
33 | float diffuse_light = 0.0;
34 | diffuse_light = dot(normal_transformed, light_dir);
35 |
36 | float lum = 1.0*diffuse_light;
37 | lum = clamp(lum, 0.0, 1.0);
38 | frag_surface_normal_color = vec3(lum, lum, lum);
39 |
40 | shadow_coord = shadow_matrix * model*vec4(position, 1.0);
41 | frag_normal = surface_normal;
42 | }
43 |
44 | void main_colors_const(){
45 | gl_Position = projection*view*model*vec4(position, 1.0);
46 | red = green = blue = 0.0;
47 |
48 | if(gl_VertexID == 0){
49 | red = 1.0;
50 | }
51 | else if(gl_VertexID == 1){
52 | green = 1.0;
53 | }
54 | else if(gl_VertexID == 2){
55 | blue = 1.0;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ambient_occlusion/glsl/quad_screen_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | uniform sampler2D tex;
3 | uniform sampler2D ao_tex;
4 | //uniform sampler2DMS tex;
5 | uniform float tex_width;
6 | uniform float tex_height;
7 | in vec2 uv;
8 | out vec3 color;
9 |
10 | uniform uint effect_select;
11 |
12 | const int blurring_mat_small_size = 3;
13 | float blurring_mat_small[blurring_mat_small_size] = float[](1, 2, 1);
14 | float blurring_mat_small_coef = 1.0/16.0;
15 |
16 | const int blurring_mat_med_size = 5;
17 | float blurring_mat_med[blurring_mat_med_size] = float[](1, 4, 6, 4, 1);
18 | float blurring_mat_med_coef = 1.0/256.0;
19 |
20 |
21 | float average(vec3 vec){
22 | return (vec.x+vec.y+vec.z)/3;
23 | }
24 |
25 | float col_to_gs(vec3 vec){
26 | return 0.21*vec.x + 0.72*vec.y + 0.07*vec.z;
27 | }
28 |
29 | float get_ao_blur(vec2 center){
30 | float ao_out = 0.0;
31 | for(int i = 0; i < blurring_mat_med_size; i++){
32 | int rel_i = i-(blurring_mat_med_size-1)/2;
33 | float sum = 0.0;
34 | for(int j = 0; j < blurring_mat_med_size; j++){
35 | int rel_j = j-(blurring_mat_med_size-1)/2;
36 | float matrix_val = blurring_mat_med[i]*blurring_mat_med[j];
37 | ao_out += matrix_val*texture(ao_tex, uv+vec2(rel_i/tex_width,rel_j/tex_height)).r;
38 | }
39 | }
40 | return ao_out*blurring_mat_med_coef;
41 | }
42 |
43 | void main() {
44 |
45 | vec3 color_out = vec3(0.5, 1.0, 0.0);
46 |
47 | if(effect_select == 0u){ //normal
48 | color_out = texture(tex, uv).rgb*get_ao_blur(uv);
49 | }
50 |
51 | color = color_out;
52 | }
53 |
--------------------------------------------------------------------------------
/ambient_occlusion/glsl/quad_screen_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/atmospheric_scattering/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME atmospheric_scattering)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Debug)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 |
26 | foreach(glsl_file ${GLSL_FILES})
27 | configure_file(${glsl_file} . COPYONLY)
28 | endforeach(glsl_file)
29 |
30 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
31 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
32 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
34 |
--------------------------------------------------------------------------------
/atmospheric_scattering/README.md:
--------------------------------------------------------------------------------
1 | # Atmospheric scattering
2 |
3 |  
4 |
5 | Implementation (with some liberties) of https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter16.html
6 |
7 | The optimisations explained in 16.3 were implemented allowing for a responsive framerate (>30) on a very modest GPU (Intel HD Graphics 620).
8 |
9 | A simple noise function was used to make some "islands" on the planet.
10 |
11 | # Controls
12 | - WASD: moves the camera
13 | - IJKL: change camera view direction
14 | - MN: freezes the sun direction
15 |
--------------------------------------------------------------------------------
/atmospheric_scattering/glsl/base_sphere_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec3 surface_normal;
5 | in vec3 vertex_normal;
6 | uniform vec3 light_position;
7 | uniform vec3 camera_position;
8 |
9 | uniform mat4 model;
10 | uniform mat4 view;
11 | uniform mat4 projection;
12 |
13 | out vec3 frag_normal_transformed;
14 | out vec3 frag_pos;
15 |
16 | void main(){
17 | gl_Position = projection*view*model*vec4(position, 1.0);
18 | frag_pos = vec3(model*vec4(position, 1.0));
19 |
20 | //model matrix for normals needs to be ((mat)⁻¹)^T
21 | mat3 normalMat = mat3(model);
22 | normalMat = transpose(inverse(normalMat));
23 |
24 | vec3 normal_transformed = normalize(normalMat*vertex_normal);
25 | normal_transformed = clamp(normal_transformed, 0.0, 1.0);
26 |
27 | frag_normal_transformed = normal_transformed;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/atmospheric_scattering/glsl/quad_screen_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/atmospheric_scattering/glsl/sky_sphere_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec3 surface_normal;
5 | in vec3 vertex_normal;
6 | uniform vec3 light_position;
7 | uniform vec3 camera_position;
8 |
9 | uniform mat4 model;
10 | uniform mat4 view;
11 | uniform mat4 projection;
12 |
13 | out vec3 frag_normal_transformed;
14 | out vec3 frag_pos;
15 |
16 | void main(){
17 | gl_Position = projection*view*model*vec4(position, 1.0);
18 | frag_pos = vec3(model*vec4(position, 1.0));
19 |
20 | //model matrix for normals needs to be ((mat)⁻¹)^T
21 | mat3 normalMat = mat3(model);
22 | normalMat = transpose(inverse(normalMat));
23 |
24 | vec3 normal_transformed = normalize(normalMat*vertex_normal);
25 | normal_transformed = clamp(normal_transformed, 0.0, 1.0);
26 |
27 | frag_normal_transformed = normal_transformed;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/build:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # A build script to automatically install dependencies (on debian, tested on ubuntu 22.04) and build all of the projects for this repo
4 | # Usage: $ ./build [folder name]
5 | # you can also run './build all' or simply './build' to build all the projects
6 | # if you want to clean the projects, you can run './build clean'
7 | # if you want to remove the 'build' dirs, you can run './build deepclean'
8 | # The script prompts you about missing dependencies, press 'y' to install them
9 |
10 | # Set to 1 to skip the dependency checks.
11 | # Automatically gets set to 1 after a successful run to not waste your time
12 | # If you are having issues with dependencies, try setting this to 0 as a first measure
13 | skip_dep_checks=1
14 |
15 | odir="$(pwd)"
16 | opt="${1:-all}"
17 |
18 | function fail() {
19 | printf >&2- "$1"
20 | cd $odir
21 | exit 1
22 | }
23 |
24 | [[ $(id -u) == 0 ]] && fail "Don't run this script as root.\n"
25 | [[ ! $odir =~ .*opengl_examples.* ]] && fail "Is the project/repo root directory called 'opengl_examples'?\nIf you cloned the repo, git should have created an 'opengl_examples' directory. Run the script from there.\n"
26 |
27 | function do_build() {
28 | printf "\n====================\nSubproject $1...\n\n"
29 | cd "$1" || fail "\nDirectory $1 may not exist...\nBuild $1 failed.\n"
30 | if [[ ! -d build ]]; then
31 | mkdir -p build >> /dev/null
32 | cd build
33 | cmake .. || fail "\nCMake failed...\nBuild $1 failed.\n"
34 | else
35 | cd build
36 | fi
37 | if [[ ! -z $2 ]]; then
38 | make "$2" || fail "\nTarget '$2' didn't succeed...\nBuild $1 failed.\n"
39 | else
40 | make || fail "\nCode didn't compile...\nBuild $1 failed.\n"
41 | fi
42 | cd ../..
43 | }
44 |
45 | function dep() {
46 | # debian specific, you can change apt and apt-get to be
47 | apt list --installed "$1" 2>&1 | grep "$1" > /dev/null
48 | if [[ $? != 0 ]]; then
49 | printf "\n====================\nYou do not have $1 installed.\n"
50 | inp=""
51 | read -a inp -n 1 -p "Install it (runs apt--press \"y\"): "
52 | if [[ $inp == "y" ]]; then
53 | printf "\n"
54 | [[ $inp != "" ]] && printf "\n"
55 | sudo apt-get -y install "$1" || fail "Failed to install $1\n"
56 | else
57 | [[ $inp != "" ]] && printf "\n"
58 | fail "Failed due to missing dependency.\n"
59 | fi
60 | fi
61 | }
62 |
63 |
64 | if [[ $skip_dep_checks != 1 ]]; then
65 | dep "libglfw3-dev"
66 | dep "libglm-dev"
67 | dep "libglew-dev"
68 | dep "libdevil-dev"
69 | pt1='s/skip_dep'
70 | pt2='_checks=0/skip_dep_checks=1/g'
71 | cat build | sed -i "$pt1$pt2" build
72 | fi
73 |
74 | # get to the root directory
75 | ndir=${odir%%/opengl_examples*}
76 | cd "$ndir/opengl_examples"
77 |
78 | if [[ $opt == "all" ]]; then
79 | echo "Building $opt..."
80 | for i in $(ls); do
81 | if [[ -f "$i/CMakeLists.txt" ]]; then
82 | do_build "$i"
83 | fi
84 | done
85 | elif [[ $opt == "clean" ]]; then
86 | echo "Cleaning..."
87 | for i in $(ls); do
88 | if [[ -f "$i/CMakeLists.txt" ]]; then
89 | do_build "$i" clean
90 | fi
91 | done
92 | elif [[ $opt == "deepclean" ]]; then
93 | echo "Deep Cleaning..."
94 | for i in $(ls); do
95 | if [[ -d "$i/build" ]]; then
96 | rm -fr "$i/build"
97 | fi
98 | done
99 | else
100 | if [[ -f "$opt/CMakeLists.txt" ]]; then
101 | do_build "$opt"
102 | else
103 | fail "\n====================\nCannot build '$opt'.\n"
104 | fi
105 | fi
106 |
107 | cd $odir
108 |
--------------------------------------------------------------------------------
/bumpmapping/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME bumpmapping)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 |
26 | foreach(glsl_file ${GLSL_FILES})
27 | configure_file(${glsl_file} . COPYONLY)
28 | endforeach(glsl_file)
29 |
30 | #configure_file(${GLSL_FILES} . COPYONLY)
31 |
32 |
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
34 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
35 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
36 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
37 |
--------------------------------------------------------------------------------
/bumpmapping/README.md:
--------------------------------------------------------------------------------
1 | # Bumpmapping
2 |
3 |  
4 |
5 | Generates a Perlin noise texture to be applied on a surface, the pixel shader of the surface will then calculate the normals given the hightmap texture and create shading. This gives
6 | the impression that the surface has bumps when it is flat, so an economy of polygons.
7 |
8 | In addition to perlin, a voronoi type noise is used for the bumpmapping
9 |
10 | Here the heightmap is stored directly into the texture and then the normals are calculated in the GPU by derivation
11 |
12 | A moving light and camera goes around the surface to demonstrate the effect.
13 |
14 | # Controls
15 |
16 | - WASD: move the camera
17 | - IJKL: change the direction of camera
18 | - B/W: deactivate/activate moving light (active by default)
19 | - 1: selects the Perlin noise (default)
20 | - 2: selects the voronoi noise
21 |
--------------------------------------------------------------------------------
/bumpmapping/_plane/plane_float.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "shader_helper.h"
8 | #include "../texture_float.h"
9 | #include "_plane/plane.h"
10 |
11 | //plane with floating texture
12 | class Plane_float : public Plane{
13 | public:
14 |
15 | void set_texture(const Texture_float *tex){
16 | if(_tex != 0){
17 | //delete current texture
18 | glDeleteTextures(1, &_tex);
19 | _tex = 0;
20 | }
21 |
22 | //texture data definition
23 | glGenTextures(1, &_tex);
24 | glBindTexture(GL_TEXTURE_2D, _tex);
25 | glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, tex->get_width(), tex->get_height(), 0, GL_RED, GL_FLOAT, tex->get_tex_data());
26 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
27 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
28 | GLuint tex_id = glGetUniformLocation(_pid, "tex");
29 | glUniform1i(tex_id, 0 /*GL_TEXTURE0*/);
30 |
31 | }
32 |
33 | void draw(glm::mat4x4 model, glm::mat4x4 view, glm::mat4x4 projection, GLfloat light_position[3], GLfloat camera_position[3]){
34 | glUseProgram(_pid);
35 | glBindVertexArray(_vao);
36 |
37 | glUniform3fv( glGetUniformLocation(_pid, "light_position"), 1, light_position);
38 | glUniform3fv( glGetUniformLocation(_pid, "camera_position"), 1, camera_position);
39 |
40 | glUniformMatrix4fv( glGetUniformLocation(_pid, "model"), 1, GL_FALSE, glm::value_ptr(model));
41 | glUniformMatrix4fv( glGetUniformLocation(_pid, "view"), 1, GL_FALSE, glm::value_ptr(view));
42 | glUniformMatrix4fv( glGetUniformLocation(_pid, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
43 |
44 | glActiveTexture(GL_TEXTURE0);
45 | glBindTexture(GL_TEXTURE_2D, _tex);
46 |
47 | glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
48 |
49 | glUseProgram(0);
50 | glBindVertexArray(0);
51 | }
52 |
53 | void cleanup(){
54 | glDeleteBuffers(1, &_vbo);
55 | glDeleteVertexArrays(1, &_vao);
56 | glDeleteProgram(_pid);
57 | }
58 |
59 | private:
60 | GLuint _tex;
61 | };
62 |
--------------------------------------------------------------------------------
/bumpmapping/_plane/plane_tex_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 frag_position;
4 |
5 | uniform vec3 camera_position;
6 | uniform vec3 light_position;
7 |
8 | in vec2 uv;
9 | uniform sampler2D tex;
10 |
11 | out vec3 color;
12 |
13 | void main(){
14 | vec3 light_dir = normalize(light_position-frag_position);
15 | float light_length = length(light_position-frag_position);
16 | float diffuse_light = 0.0;
17 | float spec_light = 0.0;
18 |
19 | vec3 frag_normal_transformed = vec3(0.0, 1.0, 0.0);
20 |
21 | //find normal from texture
22 | const float EPSILON_DERIVATIVE = 1.0/1024.0;
23 | float point_x_before = texture(tex, uv+vec2(-EPSILON_DERIVATIVE, 0.0)).r;
24 | float point_x_after = texture(tex, uv+vec2(EPSILON_DERIVATIVE, 0.0)).r;
25 | float point_y_before = texture(tex, uv+vec2(0.0, -EPSILON_DERIVATIVE)).r;
26 | float point_y_after = texture(tex, uv+vec2(0.0, EPSILON_DERIVATIVE)).r;
27 |
28 | vec3 der_x = normalize(vec3(2*EPSILON_DERIVATIVE, point_x_after-point_x_before, 0.0));
29 | vec3 der_y = normalize(vec3(0.0, point_y_after-point_y_before, 2*EPSILON_DERIVATIVE));
30 |
31 | vec3 normal = normalize(cross(der_y, der_x));
32 |
33 | //by adding to the y component, we make the surface less "rough"
34 | frag_normal_transformed = normalize(normal+vec3(0.0, 1.5, 0.0));
35 |
36 | //calculations for specular light
37 | vec3 reflexion = 2*frag_normal_transformed*dot(frag_normal_transformed, light_dir)-light_dir;
38 | reflexion = normalize(reflexion);
39 | vec3 view_dir = normalize(camera_position-frag_position);
40 |
41 | spec_light = pow(max(dot(reflexion, view_dir), 0.0), 16);
42 | spec_light = clamp(spec_light, 0.0, 1.0);
43 |
44 | diffuse_light = dot(frag_normal_transformed, light_dir)/(light_length/2.0);
45 | diffuse_light = clamp(diffuse_light, 0.0, 1.0);
46 |
47 | float lum = 1.0*diffuse_light+0.5*spec_light;
48 | lum = clamp(lum, 0.0, 1.0);
49 |
50 | color = 1.0*vec3(lum)+0.0*vec3(texture(tex, uv).r);
51 | }
52 |
--------------------------------------------------------------------------------
/bumpmapping/_plane/plane_tex_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 vpoint;
4 | in vec2 vtexcoord;
5 | uniform mat4 model;
6 | uniform mat4 view;
7 | uniform mat4 projection;
8 |
9 | uniform vec3 light_position;
10 | uniform vec3 camera_position;
11 |
12 | out vec3 frag_position;
13 | out vec2 uv;
14 |
15 | void main(){
16 | gl_Position = projection*view*model*vec4(vpoint, 1.0);
17 |
18 | frag_position = vec3(model*vec4(vpoint, 1.0));
19 | uv = vtexcoord;
20 | }
21 |
--------------------------------------------------------------------------------
/bumpmapping/texture_float.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | //texture that use float instead of uint to represent its values
7 | class Texture_float{
8 | public:
9 | Texture_float(){
10 | tex_data = NULL;
11 | }
12 |
13 | ~Texture_float(){
14 | if(tex_data != NULL){
15 | delete tex_data;
16 | }
17 | }
18 |
19 | void set_data(const std::vector > &tex_data){
20 | this->tex_height = tex_data[0].size();
21 | this->tex_width = tex_data.size();
22 |
23 | this->tex_data = new float[tex_height*tex_width];
24 |
25 | for(unsigned int i = 0; i < tex_data.size(); i++){
26 | for(unsigned int j = 0; j < tex_data[0].size(); j++){
27 |
28 | this->tex_data[i*tex_width+j] = tex_data[i][j];
29 | }
30 | }
31 | }
32 |
33 | //return the data of the image in bytes
34 | float *get_tex_data() const {
35 | return tex_data;
36 | }
37 |
38 | int get_width() const{
39 | return tex_width;
40 | }
41 |
42 | int get_height() const{
43 | return tex_height;
44 | }
45 |
46 | protected:
47 | unsigned int tex_width;
48 | unsigned int tex_height;
49 | float *tex_data;
50 | };
51 |
--------------------------------------------------------------------------------
/common/_quad_screen/quad_screen.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // two triangles that should take all the screen space to draw the framebuffer
4 | class Quad_screen{
5 |
6 | public:
7 | //texture is the framebuffer
8 | void init(GLuint texture, unsigned int screen_width, unsigned int screen_height, GLuint pid){
9 |
10 | this->_width = screen_width;
11 | this->_height = screen_height;
12 |
13 | _pid = pid;
14 | if(_pid == 0) exit(-1);
15 | glUseProgram(_pid);
16 |
17 | glGenVertexArrays(1, &_vao);
18 | glBindVertexArray(_vao);
19 |
20 | const GLfloat vpoint[] = { -1.0f, -1.0f, 0.0f,
21 | +1.0f, -1.0f, 0.0f,
22 | -1.0f, +1.0f, 0.0f,
23 | +1.0f, +1.0f, 0.0f };
24 |
25 | glGenBuffers(1, &_vbo);
26 | glBindBuffer(GL_ARRAY_BUFFER, _vbo);
27 | glBufferData(GL_ARRAY_BUFFER, sizeof(vpoint), vpoint, GL_STATIC_DRAW);
28 |
29 | GLuint vpoint_id = glGetAttribLocation(_pid, "vpoint");
30 | glEnableVertexAttribArray(vpoint_id);
31 | glVertexAttribPointer(vpoint_id, 3, GL_FLOAT, GL_FALSE, 0, NULL);
32 |
33 | const GLfloat vtexcoord[] = { /*V1*/ 0.0f, 0.0f,
34 | /*V2*/ 1.0f, 0.0f,
35 | /*V3*/ 0.0f, 1.0f,
36 | /*V4*/ 1.0f, 1.0f};
37 |
38 | glGenBuffers(1, &_vbo);
39 | glBindBuffer(GL_ARRAY_BUFFER, _vbo);
40 | glBufferData(GL_ARRAY_BUFFER, sizeof(vtexcoord), vtexcoord, GL_STATIC_DRAW);
41 |
42 | GLuint vtexcoord_id = glGetAttribLocation(_pid, "vtexcoord");
43 | glEnableVertexAttribArray(vtexcoord_id);
44 | glVertexAttribPointer(vtexcoord_id, 2, GL_FLOAT, GL_FALSE, 0, NULL);
45 |
46 | this->_tex = texture;
47 |
48 | glBindVertexArray(0);
49 | glUseProgram(0);
50 | }
51 |
52 |
53 | void load_texture(GLuint texture){
54 | this->_tex = texture;
55 | }
56 |
57 | void set_ao_texture(GLuint ao_tex){
58 | this->_ao_tex = ao_tex;
59 | }
60 |
61 | void set_depth_texture(GLuint depth_tex){
62 | this->_depth_tex = depth_tex;
63 | }
64 |
65 | void cleanup(){
66 | /// TODO
67 | }
68 |
69 | void draw(unsigned int effect_select){
70 | glUseProgram(_pid);
71 | glBindVertexArray(_vao);
72 |
73 | glViewport(0, 0, _width, _height);
74 |
75 | glUniform1ui( glGetUniformLocation(_pid, "effect_select"), effect_select);
76 | glUniform1f( glGetUniformLocation(_pid, "tex_width"), _width);
77 | glUniform1f( glGetUniformLocation(_pid, "tex_height"), _height);
78 |
79 | glActiveTexture(GL_TEXTURE0);
80 | glBindTexture(GL_TEXTURE_2D, _tex);
81 | GLuint tex_id = glGetUniformLocation(_pid, "tex");
82 | glUniform1i(tex_id, 0 /*GL_TEXTURE0*/);
83 |
84 | glActiveTexture(GL_TEXTURE1);
85 | glBindTexture(GL_TEXTURE_2D, _ao_tex);
86 | tex_id = glGetUniformLocation(_pid, "ao_tex");
87 | glUniform1i(tex_id, 1 /*GL_TEXTURE1*/);
88 |
89 | glActiveTexture(GL_TEXTURE2);
90 | glBindTexture(GL_TEXTURE_2D, _depth_tex);
91 | tex_id = glGetUniformLocation(_pid, "depth_tex");
92 | glUniform1i(tex_id, 2 /*GL_TEXTURE1*/);
93 |
94 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
95 |
96 | glBindTexture(GL_TEXTURE_2D, 0);
97 | glBindVertexArray(0);
98 | glUseProgram(0);
99 | }
100 |
101 | protected:
102 | GLuint _vao;
103 | GLuint _pid;
104 | GLuint _vbo;
105 | GLuint _tex;
106 | GLuint _ao_tex;
107 | GLuint _depth_tex;
108 | unsigned int _width;
109 | unsigned int _height;
110 | };
111 |
--------------------------------------------------------------------------------
/common/camera.h:
--------------------------------------------------------------------------------
1 | #ifndef CAMERA_H
2 | #define CAMERA_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | //fixed camera
10 | class Camera{
11 | public:
12 | Camera(){
13 |
14 | }
15 |
16 | virtual void lookAt(glm::vec3 eye, glm::vec3 center, glm::vec3 up){
17 | this->eye = eye;
18 | this->center = center;
19 | this->up = up;
20 | }
21 |
22 | virtual void lookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ){
23 | lookAt(glm::vec3(eyeX, eyeY, eyeZ), glm::vec3(centerX, centerY, centerZ), glm::vec3(upX, upY, upZ));
24 | }
25 |
26 | void get_position(float position[3]){
27 | position[0] = eye.x;
28 | position[1] = eye.y;
29 | position[2] = eye.z;
30 | }
31 |
32 | void get_direction(float direction[3]){
33 | direction[0] = center.x-eye.x;
34 | direction[1] = center.y-eye.y;
35 | direction[2] = center.z-eye.z;
36 | }
37 |
38 | void get_center(float center[3]){
39 | center[0] = this->center.x;
40 | center[1] = this->center.y;
41 | center[2] = this->center.z;
42 | }
43 |
44 |
45 | glm::mat4x4 getMatrix(){
46 | return glm::lookAt(eye, center, up);
47 | }
48 |
49 | glm::mat4x4 get_reflection_matrix(float height){
50 | //just return another lookat on the other side of the plane (only plane along y)
51 | return glm::lookAt(glm::vec3(eye.x, -eye.y+height*2, eye.z), glm::vec3(center.x, -center.y+height*2, center.z), up);
52 | }
53 |
54 | glm::mat4x4 get_perspective_mat(){
55 | return glm::perspective(3.1415f/2.0f, (float)win_width/(float)win_height, 0.1f, 1000.0f);
56 | }
57 |
58 | virtual void input_handling(char, float){
59 |
60 | }
61 |
62 | virtual void update_pos(){
63 |
64 | }
65 |
66 | virtual void set_window_size(unsigned int win_width, unsigned int win_height){
67 | this->win_width = win_width;
68 | this->win_height = win_height;
69 | }
70 |
71 | protected:
72 | //for the lookat functon
73 | glm::vec3 eye;
74 | glm::vec3 center;
75 | glm::vec3 up;
76 |
77 | unsigned int win_width;
78 | unsigned int win_height;
79 | };
80 |
81 | #endif
82 |
--------------------------------------------------------------------------------
/common/camera_rotate.h:
--------------------------------------------------------------------------------
1 | #ifndef CAMERA_ROTATE_H
2 | #define CAMERA_ROTATE_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include "camera.h"
10 |
11 | class Camera_rotate : public Camera{
12 | public:
13 | Camera_rotate(){
14 |
15 | }
16 |
17 | void init(glm::vec3 center, float radius, float speed){
18 | this->eye = glm::vec3(radius, 0, 0);
19 | this->center = center;
20 | this->up = glm::vec3(0, 1, 0);
21 | this->normal_y_rot = glm::vec3(0, 0, 1);
22 | this->angle_speed = speed;
23 | }
24 |
25 | void init(float center_x, float center_y, float center_z, float radius, float speed){
26 | init(glm::vec3(center_x, center_y, center_z), radius, speed);
27 | }
28 |
29 | void rotate_angle_x(float angle){
30 | glm::mat4 rot_mat = glm::mat4(1.0); //identity
31 |
32 | rot_mat = glm::rotate(rot_mat, angle*this->angle_speed, glm::vec3(0.0, 1.0, 0.0));
33 |
34 | this->eye = glm::vec3(rot_mat*glm::vec4(this->eye, 0.0));
35 |
36 | //keep rotate the normal for y_rot so that it rotates with the camera
37 | this->normal_y_rot = glm::vec3(rot_mat*glm::vec4(this->normal_y_rot, 0.0));
38 |
39 | this->angle_x += angle*this->angle_speed;
40 | }
41 |
42 | void rotate_angle_y(float angle){
43 | glm::mat4 rot_mat = glm::mat4(1.0); //identity
44 |
45 | this->angle_y += angle*this->angle_speed;
46 |
47 | if(this->angle_y > M_PI/2){
48 | this->angle_y = M_PI/2;
49 | return;
50 | }
51 |
52 | if(this->angle_y < -M_PI/2){
53 | this->angle_y = -M_PI/2;
54 | return;
55 | }
56 | rot_mat = glm::rotate(rot_mat, angle*this->angle_speed, this->normal_y_rot);
57 |
58 | this->eye = glm::vec3(rot_mat*glm::vec4(this->eye, 0.0));
59 | }
60 |
61 | protected:
62 | glm::vec3 normal_y_rot;
63 |
64 | float angle_x;
65 | float angle_y;
66 |
67 | float angle_speed;
68 | };
69 |
70 | #endif
71 |
--------------------------------------------------------------------------------
/common/texture.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | class Texture{
7 | public:
8 | Texture(){
9 | tex_data = NULL;
10 | }
11 |
12 | ~Texture(){
13 | if(tex_data != NULL){
14 | delete tex_data;
15 | }
16 | }
17 |
18 | //load image from disk
19 | bool load_image(const char *path){
20 | ilGenImages(1, &tex_id);
21 | ilBindImage(tex_id);
22 |
23 | ILboolean result = ilLoadImage(path);
24 |
25 | if(result == IL_FALSE){
26 | return false;
27 | }
28 |
29 | tex_width = ilGetInteger(IL_IMAGE_WIDTH);
30 | tex_height = ilGetInteger(IL_IMAGE_HEIGHT);
31 |
32 | tex_data = new unsigned char[tex_width*tex_height*3];
33 |
34 | ilCopyPixels(0, 0, 0, tex_width, tex_height, 1, IL_RGB, IL_UNSIGNED_BYTE, tex_data);
35 |
36 | //unbind the image as the image data has been copyied
37 | ilBindImage(0);
38 | ilDeleteImage(tex_id);
39 |
40 | return true;
41 | }
42 |
43 | //return the data of the image in bytes
44 | unsigned char *get_tex_data() const {
45 | return tex_data;
46 | }
47 |
48 | int get_width() const{
49 | return tex_width;
50 | }
51 |
52 | int get_height() const{
53 | return tex_height;
54 | }
55 |
56 | protected:
57 | ILuint tex_id;
58 | ILint tex_width;
59 | ILint tex_height;
60 | unsigned char *tex_data;
61 | };
62 |
--------------------------------------------------------------------------------
/common/transform.h:
--------------------------------------------------------------------------------
1 | #ifndef TRANSFORM_H
2 | #define TRANSFORM_H
3 |
4 | #include
5 | #include
6 | #include //perspective
7 |
8 | class Transform{
9 | public:
10 | Transform(){
11 | transform_mat = glm::mat4(1.0f); //identity
12 | }
13 |
14 | void scale(glm::vec3 vec){
15 | transform_mat = glm::scale(transform_mat, vec);
16 | }
17 |
18 | void scale(float x, float y, float z){
19 | this->scale(glm::vec3(x, y, z));
20 | }
21 |
22 | void translate(glm::vec3 vec){
23 | transform_mat = glm::translate(transform_mat, vec);
24 | }
25 |
26 | void translate(float x, float y, float z){
27 | this->translate(glm::vec3(x, y, z));
28 | }
29 |
30 | void rotate(glm::vec3 vec, float angle){
31 | transform_mat = glm::rotate(transform_mat, angle, vec);
32 | }
33 |
34 | void rotate(float x, float y, float z, float angle){
35 | this->rotate(glm::vec3(x, y, z), angle);
36 | }
37 |
38 | void mult(Transform t){
39 | this->transform_mat *= t.get_matrix();
40 | }
41 |
42 | void mult(glm::mat4 m){
43 | this->transform_mat *= m;
44 | }
45 |
46 | glm::mat4 get_matrix(){
47 | return transform_mat;
48 | }
49 |
50 | glm::vec3 transform_point(glm::vec3 point3){
51 | glm::vec4 point4 = glm::vec4(point3, 1.0f);
52 | point4 = transform_mat*point4;
53 | return glm::vec3(point4);
54 | }
55 |
56 | ~Transform(){
57 | }
58 |
59 |
60 | protected:
61 | glm::mat4 transform_mat;
62 | };
63 |
64 | #endif
65 |
--------------------------------------------------------------------------------
/framebuffer/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME framebuffer)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 |
26 | foreach(glsl_file ${GLSL_FILES})
27 | configure_file(${glsl_file} . COPYONLY)
28 | endforeach(glsl_file)
29 |
30 | #configure_file(${GLSL_FILES} . COPYONLY)
31 |
32 |
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
34 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
35 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
36 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
37 |
--------------------------------------------------------------------------------
/framebuffer/README.md:
--------------------------------------------------------------------------------
1 | # Framebuffer
2 |
3 |  
4 | 
5 |
6 | Instead of drawing the scene directly on the opengl viewport, we can draw it on a framebuffer, which can be used as
7 | a texture, to be drawn on a quad that takes the whole view port. This has a few advantages.
8 |
9 | Multisampling (anti aliasing) can be done, by drawing on multiple sample per pixel and then averaging them.
10 |
11 | Effect can be done on the rendered image itself. In this example, gaussian blur is implemented by convoluting the pixels with a gaussian matrix.
12 | Another implemented effect is an edge detection using a sobel operator.
13 |
14 | These effects take place in the pixel shader of the "screen quad" containing the framebuffer as a texture, so they are really optimized for parallel computation.
15 |
16 | These effects are all done in post processing, that is after the scene is rendered.
17 |
18 | # Controls
19 |
20 | - WASD: moves the camera
21 | - IJKL: change camera view direction
22 | - 0: no effects
23 | - 1: inverted colours
24 | - 2: small gaussian blur
25 | - 3: medium gaussian blur
26 | - 4: big gaussian blur
27 | - 5: edge detection (sobel convolution)
28 | - 6: broken glass
29 |
--------------------------------------------------------------------------------
/framebuffer/glsl/cube_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in float red;
4 | in float green;
5 | in float blue;
6 | out vec3 color;
7 |
8 | const vec3 COLOR[6] = vec3[](
9 | vec3(0.0, 0.0, 1.0),
10 | vec3(0.0, 1.0, 0.0),
11 | vec3(0.0, 1.0, 1.0),
12 | vec3(1.0, 0.0, 0.0),
13 | vec3(1.0, 0.0, 1.0),
14 | vec3(1.0, 1.0, 0.0));
15 |
16 | void main(){
17 | color = COLOR[gl_PrimitiveID / 2];
18 | }
19 |
--------------------------------------------------------------------------------
/framebuffer/glsl/cube_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 |
8 | out float red;
9 | out float green;
10 | out float blue;
11 |
12 | void main(){
13 | gl_Position = projection*view*model*vec4(position, 1.0);
14 | red = green = blue = 0.0;
15 |
16 | if(gl_VertexID == 0){
17 | red = 1.0;
18 | }
19 | else if(gl_VertexID == 1){
20 | green = 1.0;
21 | }
22 | else if(gl_VertexID == 2){
23 | blue = 1.0;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/framebuffer/glsl/plane_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in float red;
4 | in float green;
5 | in float blue;
6 | out vec3 color;
7 |
8 | void main(){
9 | color = vec3(red, green, blue);
10 | }
11 |
--------------------------------------------------------------------------------
/framebuffer/glsl/plane_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 vpoint;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 |
8 | out float red;
9 | out float green;
10 | out float blue;
11 |
12 | void main(){
13 | gl_Position = projection*view*model*vec4(vpoint, 1.0);
14 | red = green = blue = 0.0;
15 |
16 | if(gl_VertexID == 0){
17 | red = 1.0;
18 | }
19 | else if(gl_VertexID == 1){
20 | green = 1.0;
21 | }
22 | else if(gl_VertexID == 2){
23 | blue = 1.0;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/framebuffer/glsl/quad_screen_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/grass/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME grass)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 |
26 | foreach(glsl_file ${GLSL_FILES})
27 | configure_file(${glsl_file} . COPYONLY)
28 | endforeach(glsl_file)
29 |
30 | #configure_file(${GLSL_FILES} . COPYONLY)
31 |
32 |
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
34 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
35 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
36 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
37 |
--------------------------------------------------------------------------------
/grass/README.md:
--------------------------------------------------------------------------------
1 | # Grass
2 |
3 | 
4 |
5 | The classical approach to display grass is to use the billboard approach, where two planes of partially transparent textures are
6 | displayed. This has the advantage to have a detailled image of grass (depending on the texture). But is pretty rigid.
7 |
8 | In this examples, individual blades of grass are displayed, the advantage to display grass blade by blade is that they can move
9 | more freely. Here a perlin noise is used to simulate wind.
10 |
11 | Two approaches are used to display a huge quantity of grass, either instanced drawing or generate the grass in the geometry shader.
12 | In both cases, the model matrices are generated in cpu and stored in a huge buffer. In the instanced drawing case, the same blade is drawn
13 | multiple time with a single draw call. For each drawing instance, a different model matrix from the buffer will be used to position the blade.
14 |
15 | In the geometry shader case, a single call is also used, but the geometry is created inside the geometry shader.
16 |
17 | The goal of implementing both case was to compare the performance, but they have pretty similar performance on my computer.
18 |
19 | The advantage of both these methods is that there are very few cpu-gpu transfer, except the very large matrix buffer done at the initialisation.
20 | This means that a huge quantity of grass can be drawn.
21 | On my computer (Intel HD Graphics 620, with core i7-7500U), I get 60fps for 90k blades of grass and ~18fps for 360k blades of grass for both implementations.
22 |
23 | Each blade of grass uses its position in the world to get the wind value, from a perlin noise texture, the wind force is applied on each vertices,
24 | with stronger force on the higher vertices than the lower ones.
25 |
26 | # Controls
27 | - WASD: moves the camera
28 | - IJKL: change camera view direction
29 |
--------------------------------------------------------------------------------
/grass/_grass/grass_blades_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | uniform vec3 camera_position;
4 | uniform vec3 light_position;
5 |
6 | uniform sampler2D shadow_buffer_tex;
7 | uniform sampler2D tex_wind;
8 |
9 | out vec3 color;
10 |
11 | in vec2 frag_uv;
12 | in vec2 global_uv;
13 |
14 | void main(){
15 |
16 | //get random value from the noise texture
17 | float rand_val = mod((global_uv.x*global_uv.x)+(0.13-global_uv.x*global_uv.y), 0.01)/0.01;
18 |
19 | float dist_to_centre = pow(distance(frag_uv, vec2(0.5, 0.5)), 2);
20 |
21 | float dist_to_ground = clamp((1.0-frag_uv.y)*1, 0.0, 1.0);
22 |
23 | color = vec3( (0.1+rand_val/6.0+dist_to_centre)*dist_to_ground, (0.3+dist_to_centre)*dist_to_ground, (0.0+dist_to_centre)*dist_to_ground);
24 | }
25 |
--------------------------------------------------------------------------------
/grass/_grass/grass_blades_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec2 uv;
5 | uniform mat4 model;
6 | uniform mat4 view;
7 | uniform mat4 projection;
8 | uniform vec3 light_position;
9 |
10 | uniform sampler2D tex_wind; //wind speed texture
11 | uniform float min_pos;
12 | uniform float max_pos;
13 |
14 | uniform vec2 wind_dir;
15 | in mat4 model_mat;
16 |
17 | out vec3 frag_position;
18 | out vec3 frag_normal_transformed;
19 | out float frag_diffuse_light;
20 |
21 | out vec4 shadow_coord;
22 | out vec2 frag_uv;
23 | out vec2 global_uv;
24 |
25 | void main(){
26 |
27 | mat4 model = model_mat;
28 | vec3 new_pos = vec3(model*vec4(position, 1.0));
29 |
30 | float span_texture = max_pos-min_pos;
31 | vec2 relative_tex_pos = vec2(new_pos.x/100+0.5, new_pos.z/100+0.5);
32 | global_uv = relative_tex_pos;
33 | relative_tex_pos /= 4;
34 |
35 | float wind_x = texture(tex_wind, relative_tex_pos+wind_dir ).r;
36 | float wind_z = texture(tex_wind, relative_tex_pos+vec2(0.5, 0.5)+wind_dir ).r;
37 |
38 | //apply the wind, on the higher vertices, stronger wind
39 | if(gl_VertexID == 0){
40 | wind_x *= 3.0;
41 | wind_z *= 3.0;
42 | new_pos.x += wind_x;
43 | new_pos.y -= (abs(wind_x)+abs(wind_z))*0.5;
44 | new_pos.z += wind_z;
45 | }
46 | if(gl_VertexID == 1 || gl_VertexID == 2 ){
47 | wind_x *= 1.5;
48 | wind_z *= 1.5;
49 | new_pos.x += wind_x;
50 | new_pos.y -= (abs(wind_x)+abs(wind_z))*0.5;
51 | new_pos.z += wind_z;
52 | }
53 | if(gl_VertexID == 3 || gl_VertexID == 4 ){
54 | wind_x *= 0.5;
55 | wind_z *= 0.5;
56 | new_pos.x += wind_x;
57 | new_pos.y -= (abs(wind_x)+abs(wind_z))*0.5;
58 | new_pos.z += wind_z;
59 | }
60 |
61 | gl_Position = projection*view*vec4(new_pos, 1.0);
62 |
63 | vec3 model_pos = vec3(model*vec4(position, 1.0));
64 | frag_position = model_pos;
65 |
66 | frag_uv = uv;
67 | }
68 |
--------------------------------------------------------------------------------
/grass/_grass/grass_geom_gshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 |
4 | layout(points) in;
5 |
6 | layout(triangle_strip, max_vertices = 7) out;
7 |
8 | in vec2 geom_global_uv[];
9 | in mat4 geom_model_matrix[];
10 | in mat4 geom_view_matrix[];
11 | in mat4 geom_projection_matrix[];
12 |
13 | out vec2 frag_uv;
14 | out vec2 global_uv;
15 |
16 | uniform vec2 wind_dir;
17 | uniform sampler2D tex_wind; //wind speed texture
18 |
19 | uint nb_vertice = 7u;
20 |
21 | vec3 points[] = vec3[7u](vec3(0.0f, 0.0f, -2.0f), vec3(-1.0f, 0.0f, 0.0f), // 1
22 | vec3(1.0f, 0.0f, 0.0f), // 2
23 | vec3(-1.0f, 0.0f, 1.0f), // 3
24 | vec3(1.0f, 0.0, 1.0f), // 4
25 | vec3(-1.0f, 0.0, 2.0f), // 5
26 | vec3(1.0f, 0.0, 2.0f));
27 |
28 | vec2 vtexcoord[] = vec2[7u]( vec2(0.5f, 0.0f), // 0
29 | vec2(0.0f, 0.5f), // 1
30 | vec2(1.0f, 0.5f), // 2
31 | vec2(0.0f, 0.75f), // 3
32 | vec2(1.0f, 0.75f), // 4
33 | vec2(0.0f, 1.0f), // 5
34 | vec2(1.0f, 1.0f)); // 6
35 |
36 |
37 | uint vpoint_index[7] = uint[7](0u, 1u, 2u, 3u, 4u, 5u, 6u);
38 |
39 | vec3 calculate_vertex_wind(vec3 vertex, uint id){
40 |
41 | vec2 relative_tex_pos = vec2(vertex.x/100+0.5, vertex.z/100+0.5);
42 | relative_tex_pos /= 4;
43 |
44 | float wind_x = texture(tex_wind, relative_tex_pos+wind_dir ).r;
45 | float wind_z = texture(tex_wind, relative_tex_pos+vec2(0.5, 0.5)+wind_dir ).r;
46 |
47 | //apply the wind, on the higher vertices, stronger wind
48 | if(id == 0u){
49 | wind_x *= 3.0;
50 | wind_z *= 3.0;
51 | vertex.x += wind_x;
52 | vertex.y -= (abs(wind_x)+abs(wind_z))*0.5;
53 | vertex.z += wind_z;
54 | }
55 | if(id == 1u || id == 2u ){
56 | wind_x *= 1.5;
57 | wind_z *= 1.5;
58 | vertex.x += wind_x;
59 | vertex.y -= (abs(wind_x)+abs(wind_z))*0.5;
60 | vertex.z += wind_z;
61 | }
62 | if(id == 3u || id == 4u ){
63 | wind_x *= 0.5;
64 | wind_z *= 0.5;
65 | vertex.x += wind_x;
66 | vertex.y -= (abs(wind_x)+abs(wind_z))*0.5;
67 | vertex.z += wind_z;
68 | }
69 |
70 | return vertex;
71 | }
72 |
73 | void main()
74 | {
75 |
76 | for(uint i = 0u; i < nb_vertice; i++)
77 | {
78 | frag_uv = vtexcoord[vpoint_index[i]];
79 | global_uv = geom_global_uv[0];
80 | //apply model matrix on the point
81 | vec4 new_pos = geom_model_matrix[0]*(gl_in[0].gl_Position + vec4(points[vpoint_index[i]], 1.0) );
82 |
83 | //apply view and projection matrix
84 | gl_Position = geom_projection_matrix[0]*geom_view_matrix[0]*vec4(calculate_vertex_wind(vec3(new_pos), i), 1.0);
85 | EmitVertex();
86 | }
87 |
88 | EndPrimitive();
89 | }
90 |
--------------------------------------------------------------------------------
/grass/_grass/grass_geom_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | uniform mat4 view;
4 | uniform mat4 projection;
5 |
6 | in mat4 model_mat;
7 |
8 | out vec2 geom_global_uv;
9 | out mat4 geom_model_matrix;
10 | out mat4 geom_view_matrix;
11 | out mat4 geom_projection_matrix;
12 |
13 | void main(){
14 | //passthrough shader, vertex calculations will be done in the geometry shader
15 |
16 | vec3 new_pos = vec3(model_mat*vec4(vec3(0, 0, 0), 1.0));
17 | vec2 relative_tex_pos = vec2(new_pos.x/100+0.5, new_pos.z/100+0.5);
18 | geom_global_uv = relative_tex_pos;
19 | geom_model_matrix = model_mat;
20 | geom_view_matrix = view;
21 | geom_projection_matrix = projection;
22 | }
23 |
--------------------------------------------------------------------------------
/grass/_plane/plane_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | out vec3 color;
4 |
5 | //just draw a brown plane, there should be so much grass it shouldn't be seen
6 | void main(){
7 | color = vec3(0.3, 0.14, 0.07);
8 | }
9 |
--------------------------------------------------------------------------------
/grass/_plane/plane_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 | uniform vec3 light_position;
8 |
9 | uniform mat4 shadow_matrix; //bias*P*V
10 |
11 | in vec3 surface_normal;
12 |
13 | out vec3 frag_position;
14 | out vec3 frag_normal_transformed;
15 |
16 | void main(){
17 | gl_Position = projection*view*model*vec4(position, 1.0);
18 | }
19 |
--------------------------------------------------------------------------------
/grass/_quad_screen/quad_screen_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | uniform sampler2D tex;
3 | //uniform sampler2DMS tex;
4 | uniform float tex_width;
5 | uniform float tex_height;
6 | in vec2 uv;
7 | out vec3 color;
8 |
9 | void main() {
10 |
11 | color = texture(tex, uv).rgb;
12 | }
13 |
--------------------------------------------------------------------------------
/grass/_quad_screen/quad_screen_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/grass/texture_float.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | //texture class which contains floating values
8 | class Texture_float{
9 | public:
10 | Texture_float(){
11 | tex_data = NULL;
12 | }
13 |
14 | ~Texture_float(){
15 | if(tex_data != NULL){
16 | delete tex_data;
17 | }
18 | }
19 |
20 | //load image from disk
21 | bool load_image(const char *path){
22 | ilGenImages(1, &tex_id);
23 | ilBindImage(tex_id);
24 | ILboolean result = ilLoadImage(path);
25 | if(result == IL_FALSE){
26 | return false;
27 | }
28 |
29 | tex_width = ilGetInteger(IL_IMAGE_WIDTH);
30 | tex_height = ilGetInteger(IL_IMAGE_HEIGHT);
31 |
32 | tex_data = new float[tex_width*tex_height*3];
33 | ilCopyPixels(0, 0, 0, tex_width, tex_height, 1, IL_RGB, IL_FLOAT, tex_data);
34 |
35 | //unbind the image as the image data has been copyied
36 | ilBindImage(0);
37 | ilDeleteImage(tex_id);
38 |
39 | return true;
40 | }
41 |
42 | void set_data(const std::vector > &tex_data){
43 | this->tex_height = tex_data[0].size();
44 | this->tex_width = tex_data.size();
45 |
46 | this->tex_data = new float[tex_height*tex_width];
47 |
48 | for(unsigned int i = 0; i < tex_data.size(); i++){
49 | for(unsigned int j = 0; j < tex_data[0].size(); j++){
50 |
51 | this->tex_data[i*tex_width+j] = tex_data[i][j];
52 | }
53 | }
54 | }
55 |
56 | //return the data of the image in bytes
57 | float *get_tex_data() const {
58 | return tex_data;
59 | }
60 |
61 | int get_width() const{
62 | return tex_width;
63 | }
64 |
65 | int get_height() const{
66 | return tex_height;
67 | }
68 |
69 | protected:
70 | ILuint tex_id;
71 | unsigned int tex_width;
72 | unsigned int tex_height;
73 | float *tex_data;
74 | };
75 |
--------------------------------------------------------------------------------
/lod_terrain/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME lod_terrain)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 |
26 | foreach(glsl_file ${GLSL_FILES})
27 | configure_file(${glsl_file} . COPYONLY)
28 | endforeach(glsl_file)
29 |
30 | #configure_file(${GLSL_FILES} . COPYONLY)
31 |
32 |
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
34 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
35 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
36 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
37 |
--------------------------------------------------------------------------------
/lod_terrain/README.md:
--------------------------------------------------------------------------------
1 | # LOD Terrain
2 |
3 |  
4 |
5 | LOD (Level Of Detail) allow to have a huge procedural terrain without too many triangles, by having the polygons near
6 | the camera at high detail, and the far away ones with a lower level of details, this saves a high amount of triangls without
7 | sacrificing the visual quality.
8 |
9 | The terrain is subdivided into squares, that are ordered in a structure called a quad tree. The squares that are
10 | near the root will be bigger and coarser.
11 | As the camera moves, new squares will be added or removed from the tree.
12 |
13 | This is one of the most simple implementation of LOD, one of its biggest drawback is that
14 | the change of LOD happens instantly, it is as such very visible.
15 |
16 | Another problem of this implementation is that it is done in CPU. A lot of cpu ressources are
17 | used for the calculation of the LOD.
18 |
19 | # Controls
20 |
21 | - WASD: moves the camera
22 | - IJKL: change camera view direction
23 | - M/N: activate and deactivate fps/free camera (default: free)
24 | - B/V: activate/deactivate moving light (simulate VERY roughly sun) (default: activated)
25 | - C/X: activate/deactivate wireframe to see the lod in action (deflaut: deactivated)
26 |
--------------------------------------------------------------------------------
/lod_terrain/_terrain/terrain_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 frag_normal_transformed;
4 | in vec3 frag_position;
5 |
6 | uniform vec3 camera_position;
7 | uniform vec3 light_position;
8 |
9 | uniform bool activate_colour;
10 | uniform bool activate_heightmap;
11 | uniform bool activate_wireframe;
12 |
13 | out vec3 color;
14 |
15 | in float frag_nontransfheight;
16 |
17 | const vec3 COLOR[3] = vec3[](
18 | vec3(0.0, 0.3, 1.0),
19 | vec3(0.0, 0.7, 0.0),
20 | vec3(0.8, 0.8, 0.8));
21 |
22 | const float ambiant_light = 0.3;
23 |
24 | void main(){
25 | vec3 light_dir = normalize(light_position-frag_position);
26 | float diffuse_light = 0.0;
27 | // float spec_light = 0.0;
28 |
29 | vec3 reflexion = 2*frag_normal_transformed*dot(frag_normal_transformed, light_dir)-light_dir;
30 | reflexion = normalize(reflexion);
31 | vec3 view_dir = normalize(camera_position-frag_position);
32 |
33 | // spec_light = pow(max(dot(reflexion, view_dir), 0.0), 64);
34 | // spec_light = clamp(spec_light, 0.0, 1.0);
35 |
36 | diffuse_light = dot(frag_normal_transformed, light_dir);
37 | diffuse_light = clamp(diffuse_light, 0.0, 1.0);
38 |
39 | float lum = 0.8*diffuse_light+/*spec_light+*/ambiant_light;
40 | clamp(lum, 0.0, 1.0);
41 |
42 | float height = frag_nontransfheight/2.0+0.5;
43 | vec3 pixel_colour = vec3(0.0);
44 |
45 | if(height < 0.5){
46 | pixel_colour = (1.0-height*2)*COLOR[0]+height*2*COLOR[1];
47 | }else{
48 | pixel_colour = (1.0-(height-0.5)*2)*COLOR[1]+(height-0.5)*2*COLOR[2];
49 | }
50 |
51 | if(!activate_colour){
52 | pixel_colour = vec3(1.0);
53 | }
54 |
55 | else{
56 | color = pixel_colour*lum;
57 | }
58 |
59 | //we want black lines if wireframe is activated
60 | if (activate_wireframe){
61 | color = vec3(0.0);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/lod_terrain/_terrain/terrain_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec3 vertex_normal;
5 | uniform vec3 light_position;
6 | uniform vec3 camera_position;
7 |
8 | uniform mat4 model;
9 | uniform mat4 view;
10 | uniform mat4 projection;
11 |
12 | out vec3 frag_position;
13 | out vec3 frag_surface_normal_color;
14 | out vec3 frag_normal_transformed;
15 |
16 | //to draw the height, without having it modified by the model matrix
17 | out float frag_nontransfheight;
18 |
19 | void main(){
20 | gl_Position = projection*view*model*vec4(position, 1.0);
21 |
22 | //matrix to adapts the normals to the application of matrix on the terrain
23 | //otherwise the terrain is bad
24 | mat3 normalMat = mat3(model);
25 | normalMat = transpose(inverse(normalMat));
26 |
27 | vec3 normal_transformed = vec3(0.0);
28 | normal_transformed = normalize(normalMat*vertex_normal);
29 |
30 |
31 | ////////////////////
32 | //per vertex lighting
33 | /////////////////
34 | // vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
35 | // vec3 view_dir = normalize(camera_position-vec3(model*vec4(position, 1.0)));
36 | //
37 | // float diffuse_light = 0.0;
38 | // float spec_light = 0.0;
39 | // diffuse_light = dot(normal_transformed, light_dir);
40 | //
41 | // vec3 reflexion = 2*normal_transformed*dot(normal_transformed, light_dir)-light_dir;
42 | // reflexion = clamp(reflexion, 0.0, 1.0);
43 | // spec_light = pow(dot(reflexion, view_dir), 64);
44 | // spec_light = clamp(spec_light, 0.0, 1.0);
45 | //
46 | // float lum = 0.8*diffuse_light+0.8*spec_light;
47 | // lum = clamp(lum, 0.0, 1.0);
48 |
49 | frag_normal_transformed = normal_transformed;
50 | frag_position = vec3(model*vec4(position, 1.0));
51 |
52 | frag_nontransfheight = position[1];
53 | }
54 |
--------------------------------------------------------------------------------
/lod_terrain/_terrain_quad/qtree_test.hpp:
--------------------------------------------------------------------------------
1 | #ifndef QTREE_TEST_H
2 | #define QTREE_TEST_H
3 |
4 | #include "qtree.h"
5 | #include "noise_generator.hpp"
6 |
7 | #define QTREE_TEST_PID_DEBUG 0
8 |
9 | //tests that the qtree is really working
10 |
11 | void qtree_test_base(){
12 | Noise_generator noise_gen;
13 | Quad_tree_node root(NULL, 2, 5, 0);
14 | root.set_as_root(noise_gen, QTREE_TEST_PID_DEBUG);
15 | root.break_qtree();
16 | if(!root.is_tail && root.level == 0 && root.children[0]->is_tail && root.children[0]->level == 1){
17 | // printf("TEST PASSED\n");
18 | root.delete_root();
19 | }
20 | else{
21 | printf("TEST NOT PASSED");
22 | root.delete_root();
23 | }
24 | }
25 |
26 | void qtree_test_neighbour_simple(){
27 | Noise_generator noise_gen;
28 | Quad_tree_node root(NULL, 2, 5, 0);
29 | root.set_as_root(noise_gen, QTREE_TEST_PID_DEBUG);
30 | root.break_qtree();
31 |
32 | Quad_tree_node *north_neighbour = root.children[2]->find_neighbour_north();
33 | Quad_tree_node *south_neighbour = root.children[1]->find_neighbour_south();
34 |
35 | if(north_neighbour == root.children[0] && south_neighbour == root.children[3]){
36 | // printf("TEST PASSED\n");
37 | root.delete_root();
38 | }
39 | else{
40 | printf("TEST NOT PASSED\n");
41 | root.delete_root();
42 | }
43 | }
44 |
45 |
46 | //12
47 | //21
48 | //north neighbour of 2 should be the 1 above
49 | void qtree_test_neighbour_of_child(){
50 | Noise_generator noise_gen;
51 | Quad_tree_node root(NULL, 2, 5, 0);
52 | root.set_as_root(noise_gen, QTREE_TEST_PID_DEBUG);
53 | root.break_qtree();
54 | root.children[1]->break_qtree();
55 | root.children[2]->break_qtree();
56 |
57 | Quad_tree_node *north_neighbour_0 = root.children[2]->children[0]->find_neighbour_north();
58 | Quad_tree_node *north_neighbour_1 = root.children[2]->children[1]->find_neighbour_north();
59 |
60 | Quad_tree_node *south_neighbour_0 = root.children[1]->children[2]->find_neighbour_south();
61 | Quad_tree_node *south_neighbour_1 = root.children[1]->children[3]->find_neighbour_south();
62 |
63 | Quad_tree_node *south_neighbour_null = root.children[2]->children[2]->find_neighbour_south();
64 |
65 | Quad_tree_node *south_neighbour_sub = root.children[1]->children[1]->find_neighbour_south();
66 |
67 | if(north_neighbour_0 == root.children[0] && north_neighbour_1 == root.children[0]
68 | && south_neighbour_0 == root.children[3] && south_neighbour_1 == root.children[3]
69 | && south_neighbour_null == NULL
70 | && south_neighbour_sub == root.children[1]->children[3]){
71 | // printf("TEST_PASSED\n");
72 | root.delete_root();
73 | }
74 | else{
75 | printf("TEST NOT PASSED\n");
76 | root.delete_root();
77 | }
78 | }
79 |
80 | void qtree_test_neighbour_different_parents(){
81 | Noise_generator noise_gen;
82 | Quad_tree_node root(NULL, 2, 5, 0);
83 | root.set_as_root(noise_gen, QTREE_TEST_PID_DEBUG);
84 | root.break_qtree();
85 | root.children[0]->break_qtree();
86 | root.children[1]->break_qtree();
87 | root.children[2]->break_qtree();
88 | root.children[3]->break_qtree();
89 |
90 | Quad_tree_node *north_neighbour = root.children[2]->children[0]->find_neighbour_north();
91 | Quad_tree_node *south_neighbour = root.children[1]->children[3]->find_neighbour_south();
92 |
93 | if(north_neighbour == root.children[0]->children[2]
94 | && south_neighbour == root.children[3]->children[1]){
95 |
96 | // printf("TEST PASSED\n");
97 | root.delete_root();
98 | }
99 | else{
100 | printf("TEST NOT PASSED\n");
101 | root.delete_root();
102 | }
103 |
104 | }
105 |
106 |
107 | #endif
108 |
--------------------------------------------------------------------------------
/lod_terrain/camera_fps.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "camera.h"
7 | #include "_terrain_quad/qterrain.h"
8 |
9 | class Camera_fps : public Camera_free{
10 | public:
11 |
12 | void init(float height, QTerrain *terrain){
13 | set_height(height);
14 | set_terrain(terrain);
15 |
16 | this->update_pos();
17 | }
18 |
19 | void set_height(float height){
20 | this->height = height;
21 | }
22 |
23 | void set_terrain(QTerrain *terrain){
24 | this->terrain = terrain;
25 | }
26 |
27 | virtual void input_handling(char key, float time_delta){
28 |
29 | glm::vec3 direction;
30 | glm::vec3 speed_factor = glm::vec3(this->speed)*time_delta;
31 |
32 | direction = center - eye;
33 | direction = glm::vec3(direction[0], 0.0f, direction[2]);
34 | direction = normalize(direction);
35 |
36 | glm::vec3 left_dir = normalize(cross(up, direction));
37 | glm::vec3 right_dir = normalize(cross(direction, up));
38 |
39 | if(key == 'W' || key == 'A' || key == 'S' || key == 'D'){
40 | float height_before = eye[1];
41 |
42 | switch(key){
43 | case 'W':
44 | eye = eye + speed_factor*direction;
45 | center = center + speed_factor*direction;
46 | break;
47 | case 'S':
48 | eye = eye - speed_factor*direction;
49 | center = center - speed_factor*direction;
50 | break;
51 | case 'A':
52 | eye = eye + speed_factor*left_dir;
53 | center = center + speed_factor*left_dir;
54 | break;
55 | case 'D':
56 | eye = eye + speed_factor*right_dir;
57 | center = center + speed_factor*right_dir;
58 | }
59 |
60 | float height_diff = terrain->get_height(eye[0], eye[2]) - height_before;
61 |
62 | eye[1] += height_diff+height;
63 | center[1] += height_diff+height;
64 | }
65 | else {
66 | Camera_free::input_handling(key, time_delta);
67 | }
68 |
69 | }
70 |
71 | protected:
72 | QTerrain *terrain; //collision
73 | float height;
74 | };
75 |
--------------------------------------------------------------------------------
/lod_terrain/glsl/quad_screen_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/mouse_control/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME mouse_control)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 | #file(COPY ${GLSL_FILES} DESTINATION .)
26 | #configure_file copies files every "make"
27 | foreach(glsl_file ${GLSL_FILES})
28 | configure_file(${glsl_file} . COPYONLY)
29 | endforeach(glsl_file)
30 |
31 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
32 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
34 |
--------------------------------------------------------------------------------
/mouse_control/glsl/cube_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in float red;
4 | in float green;
5 | in float blue;
6 | out vec3 color;
7 |
8 | const vec3 COLOR[6] = vec3[](
9 | vec3(0.0, 0.0, 1.0),
10 | vec3(0.0, 1.0, 0.0),
11 | vec3(0.0, 1.0, 1.0),
12 | vec3(1.0, 0.0, 0.0),
13 | vec3(1.0, 0.0, 1.0),
14 | vec3(1.0, 1.0, 0.0));
15 |
16 | void main(){
17 | color = COLOR[gl_PrimitiveID / 2];
18 | }
19 |
--------------------------------------------------------------------------------
/mouse_control/glsl/cube_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 |
8 | out float red;
9 | out float green;
10 | out float blue;
11 |
12 | void main(){
13 | gl_Position = projection*view*model*vec4(position, 1.0);
14 | // gl_Position = vec4(position, 1.0);
15 | red = green = blue = 0.0;
16 |
17 | if(gl_VertexID == 0){
18 | red = 1.0;
19 | }
20 | else if(gl_VertexID == 1){
21 | green = 1.0;
22 | }
23 | else if(gl_VertexID == 2){
24 | blue = 1.0;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/mouse_control/glsl/plane_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in float red;
4 | in float green;
5 | in float blue;
6 | out vec3 color;
7 |
8 | void main(){
9 | color = vec3(red, green, blue);
10 | }
11 |
--------------------------------------------------------------------------------
/mouse_control/glsl/plane_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 vpoint;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 |
8 | out float red;
9 | out float green;
10 | out float blue;
11 |
12 | void main(){
13 | gl_Position = projection*view*model*vec4(vpoint, 1.0);
14 | // gl_Position = model*vec4(vpoint, 1.0);
15 | // gl_Position = vec4(vpoint, 1.0);
16 | red = green = blue = 0.0;
17 |
18 | if(gl_VertexID == 0){
19 | red = 1.0;
20 | }
21 | else if(gl_VertexID == 1){
22 | green = 1.0;
23 | }
24 | else if(gl_VertexID == 2){
25 | blue = 1.0;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/particles/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME particles)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 |
26 | foreach(glsl_file ${GLSL_FILES})
27 | configure_file(${glsl_file} . COPYONLY)
28 | endforeach(glsl_file)
29 |
30 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
31 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
32 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
34 |
--------------------------------------------------------------------------------
/particles/README.md:
--------------------------------------------------------------------------------
1 | # Particles
2 |
3 | This is a fairly simple implementation of a particle system done in opengl.
4 |
5 | The particles are generated and updated on the cpu, and drawn with instanced draw calls. The shape of the particle is defined one time and buffers for the positions and age of particles are updated and sent to the gpu every draw cycle.
6 |
7 | The particles contain their age, time to live, 3d position, initial velocity, and an additional 3d wind function can be applied on the particle.
8 |
9 | The obvious drawback of this system is that it will have lots of cpu-gpu communication.
10 |
11 | On a (Intel HD Graphics 620 Intel core i7-7500U 8GB Ram) computer, it can handle ~100K particles at a good framerate as long as particles are small enough, otherwise the fillrate of the gpu wont be enough. From 200K and up, the data transfer kills the framerate.
12 |
13 | 
14 |
15 | # Controls
16 | - WASD: moves the camera
17 | - IJKL: change camera view direction
18 |
--------------------------------------------------------------------------------
/particles/_particles_manager/fire_particles_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | uniform mat4 model;
4 | uniform mat4 view;
5 | uniform mat4 projection;
6 |
7 | uniform vec3 light_position;
8 |
9 | in vec2 frag_uv;
10 | in float frag_life;
11 | in float frag_age;
12 |
13 | out vec4 color;
14 |
15 | vec3 yellow = vec3(1, 1, 0);
16 | vec3 red = vec3(1, 0, 0);
17 | vec3 gray = vec3(0.5, 0.5, 0.5);
18 |
19 | void main(){
20 |
21 | vec2 transf_frag_uv = (frag_uv-0.5)*2;
22 |
23 | if(frag_life == 0){
24 | discard;
25 | }
26 |
27 | //round particle
28 | if(dot(transf_frag_uv, transf_frag_uv) > 1){
29 | discard;
30 | }
31 |
32 | if(frag_age < 0.5) //make a bright yellow when particle is young
33 | {
34 | color = vec4(mix(yellow, red, frag_age/0.5), 1);
35 | }
36 | else{ //then progressivly get gray
37 | float fraction = (frag_age-0.5)/3;
38 | fraction = clamp(fraction, 0, 1);
39 | float transparency = 1-(frag_age-2)/4;
40 | transparency = clamp(transparency, 0, 1);
41 | color = vec4(mix(red, gray, fraction), transparency);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/particles/_particles_manager/fire_particles_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec2 uv;
5 | in vec3 pos_point;
6 | in vec2 life_age;
7 | uniform mat4 model;
8 | uniform mat4 view;
9 | uniform mat4 projection;
10 | uniform vec3 light_position;
11 | uniform vec4 clip_coord;
12 |
13 | out vec2 frag_uv;
14 | out float frag_life;
15 | out float frag_age;
16 |
17 | void main(){
18 |
19 | //from http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/billboards/
20 | //to have billboards sprites
21 | vec3 CameraRight_worldspace = vec3(view[0][0], view[1][0], view[2][0]);
22 | vec3 CameraUp_worldspace = vec3(view[0][1], view[1][1], view[2][1]);
23 |
24 | float size = 1.0;
25 |
26 | vec3 vertexPosition_worldspace =
27 | pos_point
28 | + CameraRight_worldspace * position.x * size
29 | + CameraUp_worldspace * position.z * size;
30 |
31 | gl_Position = projection*view*vec4(vertexPosition_worldspace, 1.0);
32 | frag_uv = uv;
33 | frag_life = life_age[0];
34 | frag_age = life_age[1];
35 | }
36 |
--------------------------------------------------------------------------------
/particles/_particles_manager/snow_particles_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | uniform mat4 model;
4 | uniform mat4 view;
5 | uniform mat4 projection;
6 |
7 | uniform vec3 light_position;
8 |
9 | in vec2 frag_uv;
10 | in float frag_life;
11 | in float frag_age;
12 |
13 | out vec4 color;
14 |
15 | void main(){
16 |
17 | vec2 transf_frag_uv = (frag_uv-0.5)*2;
18 |
19 | if(frag_life == 0){ //don't draw this particle if it is dead
20 | discard;
21 | }
22 |
23 | //round particle
24 | if(dot(transf_frag_uv, transf_frag_uv) > 1){
25 | discard;
26 | }
27 |
28 | //white snow
29 | color = vec4(0.85, 0.85, 0.90, 0.5);
30 | }
31 |
--------------------------------------------------------------------------------
/particles/_particles_manager/snow_particles_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec2 uv;
5 | in vec3 pos_point;
6 | in vec2 life_age;
7 | uniform mat4 model;
8 | uniform mat4 view;
9 | uniform mat4 projection;
10 | uniform vec3 light_position;
11 | uniform vec4 clip_coord;
12 |
13 | out vec2 frag_uv;
14 | out float frag_life;
15 | out float frag_age;
16 |
17 | void main(){
18 |
19 | //from http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/billboards/
20 | //to have billboards sprites
21 | vec3 CameraRight_worldspace = vec3(view[0][0], view[1][0], view[2][0]);
22 | vec3 CameraUp_worldspace = vec3(view[0][1], view[1][1], view[2][1]);
23 |
24 | float size = 0.25;
25 |
26 | vec3 vertexPosition_worldspace =
27 | pos_point
28 | + CameraRight_worldspace * position.x * size
29 | + CameraUp_worldspace * position.z * size;
30 |
31 | gl_Position = projection*view*vec4(vertexPosition_worldspace, 1.0);
32 | frag_uv = uv;
33 | frag_life = life_age[0];
34 | frag_age = life_age[1];
35 | }
36 |
--------------------------------------------------------------------------------
/particles/glsl/cube_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 frag_surface_normal_color;
4 |
5 | uniform sampler2D shadow_buffer_tex;
6 |
7 | uniform mat4 model;
8 | uniform mat4 view;
9 | uniform mat4 projection;
10 |
11 | uniform vec3 light_position;
12 |
13 | in float red;
14 | in float green;
15 | in float blue;
16 | out vec4 color;
17 |
18 | in vec3 frag_position;
19 | in vec3 frag_normal;
20 | in vec4 shadow_coord;
21 |
22 | uniform uint window_width;
23 | uniform uint window_height;
24 | uniform uint shadow_mapping_effect;
25 |
26 | uniform vec3 shape_color;
27 |
28 | uniform uint shadow_buffer_tex_size;
29 |
30 | void main(){
31 |
32 | vec3 light_dir = normalize(light_position-frag_position);
33 | float diffuse_light = dot(frag_normal, light_dir);
34 |
35 | color = vec4(diffuse_light*shape_color, 1.0);
36 | }
37 |
--------------------------------------------------------------------------------
/particles/glsl/cube_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 | uniform vec3 light_position;
8 | uniform vec4 clip_coord;
9 | in vec3 surface_normal;
10 |
11 | uniform mat4 shadow_matrix; //bias*P*V
12 |
13 | out vec3 frag_surface_normal_color;
14 | out vec3 frag_position;
15 | out vec3 frag_normal;
16 | out float red;
17 | out float green;
18 | out float blue;
19 |
20 | out vec4 shadow_coord;
21 | out float gl_ClipDistance[1];
22 |
23 | void main(){
24 | gl_Position = projection*view*model*vec4(position, 1.0);
25 | //dont display anything under water, negative means outside clip plane
26 | gl_ClipDistance[0] = dot(model*vec4(position, 1.0), clip_coord);
27 | frag_position = vec3(model*vec4(position, 1.0));
28 |
29 | mat3 normalMat = mat3(model);
30 | normalMat = transpose(inverse(normalMat));
31 |
32 | vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
33 |
34 | vec3 normal_transformed = vec3(0.0);
35 | normal_transformed = normalize(normalMat*surface_normal);
36 |
37 | float diffuse_light = 0.0;
38 | diffuse_light = dot(normal_transformed, light_dir);
39 |
40 | float lum = 1.0*diffuse_light;
41 | lum = clamp(lum, 0.0, 1.0);
42 | frag_surface_normal_color = vec3(lum, lum, lum);
43 |
44 | shadow_coord = shadow_matrix * model*vec4(position, 1.0);
45 | frag_normal = surface_normal;
46 | }
47 |
--------------------------------------------------------------------------------
/particles/glsl/quad_screen_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/rotating_cube/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME rotating_cube)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 | #file(COPY ${GLSL_FILES} DESTINATION .)
26 | #configure_file copies files every "make"
27 | foreach(glsl_file ${GLSL_FILES})
28 | configure_file(${glsl_file} . COPYONLY)
29 | endforeach(glsl_file)
30 |
31 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
32 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
34 |
--------------------------------------------------------------------------------
/rotating_cube/glsl/cube_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in float red;
4 | in float green;
5 | in float blue;
6 | out vec3 color;
7 |
8 | const vec3 COLOR[6] = vec3[](
9 | vec3(0.0, 0.0, 1.0),
10 | vec3(0.0, 1.0, 0.0),
11 | vec3(0.0, 1.0, 1.0),
12 | vec3(1.0, 0.0, 0.0),
13 | vec3(1.0, 0.0, 1.0),
14 | vec3(1.0, 1.0, 0.0));
15 |
16 | void main(){
17 | color = COLOR[gl_PrimitiveID / 2];
18 | }
19 |
--------------------------------------------------------------------------------
/rotating_cube/glsl/cube_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 |
8 | out float red;
9 | out float green;
10 | out float blue;
11 |
12 | void main(){
13 | gl_Position = projection*view*model*vec4(position, 1.0);
14 | // gl_Position = vec4(position, 1.0);
15 | red = green = blue = 0.0;
16 |
17 | if(gl_VertexID == 0){
18 | red = 1.0;
19 | }
20 | else if(gl_VertexID == 1){
21 | green = 1.0;
22 | }
23 | else if(gl_VertexID == 2){
24 | blue = 1.0;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/rotating_cube/glsl/plane_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in float red;
4 | in float green;
5 | in float blue;
6 | out vec3 color;
7 |
8 | void main(){
9 | color = vec3(red, green, blue);
10 | }
11 |
--------------------------------------------------------------------------------
/rotating_cube/glsl/plane_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 vpoint;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 |
8 | out float red;
9 | out float green;
10 | out float blue;
11 |
12 | void main(){
13 | gl_Position = projection*view*model*vec4(vpoint, 1.0);
14 | // gl_Position = model*vec4(vpoint, 1.0);
15 | // gl_Position = vec4(vpoint, 1.0);
16 | red = green = blue = 0.0;
17 |
18 | if(gl_VertexID == 0){
19 | red = 1.0;
20 | }
21 | else if(gl_VertexID == 1){
22 | green = 1.0;
23 | }
24 | else if(gl_VertexID == 2){
25 | blue = 1.0;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/rotating_cube/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #define GL_GLEXT_PROTOTYPES 1
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include //perspective
13 |
14 | #include "camera.h"
15 | #include "shader_helper.h"
16 | #include "_plane/plane.h"
17 | #include "_cube/cube.h"
18 |
19 | void init();
20 | void display();
21 | void cleanup();
22 | GLuint load_shader(char *path, GLenum shader_type);
23 |
24 | Camera cam;
25 | Plane plane;
26 | Cube cube;
27 | glm::mat4x4 projection_mat;
28 | glm::mat4x4 cube_model_mat;
29 |
30 | const int win_width = 1280;
31 | const int win_height = 720;
32 |
33 | int main(){
34 | if( !glfwInit() ){
35 | std::cout << "Error to initialize GLFW" << std::endl;
36 | return -1;
37 | }
38 |
39 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
40 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
41 | glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
42 |
43 | GLFWwindow* window = glfwCreateWindow(win_width, win_height, "rotating_cube", NULL, NULL);
44 |
45 | if( !window ){
46 | std::cout << "failed to open window" << std::endl;
47 | return -1;
48 | }
49 |
50 | glfwMakeContextCurrent(window);
51 |
52 | glewExperimental = GL_TRUE;
53 | if(glewInit() != GLEW_NO_ERROR){
54 | std::cout << "glew error\n";
55 | return -1;
56 | }
57 |
58 | init();
59 |
60 | while(glfwGetKey(window, GLFW_KEY_ESCAPE)!=GLFW_PRESS && !glfwWindowShouldClose(window)){
61 | display();
62 | glfwSwapBuffers(window);
63 | glfwPollEvents();
64 | }
65 |
66 | cleanup();
67 |
68 | return 0;
69 | }
70 |
71 | void init(){
72 | glClearColor(1.0, 1.0, 1.0, 1.0);
73 |
74 | glEnable(GL_DEPTH_TEST);
75 | glDepthFunc(GL_LESS);
76 |
77 | glViewport(0,0,win_width,win_height);
78 | projection_mat = glm::perspective(3.1415f/2.0f, (float)win_width/(float)win_height, 0.1f, 10.0f);
79 |
80 | GLuint plane_pid = load_shaders("plane_vshader.glsl", "plane_fshader.glsl");
81 | plane.init(plane_pid);
82 | GLuint cube_pid = load_shaders("cube_vshader.glsl", "cube_fshader.glsl");
83 | cube.init(cube_pid);
84 |
85 | //transformations for the cube : put it on the plane which is at default at height 0
86 | cube_model_mat = glm::mat4(1.0); //identity
87 | cube_model_mat = glm::translate(cube_model_mat, glm::vec3(0.0, 0.5, 0.0));
88 | cube_model_mat = glm::scale(cube_model_mat, glm::vec3(0.5, 0.5, 0.5));
89 |
90 | //fixed cam
91 | cam.lookAt(1.5f, 1.5f, 1.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
92 | }
93 |
94 | void display(){
95 | glClear(GL_COLOR_BUFFER_BIT);
96 | glClear(GL_DEPTH_BUFFER_BIT);
97 | plane.draw(glm::mat4(1.0), cam.getMatrix(), projection_mat);
98 |
99 | float angle = glfwGetTime()*0.5; //glfwGetTime returns time in seconds
100 |
101 | //rotation matrix, rotate around top vector (0, 1, 0)
102 | glm::mat4 cube_model_mat_rot = glm::rotate(cube_model_mat, angle, glm::vec3(0.0, 1.0, 0.0));
103 | cube.draw(cube_model_mat_rot, cam.getMatrix(), projection_mat);
104 | }
105 |
106 | void cleanup(){
107 | }
108 |
--------------------------------------------------------------------------------
/screenshots/ambient_occlusion.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/ambient_occlusion.gif
--------------------------------------------------------------------------------
/screenshots/atmosphere_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/atmosphere_1.png
--------------------------------------------------------------------------------
/screenshots/atmosphere_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/atmosphere_2.png
--------------------------------------------------------------------------------
/screenshots/bumpmapping_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/bumpmapping_1.png
--------------------------------------------------------------------------------
/screenshots/bumpmapping_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/bumpmapping_2.png
--------------------------------------------------------------------------------
/screenshots/clouds_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/clouds_1.png
--------------------------------------------------------------------------------
/screenshots/clouds_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/clouds_2.png
--------------------------------------------------------------------------------
/screenshots/framebuffer_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/framebuffer_1.png
--------------------------------------------------------------------------------
/screenshots/framebuffer_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/framebuffer_2.png
--------------------------------------------------------------------------------
/screenshots/framebuffer_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/framebuffer_3.png
--------------------------------------------------------------------------------
/screenshots/grass_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/grass_1.png
--------------------------------------------------------------------------------
/screenshots/lod_terrain_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/lod_terrain_1.png
--------------------------------------------------------------------------------
/screenshots/lod_terrain_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/lod_terrain_2.png
--------------------------------------------------------------------------------
/screenshots/particles_example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/particles_example.png
--------------------------------------------------------------------------------
/screenshots/rotating_cube.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/rotating_cube.png
--------------------------------------------------------------------------------
/screenshots/shadow_mapping_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/shadow_mapping_1.png
--------------------------------------------------------------------------------
/screenshots/shadow_mapping_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/shadow_mapping_2.png
--------------------------------------------------------------------------------
/screenshots/sky_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/sky_1.png
--------------------------------------------------------------------------------
/screenshots/sky_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/sky_2.png
--------------------------------------------------------------------------------
/screenshots/sphere_light_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/sphere_light_1.png
--------------------------------------------------------------------------------
/screenshots/sphere_light_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/sphere_light_2.png
--------------------------------------------------------------------------------
/screenshots/terrain_camera_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/terrain_camera_1.png
--------------------------------------------------------------------------------
/screenshots/terrain_camera_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/terrain_camera_2.png
--------------------------------------------------------------------------------
/screenshots/tessellation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/tessellation.png
--------------------------------------------------------------------------------
/screenshots/texfiltering_anisotropic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/texfiltering_anisotropic.png
--------------------------------------------------------------------------------
/screenshots/texfiltering_bilinear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/texfiltering_bilinear.png
--------------------------------------------------------------------------------
/screenshots/texfiltering_nearest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/texfiltering_nearest.png
--------------------------------------------------------------------------------
/screenshots/texfiltering_trilinear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/texfiltering_trilinear.png
--------------------------------------------------------------------------------
/screenshots/texture_plane_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/texture_plane_1.png
--------------------------------------------------------------------------------
/screenshots/texture_plane_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/texture_plane_2.png
--------------------------------------------------------------------------------
/screenshots/tree_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/tree_1.png
--------------------------------------------------------------------------------
/screenshots/tree_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/tree_2.png
--------------------------------------------------------------------------------
/screenshots/tree_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/tree_3.png
--------------------------------------------------------------------------------
/screenshots/tree_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/tree_4.png
--------------------------------------------------------------------------------
/screenshots/triangle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/triangle.png
--------------------------------------------------------------------------------
/screenshots/volumetric_light_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/volumetric_light_1.png
--------------------------------------------------------------------------------
/screenshots/volumetric_light_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/volumetric_light_2.png
--------------------------------------------------------------------------------
/screenshots/water_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/water_1.png
--------------------------------------------------------------------------------
/screenshots/water_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/screenshots/water_2.png
--------------------------------------------------------------------------------
/shadow_mapping/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME shadow_mapping)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 |
26 | foreach(glsl_file ${GLSL_FILES})
27 | configure_file(${glsl_file} . COPYONLY)
28 | endforeach(glsl_file)
29 |
30 | #configure_file(${GLSL_FILES} . COPYONLY)
31 |
32 |
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
34 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
35 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
36 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
37 |
--------------------------------------------------------------------------------
/shadow_mapping/README.md:
--------------------------------------------------------------------------------
1 | # Shadow mapping
2 |
3 |  
4 |
5 | This is a simple and straightforward implementation of shadow mapping in opengl
6 |
7 | The scene is rendered from the point of view of the light, only the depth is rendered. This result is saved in a depth only framebuffer.
8 | The framebuffer is then passed to the real scene being rendered, in the pixel shaders. Each pixel calculate its position but respective to the light instead
9 | of the camera, it then calculates its distance to the camera and compares it to the texture.
10 |
11 | To know the distance between the point and the light, the MVP (well, the V and P) are passed to the shader to calculate the screen position
12 | of the fragment from the point of view of the light.
13 |
14 | To find the position of the fragment on the depth texture (the shadow map) there needs to be a transform as the MVP*vertex gives the position
15 | in screen coord [-1. 1] whereas the texture map is [0, 1]
16 |
17 | If the texture is of a small size (which it is in the demo to accentuate the effect), there will be pretty big aliasing effects on the shadow
18 | To solve this there are a few techniques:
19 |
20 | - bilinearly interpolate the shadow map
21 | - PCF: instead of testing if the fragment is in this pixel of the shadow map, test the pixels around and do an average.
22 |
23 | These techniques can produce interesting effects (see the 7x7 matrix PCF) but is costly (7x7 = 35 shadow map read per pixel)
24 |
25 | # Controls
26 |
27 | - WASD: moves the camera
28 | - IJKL: change camera view direction
29 | - VBNM: Chose different positions of light (moving dynamic light and fixed)
30 | - Shadow map types:
31 | - E: no shadow mapping
32 | - R: shadow mapping without processing: the raw shadow map is drawn, square pixels will appear
33 | - T: The shadow maps pixels are lineary interpolated, making the shadow "smoother"
34 | - Y: PCF without bilinear interpolation (3x3 PCF matrix)
35 | - U: PCF with bilinear interpolation (3x3 PCF matrix)
36 | - F: PCF with bilinear interpolation (7x7 PCF matrix)
37 | - G: optimized PCF with bilinear interpolation (3x3 PCF matrix)
38 |
--------------------------------------------------------------------------------
/shadow_mapping/glsl/cube_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 | uniform vec3 light_position;
8 | in vec3 surface_normal;
9 |
10 | uniform mat4 shadow_matrix; //bias*P*V
11 |
12 | out vec3 frag_surface_normal_color;
13 | out float red;
14 | out float green;
15 | out float blue;
16 |
17 | out vec4 shadow_coord;
18 |
19 | void main(){
20 | gl_Position = projection*view*model*vec4(position, 1.0);
21 |
22 | mat3 normalMat = mat3(model);
23 | normalMat = transpose(inverse(normalMat));
24 |
25 | vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
26 |
27 | vec3 normal_transformed = vec3(0.0);
28 | normal_transformed = normalize(normalMat*surface_normal);
29 |
30 | float diffuse_light = 0.0;
31 | diffuse_light = dot(normal_transformed, light_dir);
32 |
33 | float lum = 1.0*diffuse_light;
34 | lum = clamp(lum, 0.0, 1.0);
35 | frag_surface_normal_color = vec3(lum, lum, lum);
36 |
37 | shadow_coord = shadow_matrix * model*vec4(position, 1.0);
38 | }
39 |
40 | void main_colors_const(){
41 | gl_Position = projection*view*model*vec4(position, 1.0);
42 | red = green = blue = 0.0;
43 |
44 | if(gl_VertexID == 0){
45 | red = 1.0;
46 | }
47 | else if(gl_VertexID == 1){
48 | green = 1.0;
49 | }
50 | else if(gl_VertexID == 2){
51 | blue = 1.0;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/shadow_mapping/glsl/quad_screen_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/shadow_mapping/glsl/sphere_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec3 surface_normal;
5 | in vec3 vertex_normal;
6 | uniform vec3 light_position;
7 | uniform vec3 camera_position;
8 | uniform uint lighting_mode;
9 | uniform bool activate_specular;
10 | uniform vec3 spot_direction;
11 | uniform bool activate_spot;
12 |
13 | uniform mat4 shadow_matrix; //bias*P*V
14 |
15 | uniform mat4 model;
16 | uniform mat4 view;
17 | uniform mat4 projection;
18 |
19 | out vec3 frag_position;
20 | out vec3 frag_surface_normal_color;
21 | out vec3 frag_normal_transformed;
22 | out float frag_spot_range;
23 | out float frag_spot_pow;
24 |
25 | out vec4 shadow_coord;
26 |
27 | const float spot_range = 0.98; //hhow wide the spot should be (in term of dot(light_dir, -spot_dir))
28 | const float spot_pow = 128;
29 |
30 | void main(){
31 | gl_Position = projection*view*model*vec4(position, 1.0);
32 |
33 | mat3 normalMat = mat3(model);
34 | normalMat = transpose(inverse(normalMat));
35 |
36 | vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
37 | vec3 view_dir = normalize(camera_position-vec3(model*vec4(position, 1.0)));
38 |
39 | vec3 normal_transformed = vec3(0.0);
40 | float diffuse_light = 0.0;
41 | float spec_light = 0.0;
42 |
43 | if(lighting_mode == 0u){ // per surface
44 | normal_transformed = normalize(normalMat*surface_normal);
45 | }
46 | else if(lighting_mode == 1u){
47 | normal_transformed = normalize(normalMat*vertex_normal);
48 | }
49 | else{
50 | normal_transformed = normalize(normalMat*vertex_normal);
51 | }
52 |
53 | //normal_transformed = clamp(normal_transformed, 0.0, 1.0);
54 |
55 | diffuse_light = dot(normal_transformed, light_dir);
56 |
57 | if(activate_specular == true){
58 | vec3 reflexion = 2*normal_transformed*dot(normal_transformed, light_dir)-light_dir;
59 | reflexion = clamp(reflexion, 0.0, 1.0);
60 | spec_light = pow(dot(reflexion, view_dir), 64);
61 | spec_light = clamp(spec_light, 0.0, 1.0);
62 | }
63 |
64 | float spot_brightness = 1.0;
65 |
66 | if(activate_spot == true){
67 | vec3 spot_direction_norm = normalize(spot_direction);
68 | float cos_spot = dot(-spot_direction_norm, light_dir);
69 |
70 | if(cos_spot > spot_range){
71 | spot_brightness = 1.0;
72 | }
73 | else{
74 | spot_brightness = pow(cos_spot+(1.0-spot_range), spot_pow);
75 | }
76 | }
77 |
78 | float lum = 0.8*diffuse_light+0.8*spec_light;
79 | lum = lum*spot_brightness;
80 | lum = clamp(lum, 0.0, 1.0);
81 |
82 | shadow_coord = shadow_matrix * model*vec4(position, 1.0);
83 |
84 | frag_normal_transformed = normal_transformed;
85 | frag_position = vec3(model*vec4(position, 1.0));
86 | frag_surface_normal_color = vec3(lum, lum, lum);
87 | frag_spot_range = spot_range;
88 | frag_spot_pow = spot_pow;
89 |
90 | }
91 |
--------------------------------------------------------------------------------
/sky/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME sky)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 |
26 | foreach(glsl_file ${GLSL_FILES})
27 | configure_file(${glsl_file} . COPYONLY)
28 | endforeach(glsl_file)
29 |
30 | #configure_file(${GLSL_FILES} . COPYONLY)
31 |
32 |
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
34 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
35 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
36 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
37 |
--------------------------------------------------------------------------------
/sky/README.md:
--------------------------------------------------------------------------------
1 | # Sky
2 |
3 |  
4 |
5 | This is a simple sky/sun implementation in the same idea of a sky box, instead a sphere is used here.
6 | The sun is drawn on the skysphere without the use of any textures, and the colour of the sun is reflected in the environment.
7 | At sunset, in addition to the sky becoming red, the objects on the scene also take the colour of the sky.
8 |
9 | Not using any texture and drawing the sun in a shader has the advantage to be more flexible and faster
10 |
11 | # Controls
12 |
13 | - WASD: moves the camera
14 | - IJKL: change camera view direction
15 | - VBNM: change light position
16 | - T: make the sun move (default)
17 | - Z: stop the sun
18 |
--------------------------------------------------------------------------------
/sky/_sky/sky_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 frag_normal_transformed;
4 | in vec3 frag_position;
5 |
6 | uniform vec3 camera_position;
7 | uniform vec3 light_position;
8 | uniform uint lighting_mode;
9 | uniform bool activate_specular;
10 | uniform vec3 spot_direction;
11 | uniform bool activate_spot;
12 | uniform float sky_size;
13 |
14 | in vec3 sun_dir_corr;
15 |
16 | out vec4 color;
17 |
18 | const vec3 night_colour = vec3(0.0, 0.0, 0.5);
19 | const vec3 day_colour = vec3(0.5, 0.5, 1.0);
20 | const vec3 red_sky = vec3(0.8, 0.3, 0.1);
21 |
22 | void main(){
23 | vec3 sky_colour = vec3(0.0, 0.0, 0.0);
24 |
25 | sky_colour = night_colour;
26 |
27 | //how much the sun is up or at sunset
28 | float up_sun = dot(sun_dir_corr, vec3(0.0, -1.0, 0.0));
29 | float evening_sun = dot(sun_dir_corr, vec3(-1.0, 0.0, 0.0));
30 |
31 | if( up_sun > -0.25){
32 |
33 | float day_quantity = clamp((up_sun+0.25)*3, 0.0, 1.0);
34 |
35 | sky_colour = day_quantity*day_colour+(1.0-day_quantity)*night_colour;
36 | }
37 |
38 | if(evening_sun > 0.8){
39 |
40 | float evening_quantity = (evening_sun-0.8)*(1/0.2);
41 |
42 | sky_colour = (evening_quantity)*red_sky+(1.0-evening_quantity)*sky_colour;
43 | }
44 |
45 | //draws the sun
46 | vec3 pos_sun = (-sun_dir_corr)*sky_size + sun_dir_corr*8;
47 | vec3 frag_position_comp = frag_position-pos_sun;
48 | if(dot(frag_position_comp, sun_dir_corr) < 0){
49 | sky_colour = vec3(1.0, 1.0, 1.0);
50 | }
51 |
52 | color.a = 1.0;
53 | color.rgb = sky_colour;
54 | }
55 |
--------------------------------------------------------------------------------
/sky/_sky/sky_sphere.h:
--------------------------------------------------------------------------------
1 | #ifndef SKY_SPHERE_H
2 | #define SKY_SPHERE_H
3 |
4 | #include "_sphere/sphere.h"
5 |
6 | class Sky_sphere : public Sphere{
7 | public:
8 | void init(unsigned int vertical_segments = 0, unsigned int horizontal_segments = 0, float sky_size = 512.0f){
9 |
10 | _pid = load_shaders("sky_vshader.glsl", "sky_fshader.glsl");
11 |
12 | Sphere::init(_pid, vertical_segments, horizontal_segments);
13 |
14 | sun_dir[0] = sin(sun_counter);
15 | sun_dir[1] = cos(sun_counter);
16 | sun_dir[2] = 0;
17 |
18 | //colour of the sun
19 | //these values will not be drawn on the sky (role of frag shader) but will
20 | //be returned to tint other objects
21 | sun_rgb[0] = 1.0;
22 | sun_rgb[1] = 1.0;
23 | sun_rgb[2] = 0.9;
24 |
25 | const_sun_daylight[0] = 1.0;
26 | const_sun_daylight[1] = 1.0;
27 | const_sun_daylight[2] = 0.9;
28 |
29 | //slight tint of blue for night time
30 | const_sun_night[0] = 0.0;
31 | const_sun_night[1] = 0.0;
32 | const_sun_night[2] = 0.1;
33 |
34 | const_sun_red[0] = 0.8;
35 | const_sun_red[1] = 0.3;
36 | const_sun_red[2] = 0.1;
37 |
38 | sun_counter = 1.0;
39 |
40 | this->sky_size = sky_size;
41 |
42 |
43 | if(_pid == 0) exit(-1);
44 | }
45 |
46 | void draw(){
47 | glFrontFace(GL_CW);
48 |
49 | glUseProgram(_pid);
50 |
51 | glUniform3fv( glGetUniformLocation(_pid, "sun_dir"), 1, this->sun_dir);
52 | glUniform1f( glGetUniformLocation(_pid, "sky_size"), this->sky_size);
53 |
54 | Sphere::draw();
55 |
56 | glFrontFace(GL_CCW);
57 | }
58 |
59 | //moves the sun
60 | void advance_sun(float time_delta){
61 | sun_counter += time_delta/2;
62 | sun_dir[0] = sin(sun_counter);
63 | sun_dir[1] = cos(sun_counter);
64 |
65 | sun_rgb[0] = const_sun_daylight[0];
66 | sun_rgb[1] = const_sun_daylight[1];
67 | sun_rgb[2] = const_sun_daylight[2];
68 |
69 | sun_rgb[0] = const_sun_night[0];
70 | sun_rgb[1] = const_sun_night[1];
71 | sun_rgb[2] = const_sun_night[2];
72 |
73 | //dot product on the up vector (how much the sun is up)
74 | float up_sun = sun_dir[1]*(-1.0);
75 |
76 | //dot product with the dusk vector (how much the sun is at sunset)
77 | float evening_sun = sun_dir[0]*(-1.0);
78 |
79 | if(up_sun > -0.25){
80 | float day_quantity = (up_sun+0.25)*3;
81 |
82 | if(day_quantity > 1){
83 | day_quantity = 1;
84 | }
85 |
86 | if(day_quantity < 0){
87 | day_quantity = 0;
88 | }
89 |
90 | sun_rgb[0] = day_quantity*const_sun_daylight[0]+(1.0-day_quantity)*const_sun_night[0];
91 | sun_rgb[1] = day_quantity*const_sun_daylight[1]+(1.0-day_quantity)*const_sun_night[1];
92 | sun_rgb[2] = day_quantity*const_sun_daylight[2]+(1.0-day_quantity)*const_sun_night[2];
93 | }
94 |
95 | if(evening_sun > 0.8){
96 |
97 | float evening_quantity = (evening_sun-0.8)*(1/0.2);
98 |
99 | sun_rgb[0] = evening_quantity*const_sun_red[0]+(1.0f-evening_quantity)*sun_rgb[0];
100 | sun_rgb[1] = evening_quantity*const_sun_red[1]+(1.0f-evening_quantity)*sun_rgb[1];
101 | sun_rgb[2] = evening_quantity*const_sun_red[2]+(1.0f-evening_quantity)*sun_rgb[2];
102 | }
103 |
104 | }
105 |
106 | float* get_sun_direction(){
107 | return sun_dir;
108 | }
109 |
110 | float* get_sun_pos(){
111 | return sun_pos;
112 | }
113 |
114 | float* get_sun_rgb_color(){
115 | return sun_rgb;
116 | }
117 |
118 | protected:
119 | float sun_dir[3];
120 | float sun_pos[3];
121 | float sun_rgb[3];
122 | float const_sun_daylight[3];
123 | float const_sun_night[3];
124 | float const_sun_red[3];
125 |
126 | float sun_counter;
127 | float sky_size;
128 | };
129 |
130 | #endif
131 |
--------------------------------------------------------------------------------
/sky/_sky/sky_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec3 surface_normal;
5 | in vec3 vertex_normal;
6 | uniform vec3 light_position;
7 | uniform vec3 camera_position;
8 | uniform vec4 clip_coord;
9 |
10 | uniform mat4 model;
11 | uniform mat4 view;
12 | uniform mat4 projection;
13 |
14 | out vec3 frag_position;
15 | out vec3 frag_normal_transformed;
16 |
17 | out vec4 shadow_coord;
18 | out vec3 sun_dir_corr;
19 |
20 | uniform vec3 sun_dir;
21 |
22 | void main(){
23 | gl_Position = projection*view*model*vec4(position, 1.0);
24 | gl_ClipDistance[0] = dot(model*vec4(position, 1.0), clip_coord);
25 |
26 | frag_position = vec3(model*vec4(position, 1.0));
27 |
28 | sun_dir_corr = sun_dir;
29 | }
30 |
--------------------------------------------------------------------------------
/sky/glsl/cube_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 frag_surface_normal_color;
4 |
5 | uniform sampler2D shadow_buffer_tex;
6 |
7 | uniform mat4 model;
8 | uniform mat4 view;
9 | uniform mat4 projection;
10 |
11 | uniform vec3 light_position;
12 |
13 | in float red;
14 | in float green;
15 | in float blue;
16 | out vec4 color;
17 |
18 | in vec3 frag_position;
19 | in vec3 frag_normal;
20 | in vec4 shadow_coord;
21 |
22 | uniform uint window_width;
23 | uniform uint window_height;
24 | uniform uint shadow_mapping_effect;
25 |
26 | uniform vec3 shape_color;
27 |
28 | uniform uint shadow_buffer_tex_size;
29 |
30 | uniform vec3 sun_dir;
31 | uniform vec3 sun_col;
32 |
33 | void main(){
34 |
35 | vec3 light_dir = normalize(light_position-frag_position);
36 | float dist_light = distance(light_position, frag_position);
37 | float diffuse_light = dot(frag_normal, light_dir);
38 | float light_intensity = diffuse_light*1/(dist_light/8);
39 |
40 | float diffuse_sun = dot(frag_normal, -sun_dir);
41 | diffuse_sun = clamp(diffuse_sun, 0.0, 1.0);
42 | vec3 sun_intensity = sun_col*diffuse_sun;
43 |
44 | vec3 final_intensity = vec3(0.0);
45 | final_intensity.r = max(light_intensity, sun_intensity.r);
46 | final_intensity.g = max(light_intensity, sun_intensity.g);
47 | final_intensity.b = max(light_intensity, sun_intensity.b);
48 |
49 | color = vec4(final_intensity*shape_color, 1.0);
50 | }
51 |
--------------------------------------------------------------------------------
/sky/glsl/cube_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 | uniform vec3 light_position;
8 | uniform vec4 clip_coord;
9 | in vec3 surface_normal;
10 |
11 | uniform mat4 shadow_matrix; //bias*P*V
12 |
13 | out vec3 frag_surface_normal_color;
14 | out vec3 frag_position;
15 | out vec3 frag_normal;
16 | out float red;
17 | out float green;
18 | out float blue;
19 |
20 | out vec4 shadow_coord;
21 | out float gl_ClipDistance[1];
22 |
23 | void main(){
24 | gl_Position = projection*view*model*vec4(position, 1.0);
25 | gl_ClipDistance[0] = dot(model*vec4(position, 1.0), clip_coord);
26 | frag_position = vec3(model*vec4(position, 1.0));
27 |
28 | mat3 normalMat = mat3(model);
29 | normalMat = transpose(inverse(normalMat));
30 |
31 | vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
32 |
33 | vec3 normal_transformed = vec3(0.0);
34 | normal_transformed = normalize(normalMat*surface_normal);
35 |
36 | float diffuse_light = 0.0;
37 | diffuse_light = dot(normal_transformed, light_dir);
38 |
39 | float lum = 1.0*diffuse_light;
40 | lum = clamp(lum, 0.0, 1.0);
41 | frag_surface_normal_color = vec3(lum, lum, lum);
42 |
43 | shadow_coord = shadow_matrix * model*vec4(position, 1.0);
44 | frag_normal = surface_normal;
45 | }
46 |
--------------------------------------------------------------------------------
/sky/glsl/quad_screen_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | uniform sampler2D tex;
3 | uniform sampler2D ao_tex;
4 | //uniform sampler2DMS tex;
5 | uniform float tex_width;
6 | uniform float tex_height;
7 | in vec2 uv;
8 | out vec4 color;
9 |
10 | uniform uint effect_select;
11 |
12 | void main() {
13 |
14 | vec3 color_out = vec3(0.5, 1.0, 0.0);
15 |
16 | if(effect_select == 0u){ //normal
17 | color_out = texture(tex, uv).rgb;//*get_ao_blur(uv); (ao_blur caused some glitches)
18 | }
19 |
20 | color = vec4(color_out, 1.0);
21 | }
22 |
--------------------------------------------------------------------------------
/sky/glsl/quad_screen_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/sky/glsl/sphere_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 frag_surface_normal_color;
4 |
5 | in vec3 frag_normal_transformed;
6 | in vec3 frag_position;
7 | in float frag_spot_range;
8 | in float frag_spot_pow;
9 |
10 | uniform sampler2D shadow_buffer_tex;
11 |
12 | uniform vec3 camera_position;
13 | uniform vec3 light_position;
14 | uniform uint lighting_mode;
15 | uniform bool activate_specular;
16 | uniform vec3 spot_direction;
17 | uniform bool activate_spot;
18 |
19 | uniform vec3 sun_dir;
20 | uniform vec3 sun_col;
21 |
22 | out vec4 color;
23 |
24 | in vec4 shadow_coord;
25 |
26 | uniform uint shadow_mapping_effect;
27 | uniform uint shadow_buffer_tex_size;
28 |
29 | float get_diffuse_strength(vec3 light_dir, vec3 normal){
30 | return clamp(dot(normal, light_dir), 0.0, 1.0);
31 | }
32 |
33 | float get_specular_strength(vec3 light_dir, vec3 normal, vec3 cam_pos, vec3 frag_pos){
34 | float spec_light = 0.0;
35 |
36 | vec3 reflexion = 2*normal*dot(normal, light_dir)-light_dir;
37 | reflexion = normalize(reflexion);
38 | vec3 view_dir = normalize(cam_pos-frag_pos);
39 |
40 | spec_light = pow(max(dot(reflexion, view_dir), 0.0), 128);
41 | spec_light = clamp(spec_light, 0.0, 1.0);
42 | return spec_light;
43 | }
44 |
45 | void main(){
46 | if(lighting_mode == 0u || lighting_mode == 1u){ //surface or vertex shading
47 | color = vec4(frag_surface_normal_color, 1.0);
48 | }
49 | else{
50 | vec3 light_dir = normalize(light_position-frag_position);
51 | float light_dist = distance(light_position, frag_position);
52 | float diffuse_light = 0.0;
53 | float spec_light = 0.0;
54 |
55 | float diffuse_sun = 0.0;
56 | float spec_sun = 0.0;
57 |
58 | diffuse_light = get_diffuse_strength(light_dir, frag_normal_transformed);
59 | diffuse_sun = get_diffuse_strength(-sun_dir, frag_normal_transformed);
60 |
61 | if(activate_specular == true){
62 | spec_light = get_specular_strength(light_dir, frag_normal_transformed, camera_position, frag_position);
63 | spec_sun = get_specular_strength(-sun_dir, frag_normal_transformed, camera_position, frag_position);
64 | }
65 |
66 | float spot_brightness = 1.0;
67 |
68 | if(activate_spot == true){
69 | vec3 spot_direction_norm = normalize(spot_direction);
70 | float cos_spot = dot(-spot_direction_norm, light_dir);
71 |
72 | if(cos_spot > frag_spot_range){
73 | spot_brightness = 1.0;
74 | }
75 | else{
76 | spot_brightness = pow(cos_spot+(1.0-frag_spot_range), frag_spot_pow);
77 | }
78 | }
79 |
80 | float lum_light = (0.8*diffuse_light+spec_light)*1/(light_dist/8);
81 | lum_light = spot_brightness*lum_light;
82 | vec3 light_strength = vec3(lum_light, lum_light, lum_light);
83 |
84 | float lum_sun = (0.8*diffuse_sun+spec_sun);
85 | vec3 sun_strength = sun_col*lum_sun;
86 | //color = vec3(texture( shadow_buffer_tex, shadow_coord.xy/shadow_coord.w ).x);
87 | color = vec4(light_strength+sun_strength, 1.0);
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/sky/glsl/sphere_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec3 surface_normal;
5 | in vec3 vertex_normal;
6 | uniform vec3 light_position;
7 | uniform vec3 camera_position;
8 | uniform vec4 clip_coord;
9 | uniform uint lighting_mode;
10 | uniform bool activate_specular;
11 | uniform vec3 spot_direction;
12 | uniform bool activate_spot;
13 |
14 | uniform mat4 shadow_matrix; //bias*P*V
15 |
16 | uniform mat4 model;
17 | uniform mat4 view;
18 | uniform mat4 projection;
19 |
20 | out vec3 frag_position;
21 | out vec3 frag_surface_normal_color;
22 | out vec3 frag_normal_transformed;
23 | out float frag_spot_range;
24 | out float frag_spot_pow;
25 |
26 | out vec4 shadow_coord;
27 |
28 | const float spot_range = 0.98; //hhow wide the spot should be (in term of dot(light_dir, -spot_dir))
29 | const float spot_pow = 128;
30 |
31 | void main(){
32 | gl_Position = projection*view*model*vec4(position, 1.0);
33 | gl_ClipDistance[0] = dot(model*vec4(position, 1.0), clip_coord);
34 |
35 | mat3 normalMat = mat3(model);
36 | normalMat = transpose(inverse(normalMat));
37 |
38 | vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
39 | vec3 view_dir = normalize(camera_position-vec3(model*vec4(position, 1.0)));
40 |
41 | vec3 normal_transformed = vec3(0.0);
42 | float diffuse_light = 0.0;
43 | float spec_light = 0.0;
44 |
45 | if(lighting_mode == 0u){ // per surface
46 | normal_transformed = normalize(normalMat*surface_normal);
47 | }
48 | else if(lighting_mode == 1u){
49 | normal_transformed = normalize(normalMat*vertex_normal);
50 | }
51 | else{
52 | normal_transformed = normalize(normalMat*vertex_normal);
53 | }
54 |
55 | //normal_transformed = clamp(normal_transformed, 0.0, 1.0);
56 |
57 | diffuse_light = dot(normal_transformed, light_dir);
58 |
59 | if(activate_specular == true){
60 | vec3 reflexion = 2*normal_transformed*dot(normal_transformed, light_dir)-light_dir;
61 | reflexion = clamp(reflexion, 0.0, 1.0);
62 | spec_light = pow(dot(reflexion, view_dir), 64);
63 | spec_light = clamp(spec_light, 0.0, 1.0);
64 | }
65 |
66 | float spot_brightness = 1.0;
67 |
68 | if(activate_spot == true){
69 | vec3 spot_direction_norm = normalize(spot_direction);
70 | float cos_spot = dot(-spot_direction_norm, light_dir);
71 |
72 | if(cos_spot > spot_range){
73 | spot_brightness = 1.0;
74 | }
75 | else{
76 | spot_brightness = pow(cos_spot+(1.0-spot_range), spot_pow);
77 | }
78 | }
79 |
80 | float lum = 0.8*diffuse_light+0.8*spec_light;
81 | lum = lum*spot_brightness;
82 | lum = clamp(lum, 0.0, 1.0);
83 |
84 | shadow_coord = shadow_matrix * model*vec4(position, 1.0);
85 |
86 | frag_normal_transformed = normal_transformed;
87 | frag_position = vec3(model*vec4(position, 1.0));
88 | frag_surface_normal_color = vec3(lum, lum, lum);
89 | frag_spot_range = spot_range;
90 | frag_spot_pow = spot_pow;
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/sphere_light/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME sphere_light)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h" "*.glsl")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 |
26 | foreach(glsl_file ${GLSL_FILES})
27 | configure_file(${glsl_file} . COPYONLY)
28 | endforeach(glsl_file)
29 |
30 | #configure_file(${GLSL_FILES} . COPYONLY)
31 |
32 |
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
34 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
35 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
36 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
37 |
--------------------------------------------------------------------------------
/sphere_light/README.md:
--------------------------------------------------------------------------------
1 | # Sphere lighting
2 |
3 |  
4 |
5 | The goal of this example is to implement a simple lighting model in opengl.
6 |
7 | A sphere is used in the middle of the scene in order to demonstrate the various lighting
8 |
9 | Multiple lighting models are implemented:
10 | - Flat: one normal per surface
11 | - Per vertex or Goureaud: one normal per vertex, calculation done in the vertex shader, the lighting is then interpolated for each pixel
12 | - Per pixel or Phong: Normals are interpolated for each pixel then the shading is calculated for each pixel, better visual result but more calculations needed
13 |
14 | Both the diffuse and specular lighting are calculated and both point light and spots are implemented and can be activated in the controls
15 |
16 | # controls
17 | - 0: flat lighting (default)
18 | - 1: vertex lighting (goureaud)
19 | - 2: pixel lighting (phong)
20 | - A: deactivate specular shading
21 | - S: activate specular shading (default)
22 | - Q: deactivate spotlight
23 | - W: activate spotlight (default)
24 | - Z: light going up and down (default)
25 | - X: light rotating above sphere
26 |
--------------------------------------------------------------------------------
/sphere_light/glsl/plane_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in float red;
4 | in float green;
5 | in float blue;
6 | out vec3 color;
7 |
8 | in vec3 frag_surface_normal_color;
9 |
10 | in vec3 frag_normal_transformed;
11 | in vec3 frag_position;
12 | in float frag_spot_range;
13 | in float frag_spot_pow;
14 |
15 | uniform vec3 camera_position;
16 | uniform vec3 light_position;
17 | uniform uint lighting_mode;
18 | uniform bool activate_specular;
19 | uniform vec3 spot_direction;
20 | uniform bool activate_spot;
21 |
22 | void main(){
23 |
24 | if(lighting_mode == 0u || lighting_mode == 1u){ //surface or vertex shading => take values calculated in vertex shader
25 | color = frag_surface_normal_color*vec3(red, green, blue);
26 | }
27 | else{
28 | vec3 light_dir = normalize(light_position-frag_position);
29 | float diffuse_light = 0.0;
30 |
31 | float spot_brightness = 1.0;
32 |
33 | if(activate_spot == true){
34 | vec3 spot_direction_norm = normalize(spot_direction);
35 | float cos_spot = dot(-spot_direction_norm, light_dir);
36 |
37 | if(cos_spot > frag_spot_range){
38 | spot_brightness = 1.0;
39 | }
40 | else{
41 | spot_brightness = pow(cos_spot+(1.0-frag_spot_range), frag_spot_pow);
42 | }
43 | }
44 |
45 | diffuse_light = dot(frag_normal_transformed, light_dir);
46 |
47 | float lum = 0.8*diffuse_light;
48 | lum = spot_brightness*lum;
49 |
50 | color = lum*vec3(red, green, blue);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/sphere_light/glsl/plane_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 vpoint;
4 | in vec3 normal;
5 | uniform mat4 model;
6 | uniform mat4 view;
7 | uniform mat4 projection;
8 |
9 | uniform vec3 light_position;
10 | uniform vec3 camera_position;
11 | uniform uint lighting_mode;
12 | uniform bool activate_specular;
13 | uniform vec3 spot_direction;
14 | uniform bool activate_spot;
15 |
16 | out float red;
17 | out float green;
18 | out float blue;
19 |
20 | out vec3 frag_position;
21 | out vec3 frag_surface_normal_color;
22 | out vec3 frag_normal_transformed;
23 | out float frag_spot_range;
24 | out float frag_spot_pow;
25 |
26 | const float spot_range = 0.98; //how wide the spot should be (in term of dot(light_dir, -spot_dir))
27 | const float spot_pow = 128;
28 |
29 | void main(){
30 | gl_Position = projection*view*model*vec4(vpoint, 1.0);
31 | red = green = blue = 0.0;
32 |
33 | if(gl_VertexID == 0){
34 | red = 1.0;
35 | }
36 | else if(gl_VertexID == 1){
37 | green = 1.0;
38 | }
39 | else if(gl_VertexID == 2){
40 | blue = 1.0;
41 | }
42 |
43 | gl_Position = projection*view*model*vec4(vpoint, 1.0);
44 |
45 | //model matrix for normals needs to be ((mat)⁻¹)^T
46 | mat3 normalMat = mat3(model);
47 | normalMat = transpose(inverse(normalMat));
48 |
49 | //find light and view dir from the vertex
50 | vec3 light_dir = normalize(light_position-vec3(model*vec4(vpoint, 1.0)));
51 | vec3 view_dir = normalize(camera_position-vec3(model*vec4(vpoint, 1.0)));
52 |
53 | vec3 normal_transformed = vec3(0.0);
54 | float diffuse_light = 0.0;
55 |
56 | //per vertex or per pixel
57 | normal_transformed = normalize(normalMat*normal);
58 | normal_transformed = clamp(normal_transformed, 0.0, 1.0);
59 |
60 | //calculate per vertex diffuse light
61 | diffuse_light = dot(normal_transformed, light_dir);
62 |
63 | float spot_brightness = 1.0;
64 |
65 | if(activate_spot == true){
66 | vec3 spot_direction_norm = normalize(spot_direction);
67 | float cos_spot = dot(-spot_direction_norm, light_dir);
68 |
69 | if(cos_spot > spot_range){
70 | spot_brightness = 1.0;
71 | }
72 | else{
73 | spot_brightness = pow(cos_spot+(1.0-spot_range), spot_pow);
74 | }
75 | }
76 |
77 | //calculate a sum for the lighting value of either per vertex or surface
78 | float lum = 0.8*diffuse_light;
79 | lum = lum*spot_brightness;
80 | lum = clamp(lum, 0.0, 1.0);
81 |
82 | //calculations of transforms, positions for the per pixel lighting
83 | frag_normal_transformed = normal_transformed;
84 | frag_position = vec3(model*vec4(vpoint, 1.0));
85 | frag_surface_normal_color = vec3(lum, lum, lum);
86 | frag_spot_range = spot_range;
87 | frag_spot_pow = spot_pow;
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/sphere_light/glsl/sphere_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 frag_surface_normal_color;
4 |
5 | in vec3 frag_normal_transformed;
6 | in vec3 frag_position;
7 | in float frag_spot_range;
8 | in float frag_spot_pow;
9 |
10 | uniform vec3 camera_position;
11 | uniform vec3 light_position;
12 | uniform uint lighting_mode;
13 | uniform bool activate_specular;
14 | uniform vec3 spot_direction;
15 | uniform bool activate_spot;
16 |
17 | out vec3 color;
18 |
19 | void main(){
20 | if(lighting_mode == 0u || lighting_mode == 1u){ //surface or vertex shading => take values calculated in vertex shader
21 | color = frag_surface_normal_color;
22 | }
23 | else{
24 | vec3 light_dir = normalize(light_position-frag_position);
25 | float diffuse_light = 0.0;
26 | float spec_light = 0.0;
27 |
28 | //specular is the bright spot, this is a classical calculation for it
29 | if(activate_specular == true){
30 | vec3 reflexion = 2*frag_normal_transformed*dot(frag_normal_transformed, light_dir)-light_dir;
31 | reflexion = normalize(reflexion);
32 | vec3 view_dir = normalize(camera_position-frag_position);
33 |
34 | reflexion = clamp(reflexion, 0.0, 1.0);
35 | spec_light = pow(max(dot(reflexion, view_dir), 0.0), 64);
36 | spec_light = clamp(spec_light, 0.0, 1.0);
37 | }
38 |
39 | float spot_brightness = 1.0;
40 |
41 | if(activate_spot == true){
42 | vec3 spot_direction_norm = normalize(spot_direction);
43 | float cos_spot = dot(-spot_direction_norm, light_dir);
44 |
45 | if(cos_spot > frag_spot_range){
46 | spot_brightness = 1.0;
47 | }
48 | else{
49 | //spot brightness goes down fast if out of it
50 | spot_brightness = pow(cos_spot+(1.0-frag_spot_range), frag_spot_pow);
51 | }
52 | }
53 |
54 | diffuse_light = dot(frag_normal_transformed, light_dir);
55 |
56 | float lum = 0.8*diffuse_light+spec_light;
57 | lum = spot_brightness*lum;
58 |
59 | color = vec3(lum, lum, lum);
60 | }
61 |
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/sphere_light/glsl/sphere_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec3 surface_normal;
5 | in vec3 vertex_normal;
6 | uniform vec3 light_position;
7 | uniform vec3 camera_position;
8 | uniform uint lighting_mode;
9 | uniform bool activate_specular;
10 | uniform vec3 spot_direction;
11 | uniform bool activate_spot;
12 |
13 | uniform mat4 model;
14 | uniform mat4 view;
15 | uniform mat4 projection;
16 |
17 | out vec3 frag_position;
18 | out vec3 frag_surface_normal_color;
19 | out vec3 frag_normal_transformed;
20 | out float frag_spot_range;
21 | out float frag_spot_pow;
22 |
23 | const float spot_range = 0.98; //how wide the spot should be (in term of dot(light_dir, -spot_dir))
24 | const float spot_pow = 128;
25 |
26 | void main(){
27 | gl_Position = projection*view*model*vec4(position, 1.0);
28 |
29 | //model matrix for normals needs to be ((mat)⁻¹)^T
30 | mat3 normalMat = mat3(model);
31 | normalMat = transpose(inverse(normalMat));
32 |
33 | //find light and view dir from the vertex
34 | vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
35 | vec3 view_dir = normalize(camera_position-vec3(model*vec4(position, 1.0)));
36 |
37 | vec3 normal_transformed = vec3(0.0);
38 | float diffuse_light = 0.0;
39 | float spec_light = 0.0;
40 |
41 | //apply model transform to either surface normal or vertex normal depending on mode
42 | if(lighting_mode == 0u){ // per surface
43 | normal_transformed = normalize(normalMat*surface_normal);
44 | }
45 | else{ //per vertex or per pixel
46 | normal_transformed = normalize(normalMat*vertex_normal);
47 | }
48 | normal_transformed = clamp(normal_transformed, 0.0, 1.0);
49 |
50 | //calculate diffuse light for the normal (if per vertex lighting)
51 | diffuse_light = dot(normal_transformed, light_dir);
52 |
53 | //calculate specular for per surface or vertex lighting
54 | if(activate_specular == true){
55 | vec3 reflexion = 2*normal_transformed*dot(normal_transformed, light_dir)-light_dir;
56 | reflexion = clamp(reflexion, 0.0, 1.0);
57 | spec_light = pow(dot(reflexion, view_dir), 64);
58 | spec_light = clamp(spec_light, 0.0, 1.0);
59 | }
60 |
61 | float spot_brightness = 1.0;
62 |
63 | if(activate_spot == true){
64 | vec3 spot_direction_norm = normalize(spot_direction);
65 | float cos_spot = dot(-spot_direction_norm, light_dir);
66 |
67 | if(cos_spot > spot_range){
68 | spot_brightness = 1.0;
69 | }
70 | else{
71 | spot_brightness = pow(cos_spot+(1.0-spot_range), spot_pow);
72 | }
73 | }
74 |
75 | //calculate a sum for the lighting value of either per vertex or surface
76 | float lum = 0.8*diffuse_light+0.8*spec_light;
77 | lum = lum*spot_brightness;
78 | lum = clamp(lum, 0.0, 1.0);
79 |
80 | //calculations of transforms, positions for the per pixel lighting
81 | frag_normal_transformed = normal_transformed;
82 | frag_position = vec3(model*vec4(position, 1.0));
83 | frag_surface_normal_color = vec3(lum, lum, lum);
84 | frag_spot_range = spot_range;
85 | frag_spot_pow = spot_pow;
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/terrain_camera/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME terrain_camera)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 |
26 | foreach(glsl_file ${GLSL_FILES})
27 | configure_file(${glsl_file} . COPYONLY)
28 | endforeach(glsl_file)
29 |
30 | #configure_file(${GLSL_FILES} . COPYONLY)
31 |
32 |
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
34 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
35 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
36 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
37 |
--------------------------------------------------------------------------------
/terrain_camera/README.md:
--------------------------------------------------------------------------------
1 | # Terrain camera
2 |
3 |  
4 |
5 | This example is an implementation of a procedural terrain using a Perlin noise in which we can move using a free-moving camera or a FPS-style camera
6 |
7 | The terrain is generated using a perlin noise which provides a natural look, the noise is generated using an additive noise funcition with a fractional
8 | amplitude each loop.
9 |
10 | The noise generation is done in the CPU, as such it isn't the fastest (4sec needed for the generation on a i7 laptop).
11 |
12 | In addition to the heightmap, the normals for the terrain are also generated using the same perlin noise, this allows a specular lighting to be used.
13 |
14 | Other evaluated noise functions were linear, which is fast but gives ugly results, and the ease function with random values, which gives a smooth results, less natural than Perlin but with less calculations. Perlin stays very slow, and could be accelerated by being implemented on the GPU or using some sort of LOD to not load a precise noise function with lots of loops in far away polygons.
15 |
16 | # Controls
17 |
18 | - WASD: move the camera position
19 | - IJKL: move the camera orientation
20 | - M: free camera
21 | - N: fps camera, stuck to the ground (default)
22 | - B/V: activate/deactivate moving light (default is not moving)
23 | - Z/X: activate/deactivate colour (default is colour)
24 | - T/Y: activate/deactivate heighmap: draw terrain pixel depending on their height (default is not drawn)
25 |
--------------------------------------------------------------------------------
/terrain_camera/_terrain/terrain_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 frag_normal_transformed;
4 | in vec3 frag_position;
5 |
6 | uniform vec3 camera_position;
7 | uniform vec3 light_position;
8 |
9 | uniform bool activate_colour;
10 | uniform bool activate_heightmap;
11 |
12 | out vec3 color;
13 |
14 | in float frag_nontransfheight;
15 |
16 | //colors the terrain depending on the height
17 | const vec3 COLOR[3] = vec3[](
18 | vec3(0.0, 0.0, 1.0), //blue, water
19 | vec3(0.0, 0.7, 0.0), // green, grass
20 | vec3(0.8, 0.8, 0.8)); //gray/white, snowtops
21 |
22 | void main(){
23 | vec3 light_dir = normalize(light_position-frag_position);
24 | float diffuse_light = 0.0;
25 |
26 | vec3 reflexion = 2*frag_normal_transformed*dot(frag_normal_transformed, light_dir)-light_dir;
27 | reflexion = normalize(reflexion);
28 | vec3 view_dir = normalize(camera_position-frag_position);
29 |
30 | reflexion = clamp(reflexion, 0.0, 1.0);
31 |
32 | diffuse_light = dot(frag_normal_transformed, light_dir);
33 |
34 | float lum = 0.8*diffuse_light;
35 |
36 | float height = frag_nontransfheight/2.0+0.5;
37 | vec3 pixel_colour = vec3(0.0);
38 |
39 | if(height < 0.5){
40 | pixel_colour = (1.0-height*2)*COLOR[0]+height*2*COLOR[1];
41 | }else{
42 | pixel_colour = (1.0-(height-0.5)*2)*COLOR[1]+(height-0.5)*2*COLOR[2];
43 | }
44 |
45 | if(!activate_colour){
46 | pixel_colour = vec3(1.0);
47 | }
48 |
49 | if(activate_heightmap){
50 | color = vec3(frag_nontransfheight/2.0+0.5, frag_nontransfheight/2.0+0.5, frag_nontransfheight/2.0+0.5);
51 | }
52 | else{
53 | color = pixel_colour*lum;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/terrain_camera/_terrain/terrain_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec3 vertex_normal;
5 | uniform vec3 light_position;
6 | uniform vec3 camera_position;
7 |
8 | uniform mat4 model;
9 | uniform mat4 view;
10 | uniform mat4 projection;
11 |
12 | out vec3 frag_position;
13 | out vec3 frag_surface_normal_color;
14 | out vec3 frag_normal_transformed;
15 |
16 | //to draw the height, without having it modified by the model matrix
17 | out float frag_nontransfheight;
18 |
19 | void main(){
20 | gl_Position = projection*view*model*vec4(position, 1.0);
21 |
22 | mat3 normalMat = mat3(model);
23 | normalMat = transpose(inverse(normalMat));
24 |
25 | vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
26 | vec3 view_dir = normalize(camera_position-vec3(model*vec4(position, 1.0)));
27 |
28 | vec3 normal_transformed = vec3(0.0);
29 | float diffuse_light = 0.0;
30 |
31 | normal_transformed = normalize(normalMat*vertex_normal);
32 |
33 | normal_transformed = clamp(normal_transformed, 0.0, 1.0);
34 |
35 | diffuse_light = dot(normal_transformed, light_dir);
36 |
37 | float lum = 0.8*diffuse_light;
38 | lum = clamp(lum, 0.0, 1.0);
39 |
40 | frag_normal_transformed = normal_transformed;
41 | frag_position = vec3(model*vec4(position, 1.0));
42 |
43 | frag_nontransfheight = position[1];
44 | }
45 |
--------------------------------------------------------------------------------
/terrain_camera/camera_fps.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "camera.h"
7 | #include "_terrain/terrain.h"
8 |
9 | class Camera_fps : public Camera_free{
10 | public:
11 |
12 | void init(float height, Terrain *terrain){
13 | set_height(height);
14 | set_terrain(terrain);
15 |
16 | this->update_pos();
17 | }
18 |
19 | void set_height(float height){
20 | this->height = height;
21 | }
22 |
23 | void set_terrain(Terrain *terrain){
24 | this->terrain = terrain;
25 | }
26 |
27 | virtual void input_handling(char key, float time_delta){
28 |
29 | glm::vec3 direction;
30 | glm::vec3 speed_factor = glm::vec3(this->speed)*time_delta;
31 |
32 | direction = center - eye;
33 | direction = glm::vec3(direction[0], 0.0f, direction[2]);
34 | direction = normalize(direction);
35 |
36 | glm::vec3 left_dir = normalize(cross(up, direction));
37 | glm::vec3 right_dir = normalize(cross(direction, up));
38 |
39 | if(key == 'W' || key == 'A' || key == 'S' || key == 'D'){
40 | float height_before = eye[1];
41 |
42 | switch(key){
43 | case 'W':
44 | eye = eye + speed_factor*direction;
45 | center = center + speed_factor*direction;
46 | break;
47 | case 'S':
48 | eye = eye - speed_factor*direction;
49 | center = center - speed_factor*direction;
50 | break;
51 | case 'A':
52 | eye = eye + speed_factor*left_dir;
53 | center = center + speed_factor*left_dir;
54 | break;
55 | case 'D':
56 | eye = eye + speed_factor*right_dir;
57 | center = center + speed_factor*right_dir;
58 | }
59 |
60 | float height_diff = terrain->get_height(eye[0], eye[2]) - height_before;
61 | //printf("eye: %f, %f, %f\n", eye[0], eye[1], eye[2]);
62 |
63 | eye[1] += height_diff+height;
64 | center[1] += height_diff+height;
65 | }
66 | else {
67 | Camera_free::input_handling(key, time_delta);
68 | }
69 |
70 | }
71 |
72 | protected:
73 | Terrain *terrain; //collision
74 | float height;
75 | };
76 |
--------------------------------------------------------------------------------
/terrain_camera/transform.h:
--------------------------------------------------------------------------------
1 | #ifndef TRANSFORM_H
2 | #define TRANSFORM_H
3 |
4 | #include
5 | #include
6 | #include //perspective
7 |
8 | class Transform{
9 | public:
10 | Transform(){
11 | transform_mat = glm::mat4(1.0f); //identity
12 | }
13 |
14 | void scale(glm::vec3 vec){
15 | transform_mat = glm::scale(transform_mat, vec);
16 | }
17 |
18 | void scale(float x, float y, float z){
19 | this->scale(glm::vec3(x, y, z));
20 | }
21 |
22 | glm::mat4 get_matrix(){
23 | return transform_mat;
24 | }
25 |
26 | glm::vec3 transform_point(glm::vec3 point3){
27 | glm::vec4 point4 = glm::vec4(point3, 1.0f);
28 | point4 = transform_mat*point4;
29 | return glm::vec3(point4);
30 | }
31 |
32 | ~Transform(){
33 | }
34 |
35 |
36 | protected:
37 | glm::mat4 transform_mat;
38 | };
39 |
40 | #endif
41 |
--------------------------------------------------------------------------------
/tessellation_shader/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME tessellation_shader)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Debug)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | find_package(Threads)
15 |
16 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
17 | set(LIB_PATH "/usr/lib")
18 |
19 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
20 | LINK_DIRECTORIES(${LIB_PATH})
21 |
22 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
23 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
24 |
25 | #copy all glsl files to build folder
26 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
27 |
28 | foreach(glsl_file ${GLSL_FILES})
29 | configure_file(${glsl_file} . COPYONLY)
30 | endforeach(glsl_file)
31 |
32 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
34 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
35 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
36 | target_link_libraries(${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT})
37 |
--------------------------------------------------------------------------------
/tessellation_shader/README.md:
--------------------------------------------------------------------------------
1 | # Tessellation shader
2 |
3 | Requires OpenGL 4.0
4 |
5 | 
6 |
7 | This example shows 18 triangles arranged in a flat plane. The height of the verice is calculated from sines, `sin(x)+sin(z)`.
8 | Without tessellation, the surface will appear very flat, however using the tessellation shader, intermediate veroces will appear between the triangles according to a tessellation level.
9 |
10 | Two levels of the tessellation shader are used, the Tessellation Control Shader (TCS) is used to calculate the tessellation level for the edges.
11 | The Tessellation Evaluation Shader (TES), acts as a vertex shader but for the resulting tessellated vertices. The vertex shader is only used for the control points, that is original vertices of the shape before the tessellation.
12 |
13 | The tessellation level is calculated as the inverse of the distance between the camera and the verices. Moving the camera around will change the tessellation level the closer it is to a geometry, the more detailed it will be.
14 |
15 | # Controls
16 | - WASD: moves the camera
17 | - IJKL: change camera view direction
18 | - N/M: Wireframe ON/OFF
19 | - 1-9: Have a fixed tessellation level
20 | - 0: Use inverse of distance as tessellation level
21 |
--------------------------------------------------------------------------------
/tessellation_shader/glsl/plane_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 400 core
2 |
3 | out vec3 color;
4 |
5 | in vec2 uv;
6 | in vec3 normal;
7 | uniform sampler2D tex;
8 |
9 | void main(){
10 | vec3 sun_dir = normalize(vec3(1,1,1));
11 | color = vec3( dot(normal, sun_dir))/2;
12 |
13 | //possibility of having a texture
14 | // color = texture(tex, uv).rgb;
15 | }
16 |
--------------------------------------------------------------------------------
/tessellation_shader/glsl/plane_tcshader.glsl:
--------------------------------------------------------------------------------
1 | #version 400 core
2 |
3 | layout (vertices = 3) out;
4 |
5 | uniform vec3 camera_position;
6 |
7 | uniform int fixed_tessellation_level_active;
8 | uniform int fixed_tessellation_level;
9 |
10 | in vec2 uv_tess[];
11 |
12 | out vec2 uv_tes[];
13 |
14 | void main()
15 | {
16 | uv_tes[gl_InvocationID] = uv_tess[gl_InvocationID];
17 |
18 | float dist0 = distance(camera_position, (gl_in[0].gl_Position.xyz+gl_in[1].gl_Position.xyz)*0.5 );
19 | float dist1 = distance(camera_position, (gl_in[1].gl_Position.xyz+gl_in[2].gl_Position.xyz)*0.5);
20 | float dist2 = distance(camera_position, (gl_in[2].gl_Position.xyz+gl_in[0].gl_Position.xyz)*0.5);
21 |
22 | gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
23 |
24 | // Calculate the tessellation levels, from distance
25 | float tess_lvl0 = 150/dist0;
26 | float tess_lvl1 = 150/dist1;
27 | float tess_lvl2 = 150/dist2;
28 |
29 | if(fixed_tessellation_level_active != 0){
30 | tess_lvl0 = fixed_tessellation_level;
31 | tess_lvl1 = fixed_tessellation_level;
32 | tess_lvl2 = fixed_tessellation_level;
33 | }
34 |
35 | //select correct levels for outer level, otherwise some cracks will appear
36 | gl_TessLevelOuter[0] = tess_lvl1;
37 | gl_TessLevelOuter[1] = tess_lvl2;
38 | gl_TessLevelOuter[2] = tess_lvl0;
39 | gl_TessLevelInner[0] = (tess_lvl0+tess_lvl1+tess_lvl2)/3;
40 | }
41 |
--------------------------------------------------------------------------------
/tessellation_shader/glsl/plane_teshader.glsl:
--------------------------------------------------------------------------------
1 | #version 400 core
2 |
3 | uniform mat4 view;
4 | uniform mat4 projection;
5 |
6 | //selection of the tessellation
7 | // layout(triangles, fractional_even_spacing, ccw) in;
8 | layout(triangles, fractional_odd_spacing, ccw) in;
9 | // layout(triangles, equal_spacing, ccw) in;
10 |
11 | in vec2 uv_tes[];
12 | out vec2 uv;
13 |
14 | out vec3 normal;
15 |
16 | precise gl_Position;
17 |
18 | //do interpolation between the points according to the barycentric values
19 | vec2 mix_tess_vec2(vec2 p0, vec2 p1, vec2 p2){
20 | return gl_TessCoord.x*p0 + gl_TessCoord.y*p1 + gl_TessCoord.z*p2;
21 | }
22 |
23 | vec4 mix_tess_vec4(vec4 p0, vec4 p1, vec4 p2){
24 | return gl_TessCoord.x*p0 + gl_TessCoord.y*p1 + gl_TessCoord.z*p2;
25 | }
26 |
27 | void main(){
28 | uv = mix_tess_vec2(uv_tes[0], uv_tes[1], uv_tes[2]);
29 |
30 | float sine_frequency = 2;
31 |
32 | vec4 vertex_position = mix_tess_vec4(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_in[2].gl_Position);
33 |
34 | //will do a simple 2D sine terrain
35 | vertex_position.y += (sin(vertex_position.x*sine_frequency)+sin(vertex_position.z*sine_frequency))*0.3;
36 |
37 | //vectors to calculate the normal of the sine terrain (partial derivative of sin(x))
38 | vec3 norm_vec_x = vec3(1, cos(sine_frequency*vertex_position.x), 0);
39 | vec3 norm_vec_z = vec3(0, cos(sine_frequency*vertex_position.z), 1);
40 |
41 | normal = normalize(cross(norm_vec_z, norm_vec_x));
42 |
43 | gl_Position = projection*view*vertex_position;
44 | }
45 |
--------------------------------------------------------------------------------
/tessellation_shader/glsl/plane_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 400 core
2 |
3 | in vec3 vpoint;
4 | in vec2 vtexcoord;
5 | uniform mat4 model;
6 | uniform mat4 view;
7 | uniform mat4 projection;
8 |
9 | out vec2 uv_tess;
10 |
11 | void main(){
12 | //only calculate the model matrix to have distance between vertex and camera in tess. shader
13 | gl_Position = model*vec4(vpoint, 1.0);
14 |
15 | uv_tess = vtexcoord;
16 | }
17 |
--------------------------------------------------------------------------------
/tessellation_shader/glsl/quad_screen_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | uniform sampler2D tex;
3 | uniform sampler2D ao_tex;
4 | uniform float tex_width;
5 | uniform float tex_height;
6 | in vec2 uv;
7 | out vec4 color;
8 |
9 | uniform uint effect_select;
10 |
11 | void main() {
12 |
13 | vec3 color_out = vec3(0.5, 1.0, 0.0);
14 |
15 | if(effect_select == 0u){ //normal
16 | color_out = texture(tex, uv).rgb;//*get_ao_blur(uv); (ao_blur caused some glitches)
17 | }
18 |
19 | color = vec4(color_out, 1.0);
20 | }
21 |
--------------------------------------------------------------------------------
/tessellation_shader/glsl/quad_screen_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/texture_filtering/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME texture_filtering)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Debug)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | find_package(Threads)
15 |
16 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
17 | set(LIB_PATH "/usr/lib")
18 |
19 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
20 | LINK_DIRECTORIES(${LIB_PATH})
21 |
22 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
23 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
24 |
25 | #copy all glsl files to build folder
26 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
27 |
28 | foreach(glsl_file ${GLSL_FILES})
29 | configure_file(${glsl_file} . COPYONLY)
30 | endforeach(glsl_file)
31 |
32 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
34 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
35 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
36 | target_link_libraries(${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT})
37 |
--------------------------------------------------------------------------------
/texture_filtering/README.md:
--------------------------------------------------------------------------------
1 | # Texture filtering
2 |
3 | Shows some different texture filtering on a classical checkerboard texture to show how aliasing can be mitigated at the expense of more processing.
4 |
5 | | GL_NEAREST | GL_NEAREST_MIPMAP_NEAREST |
6 | | ------ | ----------- |
7 | |  |  |
8 |
9 | | GL_NEAREST_MIPMAP_LINEAR | Anisotropic 8.0f |
10 | | --------- | ---------- |
11 | |  |  |
12 |
13 | Point filtering is the simplest to compute, each pixel on screen will correspond to the nearest pixel on the texture, but will cause some aliasing artifacts in the distance when the object is moving
14 | Using Mipmaps solves the problem of aliasing by having multiple sizes of the same texture in memory which will be displayed at a distance, in the case of the checkerboard texture this causes a blur.
15 | Using the `GL_LINEAR_MIPMAP_LINEAR` fitering allows opengl to interpolate between the mipmap levels avoiding visible bands between the different levels.
16 | Anisotropic filtering will allow some clever and costly computation within opengl to take into account the position of the camera and the angle of the texture to fix both the aliasing and the blur.
17 |
18 | # Controls
19 | - WASD: moves the camera
20 | - IJKL: change camera view direction
21 | - X: GL_NEAREST as texture filtering, will take
22 | - C: GL_LINEAR, does bilinear interpolation on the texture
23 | - V: GL_LINEAR_MIPMAP_NEAREST, will use mipmap in the distance
24 | - B: GL_LINEAR_MIPMAP_LINEAR, will use mipmap in the distance but will interpolate between the mipmap levels (trilinear filtering)
25 | - 1: anisotropic filtering value 1
26 | - 2: anisotropic filtering value 2
27 | - 3: anisotropic filtering value 4
28 | - 4: anisotropic filtering value 8
29 | - N/M: activates or stops the rotation of the textured surface
30 |
--------------------------------------------------------------------------------
/texture_filtering/glsl/plane_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | out vec3 color;
4 |
5 | in vec2 uv;
6 | uniform sampler2D tex;
7 |
8 | void main(){
9 | color = texture(tex, uv).rgb;
10 | }
11 |
--------------------------------------------------------------------------------
/texture_filtering/glsl/plane_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 vpoint;
4 | in vec2 vtexcoord;
5 | uniform mat4 model;
6 | uniform mat4 view;
7 | uniform mat4 projection;
8 |
9 | out vec2 uv;
10 |
11 | void main(){
12 | gl_Position = projection*view*model*vec4(vpoint, 1.0);
13 |
14 | uv = vtexcoord;
15 | }
16 |
--------------------------------------------------------------------------------
/texture_filtering/glsl/quad_screen_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | uniform sampler2D tex;
3 | uniform sampler2D ao_tex;
4 | uniform float tex_width;
5 | uniform float tex_height;
6 | in vec2 uv;
7 | out vec4 color;
8 |
9 | uniform uint effect_select;
10 |
11 | void main() {
12 |
13 | vec3 color_out = vec3(0.5, 1.0, 0.0);
14 |
15 | if(effect_select == 0u){ //normal
16 | color_out = texture(tex, uv).rgb;//*get_ao_blur(uv); (ao_blur caused some glitches)
17 | }
18 |
19 | color = vec4(color_out, 1.0);
20 | }
21 |
--------------------------------------------------------------------------------
/texture_filtering/glsl/quad_screen_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/texture_filtering/texture_checkers.h:
--------------------------------------------------------------------------------
1 | #include "texture.h"
2 |
3 |
4 | class Texture_checkers : public Texture{
5 | public:
6 | Texture_checkers(){
7 | }
8 |
9 | ~Texture_checkers(){
10 | }
11 |
12 | //n = number of checkers on one side
13 | void init(int size, int n){
14 | this->tex_width = size;
15 | this->tex_height = size;
16 |
17 | this->tex_data = new unsigned char[size*size*3];
18 |
19 | for(int i = 0; i < size; i++){
20 | for(int j = 0; j < size; j++){
21 | int ind = (i*size+j)*3;
22 |
23 | int square_x = i/n;
24 | int square_y = j/n;
25 |
26 | if((square_x+square_y)%2 == 0){
27 | tex_data[ind] = 0;
28 | tex_data[ind+1] = 0;
29 | tex_data[ind+2] = 0;
30 | }
31 | else{
32 | tex_data[ind] = 255;
33 | tex_data[ind+1] = 255;
34 | tex_data[ind+2] = 255;
35 | }
36 | }
37 | }
38 | }
39 | };
40 |
--------------------------------------------------------------------------------
/texture_plane/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME texture_plane)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 | foreach(glsl_file ${GLSL_FILES})
26 | configure_file(${glsl_file} . COPYONLY)
27 | endforeach(glsl_file)
28 |
29 | file(GLOB_RECURSE TEXTURE_FILES "*.png")
30 | foreach(texture_file ${TEXTURE_FILES})
31 | configure_file(${texture_file} . COPYONLY)
32 | endforeach(texture_file)
33 |
34 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
35 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
36 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
37 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
38 |
--------------------------------------------------------------------------------
/texture_plane/README.md:
--------------------------------------------------------------------------------
1 | # Texture plane
2 |
3 |  
4 |
5 | # Controls
6 |
7 | - 1: Png image as texture
8 | - 2: Generated checkers as texture
9 |
--------------------------------------------------------------------------------
/texture_plane/glsl/plane_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in float red;
4 | in float green;
5 | in float blue;
6 | out vec3 color;
7 |
8 | in vec2 uv;
9 | uniform sampler2D tex;
10 |
11 | void main(){
12 | color = 0.5*texture(tex, uv).rgb + 0.5*vec3(red, green, blue);
13 | }
14 |
--------------------------------------------------------------------------------
/texture_plane/glsl/plane_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 vpoint;
4 | in vec2 vtexcoord;
5 | uniform mat4 model;
6 | uniform mat4 view;
7 | uniform mat4 projection;
8 |
9 | out float red;
10 | out float green;
11 | out float blue;
12 | out vec2 uv;
13 |
14 | void main(){
15 | gl_Position = projection*view*model*vec4(vpoint, 1.0);
16 | red = green = blue = 0.0;
17 |
18 | if(gl_VertexID == 0){
19 | red = 1.0;
20 | }
21 | else if(gl_VertexID == 1){
22 | green = 1.0;
23 | }
24 | else if(gl_VertexID == 2){
25 | blue = 1.0;
26 | }
27 |
28 | uv = vtexcoord;
29 | }
30 |
--------------------------------------------------------------------------------
/texture_plane/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #define GL_GLEXT_PROTOTYPES 1
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #define GLM_FORCE_RADIANS
13 | #include //perspective
14 |
15 | #include
16 |
17 | #include "camera.h"
18 | #include "shader_helper.h"
19 | #include "_plane/plane.h"
20 | #include "texture.h"
21 | #include "texture_checkers.h"
22 |
23 | void init();
24 | void display();
25 | void cleanup();
26 | GLuint load_shader(char *path, GLenum shader_type);
27 |
28 | Camera cam;
29 | Plane plane;
30 | //init matrices with identity
31 | glm::mat4x4 projection_mat = glm::mat4(1.0);
32 | glm::mat4x4 plane_model_mat = glm::mat4(1.0);
33 |
34 | Texture plane_texture;
35 | Texture_checkers tex_checkers;
36 |
37 | const int win_width = 1280;
38 | const int win_height = 720;
39 |
40 | int main(){
41 | if( !glfwInit() ){
42 | std::cout << "Error to initialize GLFW" << std::endl;
43 | return -1;
44 | }
45 |
46 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
47 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
48 | glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
49 |
50 | GLFWwindow* window = glfwCreateWindow(win_width, win_height, "texture_plane", NULL, NULL);
51 |
52 | if( !window ){
53 | std::cout << "failed to open window" << std::endl;
54 | return -1;
55 | }
56 |
57 | glfwMakeContextCurrent(window);
58 |
59 | glewExperimental = GL_TRUE;
60 | if(glewInit() != GLEW_NO_ERROR){
61 | std::cout << "glew error\n";
62 | return -1;
63 | }
64 |
65 | init();
66 |
67 | while(glfwGetKey(window, GLFW_KEY_ESCAPE)!=GLFW_PRESS && !glfwWindowShouldClose(window)){
68 | glfwPollEvents();
69 |
70 | if(glfwGetKey(window, '1')==GLFW_PRESS){
71 | plane.set_texture(&plane_texture);
72 | }
73 | else if(glfwGetKey(window, '2') == GLFW_PRESS){
74 | plane.set_texture(&tex_checkers);
75 | }
76 |
77 | display();
78 | glfwSwapBuffers(window);
79 | }
80 |
81 | cleanup();
82 |
83 | return 0;
84 | }
85 |
86 | void init(){
87 | glClearColor(1.0, 1.0, 1.0, 1.0);
88 |
89 | glEnable(GL_DEPTH_TEST);
90 | glDepthFunc(GL_LESS);
91 |
92 | glViewport(0,0,win_width,win_height);
93 | projection_mat = glm::perspective(60.0f*2*3.1415f/360.0f, (float)win_width/(float)win_height, 0.1f, 10.0f);
94 |
95 | ilInit();
96 |
97 | bool loaded = plane_texture.load_image("the_red_pepper.png");
98 | tex_checkers.init(8);
99 |
100 | if(!loaded){
101 | std::cout << "texture could not load :(" << std::endl;
102 | }
103 |
104 | GLuint plane_pid = load_shaders("plane_vshader.glsl", "plane_fshader.glsl");
105 | plane.init(plane_pid);
106 | plane.set_texture(&plane_texture);
107 |
108 | cam.lookAt(1.5f, 1.5f, 1.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
109 | }
110 |
111 | void display(){
112 | glClear(GL_COLOR_BUFFER_BIT);
113 | glClear(GL_DEPTH_BUFFER_BIT);
114 | float angle = glfwGetTime();
115 |
116 | //rotation matrix for the textured plane
117 | glm::mat4x4 plane_rot = glm::rotate(plane_model_mat, angle, glm::vec3(0.0, 1.0, 0.0));
118 | plane.draw(plane_rot, cam.getMatrix(), projection_mat);
119 | }
120 |
121 | void cleanup(){
122 | }
123 |
--------------------------------------------------------------------------------
/texture_plane/texture_checkers.h:
--------------------------------------------------------------------------------
1 | #include "texture.h"
2 |
3 |
4 | class Texture_checkers : public Texture{
5 | public:
6 | Texture_checkers(){
7 |
8 | }
9 |
10 | ~Texture_checkers(){
11 | //super destructor will be called automatically
12 | }
13 |
14 | //n = number of checkers on one side
15 | void init(int n){
16 | this->tex_width = n;
17 | this->tex_height = n;
18 |
19 | this->tex_data = new unsigned char[n*n*3];
20 |
21 | for(int i = 0; i < n; i++){
22 | for(int j = 0; j < n; j++){
23 | int ind = (i*n+j)*3;
24 | if((i+j)%2 == 0){
25 | tex_data[ind] = 0;
26 | tex_data[ind+1] = 0;
27 | tex_data[ind+2] = 0;
28 | }
29 | else{
30 | tex_data[ind] = 255;
31 | tex_data[ind+1] = 255;
32 | tex_data[ind+2] = 255;
33 | }
34 | }
35 | }
36 | }
37 | };
38 |
--------------------------------------------------------------------------------
/texture_plane/the_red_pepper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damdoy/opengl_examples/d380b4409fbf18c64a19075d0e13800eb7c004b7/texture_plane/the_red_pepper.png
--------------------------------------------------------------------------------
/tree/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME tree)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 |
26 | foreach(glsl_file ${GLSL_FILES})
27 | configure_file(${glsl_file} . COPYONLY)
28 | endforeach(glsl_file)
29 |
30 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
31 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
32 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
34 |
--------------------------------------------------------------------------------
/tree/README.md:
--------------------------------------------------------------------------------
1 | # Tree procedural generation using L-System
2 |
3 | Procedural generation of trees using L-Systems.
4 |
5 | The trunks are made of cylinder with some sort of simplified brown perlin noise as texture.
6 |
7 | Leaves are added on the tips of the branches, they are a bunch of green triangles whose corners has been smoothed by the fragment shader.
8 |
9 | The leaves are added as small spheres of these triangle shapes and the ones that are on the bottom of the sphere are darker in colour to give
10 | a sense of shadow and depth.
11 |
12 |  
13 |
14 |  
15 |
16 | # Controls
17 | - WASD: moves the camera
18 | - IJKL: change camera view direction
19 | - R: Generate a new tree
20 |
--------------------------------------------------------------------------------
/tree/_trees/leaves_individual_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 frag_position;
4 |
5 | uniform vec3 camera_position;
6 | uniform vec3 light_position;
7 |
8 | in vec2 uv_frag;
9 |
10 | uniform vec3 sun_col;
11 |
12 | out vec4 color;
13 | in float frag_diffuse_light;
14 |
15 | in float frag_relative_ground_pos;
16 |
17 | void main(){
18 |
19 | float distance_to_middle = distance(uv_frag, vec2(0.5, 0.5));
20 |
21 | if(distance_to_middle > 0.4 ){
22 | discard;
23 | }
24 |
25 | float rand_val = sin(frag_position.x*frag_position.z/10)+cos( (0.13-frag_position.x*frag_position.y) / 10 );
26 |
27 | color.a = 1.0;
28 |
29 | float lum = 1.0*frag_diffuse_light;
30 |
31 | float light_intensity = (frag_relative_ground_pos+0.6)*1.5;
32 | light_intensity = clamp(light_intensity, 0.0, 1.0);
33 | float reverse_dist_to_middle = 1.0-distance_to_middle;
34 |
35 | // color.rgb = lum*sun_col;
36 | color.rgb = vec3(0.1+rand_val/6, 0.4, 0.05)*light_intensity*reverse_dist_to_middle;
37 | // color.rgb = vec3(distance_to_middle);
38 | }
39 |
--------------------------------------------------------------------------------
/tree/_trees/leaves_individual_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec3 surface_normal;
5 | in vec2 uv;
6 | in mat4 model_mat;
7 | in vec3 raw_position;
8 | uniform mat4 model;
9 | uniform mat4 view;
10 | uniform mat4 projection;
11 |
12 | uniform vec3 light_position;
13 | uniform vec3 camera_position;
14 |
15 | uniform vec2 wind_offset;
16 | uniform sampler2D tex_wind;
17 |
18 | uniform vec3 sun_dir;
19 | uniform vec3 sun_col;
20 |
21 | out vec3 frag_position;
22 | out vec2 uv_frag;
23 |
24 | out float frag_diffuse_light;
25 | out float frag_relative_ground_pos;
26 |
27 | void main(){
28 |
29 | //(reminder) mat[2][0] // first elem of 2nd column
30 |
31 | mat4 global_model = model*model_mat;
32 | vec3 new_pos_tex = vec3(global_model*vec4(position, 1.0));
33 |
34 | vec2 relative_tex_pos = vec2(new_pos_tex.x/40+0.5, new_pos_tex.z/40+0.5);
35 |
36 | float wind_x = texture(tex_wind, (relative_tex_pos+wind_offset) ).r;
37 | float wind_z = texture(tex_wind, (relative_tex_pos+vec2(0.5, 0.5)+wind_offset) ).r;
38 |
39 | //rotation around x axis
40 | mat4 rot_mat_x = mat4(1, 0, 0, 0,
41 | 0, cos(wind_x), -sin(wind_x), 0,
42 | 0, sin(wind_x), cos(wind_x), 0,
43 | 0, 0, 0, 1);
44 |
45 | //rotation around z axis
46 | mat4 rot_mat_z = mat4(cos(wind_z), -sin(wind_z), 0, 0,
47 | sin(wind_z), cos(wind_x), 0, 0,
48 | 0, 0, 0, 0,
49 | 0, 0, 0, 1);
50 |
51 | vec3 new_pos = vec3(global_model*rot_mat_x*rot_mat_z*vec4(position, 1.0));
52 |
53 | float sun_intensity = dot(-sun_dir, vec3(0, 1, 0));
54 |
55 | sun_intensity = clamp(sun_intensity, 0.2, 1);
56 |
57 | float lum = 0.8*sun_intensity;
58 | frag_diffuse_light = lum;
59 |
60 | frag_relative_ground_pos = raw_position.y;
61 |
62 | gl_Position = projection*view*vec4(new_pos, 1.0);
63 |
64 | frag_position = vec3(vec4(new_pos, 1.0));
65 | uv_frag = uv;
66 | }
67 |
--------------------------------------------------------------------------------
/tree/_trees/texture_float.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | class Texture_float{
7 | public:
8 | Texture_float(){
9 | tex_data = NULL;
10 | }
11 |
12 | ~Texture_float(){
13 | if(tex_data != NULL){
14 | delete tex_data;
15 | }
16 | }
17 |
18 | //load image from disk
19 | bool load_image(const char *path){
20 | ilGenImages(1, &tex_id);
21 | ilBindImage(tex_id);
22 | ILboolean result = ilLoadImage(path);
23 | if(result == IL_FALSE){
24 | return false;
25 | }
26 |
27 | tex_width = ilGetInteger(IL_IMAGE_WIDTH);
28 | tex_height = ilGetInteger(IL_IMAGE_HEIGHT);
29 |
30 | tex_data = new float[tex_width*tex_height*3];
31 | ilCopyPixels(0, 0, 0, tex_width, tex_height, 1, IL_RGB, IL_FLOAT, tex_data);
32 |
33 | //unbind the image as the image data has been copyied
34 | ilBindImage(0);
35 | ilDeleteImage(tex_id);
36 |
37 | return true;
38 | }
39 |
40 | void set_data(const std::vector > &tex_data){
41 | this->tex_height = tex_data[0].size();
42 | this->tex_width = tex_data.size();
43 |
44 | this->tex_data = new float[tex_height*tex_width];
45 |
46 | for(unsigned int i = 0; i < tex_data.size(); i++){
47 | for(unsigned int j = 0; j < tex_data[0].size(); j++){
48 |
49 | this->tex_data[i*tex_width+j] = tex_data[i][j];
50 | }
51 | }
52 | }
53 |
54 | //return the data of the image in bytes
55 | float *get_tex_data() const {
56 | return tex_data;
57 | }
58 |
59 | int get_width() const{
60 | return tex_width;
61 | }
62 |
63 | int get_height() const{
64 | return tex_height;
65 | }
66 |
67 | protected:
68 | ILuint tex_id;
69 | unsigned int tex_width;
70 | unsigned int tex_height;
71 | float *tex_data;
72 | };
73 |
--------------------------------------------------------------------------------
/tree/_trees/trunk_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | uniform mat4 model;
4 | uniform mat4 view;
5 | uniform mat4 projection;
6 |
7 | uniform vec3 light_position;
8 |
9 | uniform sampler2D tex;
10 |
11 | in float red;
12 | in float green;
13 | in float blue;
14 | out vec4 color;
15 |
16 | in vec3 frag_position;
17 | in vec3 frag_normal;
18 | in vec4 shadow_coord;
19 | in vec2 tex_coord;
20 |
21 | uniform uint window_width;
22 | uniform uint window_height;
23 | uniform uint shadow_mapping_effect;
24 |
25 | uniform vec3 shape_color;
26 |
27 | uniform uint shadow_buffer_tex_size;
28 |
29 | uniform vec3 sun_dir;
30 | uniform vec3 sun_col;
31 |
32 | float get_shadow_val(float offset_x, float offset_y);
33 |
34 | vec3 get_billin(vec2 pos, vec3 min, vec3 max);
35 |
36 | mat2 noise_ao;
37 |
38 | vec3 bark_high = vec3(0.6, 0.4, 0.2);
39 | vec3 bark_low = vec3(0.4, 0.25, 0.2);
40 |
41 | void main(){
42 |
43 | float shadow = 1;
44 |
45 | vec3 light_dir = normalize(light_position-frag_position);
46 | float dist_light = distance(light_position, frag_position);
47 | float diffuse_light = dot(frag_normal, light_dir);
48 | float light_intensity = diffuse_light*1/(dist_light/8);
49 |
50 | float diffuse_sun = dot(frag_normal, -sun_dir);
51 | diffuse_sun = clamp(diffuse_sun, 0.0, 1.0);
52 | vec3 sun_intensity = sun_col*diffuse_sun;
53 |
54 | vec3 final_intensity = vec3(0.0);
55 |
56 | final_intensity.r = sun_intensity.r;
57 | final_intensity.g = sun_intensity.g;
58 | final_intensity.b = sun_intensity.b;
59 |
60 | //use texture or simple generated bilin function
61 | vec3 texture_col = get_billin(tex_coord*25, bark_low, bark_high);
62 |
63 | float time_of_day = dot(-sun_dir, vec3(0, 1, 0));
64 |
65 | vec3 color_trunk = texture_col*diffuse_light;
66 |
67 | color = vec4( color_trunk*shadow , 1.0);
68 | }
69 |
70 | float rand(ivec2 pt)
71 | {
72 | float x = pt.x*3.13;
73 | float y = pt.y*7.17;
74 | return fract(x*y/17);
75 | }
76 |
77 | float rand(vec2 pt)
78 | {
79 | return rand(ivec2(pt.x, pt.y));
80 | }
81 |
82 | vec3 get_billin(vec2 pos, vec3 min, vec3 max)
83 | {
84 | vec2 rounded_pos = round(pos);
85 |
86 | float val00 = rand((pos));
87 | float val10 = rand((vec2(pos.x, pos.y+1)));
88 | float val01 = rand((vec2(pos.x+1, pos.y)));
89 | float val11 = rand((vec2(pos.x+1, pos.y+1)));
90 |
91 | vec2 pos_fract = fract(pos);
92 |
93 | //2d linear interpolation
94 | float val_x0 = mix(val00, val01, pos_fract.x);
95 | float val_x1 = mix(val10, val11, pos_fract.x);
96 |
97 | float final_val = mix(val_x0, val_x1, pos_fract.y);
98 |
99 | return mix(max, min, final_val);
100 | }
101 |
--------------------------------------------------------------------------------
/tree/_trees/trunk_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 |
5 | in mat4 model_mat;
6 | // uniform mat4 model;
7 |
8 | uniform mat4 model;
9 | uniform mat4 view;
10 | uniform mat4 projection;
11 | uniform vec3 light_position;
12 | uniform vec4 clip_coord;
13 | uniform vec3 sun_dir;
14 | uniform vec3 sun_col;
15 | in vec3 normals;
16 | in vec2 uv;
17 |
18 | uniform mat4 shadow_matrix; //bias*P*V
19 |
20 | out vec3 frag_position;
21 | out vec3 frag_normal;
22 | out float red;
23 | out float green;
24 | out float blue;
25 | out vec2 tex_coord;
26 |
27 | out vec4 shadow_coord;
28 |
29 | float get_diffuse_strength(vec3 light_dir, vec3 normal){
30 | return clamp(dot(normal, light_dir), 0.0, 1.0);
31 | }
32 |
33 | void main(){
34 |
35 | mat4 global_model = model*model_mat; //model matrix for the tree + for each trunk piece
36 |
37 | gl_Position = projection*view*global_model*vec4(position, 1.0);
38 | frag_position = vec3(global_model*vec4(position, 1.0));
39 |
40 | mat3 normalMat = mat3(global_model);
41 | normalMat = transpose(inverse(normalMat));
42 |
43 | vec3 light_dir = normalize(light_position-vec3(global_model*vec4(position, 1.0)));
44 |
45 | vec3 normal_transformed = vec3(0.0);
46 | normal_transformed = normalize(normalMat*normals);
47 |
48 | float diffuse_light = 0.0;
49 | diffuse_light = dot(normal_transformed, light_dir);
50 | float diffuse_sun = 0.0;
51 | diffuse_sun = get_diffuse_strength(-sun_dir, normal_transformed);
52 |
53 | tex_coord = uv;
54 |
55 | shadow_coord = shadow_matrix * global_model*vec4(position, 1.0);
56 | frag_normal = normal_transformed;
57 | }
58 |
--------------------------------------------------------------------------------
/tree/glsl/cube_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 frag_surface_normal_color;
4 |
5 | uniform sampler2D shadow_buffer_tex;
6 |
7 | uniform mat4 model;
8 | uniform mat4 view;
9 | uniform mat4 projection;
10 |
11 | uniform vec3 light_position;
12 |
13 | in float red;
14 | in float green;
15 | in float blue;
16 | out vec4 color;
17 |
18 | in vec3 frag_position;
19 | in vec3 frag_normal;
20 | in vec4 shadow_coord;
21 |
22 | uniform uint window_width;
23 | uniform uint window_height;
24 | uniform uint shadow_mapping_effect;
25 |
26 | uniform vec3 shape_color;
27 |
28 | uniform uint shadow_buffer_tex_size;
29 |
30 | void main(){
31 |
32 | vec3 light_dir = normalize(light_position-frag_position);
33 | float diffuse_light = dot(frag_normal, light_dir);
34 |
35 | color = vec4(diffuse_light*shape_color, 1.0);
36 | }
37 |
--------------------------------------------------------------------------------
/tree/glsl/cube_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 | uniform vec3 light_position;
8 | uniform vec4 clip_coord;
9 | in vec3 surface_normal;
10 |
11 | uniform mat4 shadow_matrix; //bias*P*V
12 |
13 | out vec3 frag_surface_normal_color;
14 | out vec3 frag_position;
15 | out vec3 frag_normal;
16 | out float red;
17 | out float green;
18 | out float blue;
19 |
20 | out vec4 shadow_coord;
21 | out float gl_ClipDistance[1];
22 |
23 | void main(){
24 | // model = mat4(5);
25 | // model[3][3] = 1;
26 | gl_Position = projection*view*model*vec4(position, 1.0);
27 | //dont display anything under water, negative means outside clip plane
28 | gl_ClipDistance[0] = dot(model*vec4(position, 1.0), clip_coord);
29 | frag_position = vec3(model*vec4(position, 1.0));
30 |
31 | mat3 normalMat = mat3(model);
32 | normalMat = transpose(inverse(normalMat));
33 |
34 | vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
35 |
36 | vec3 normal_transformed = vec3(0.0);
37 | normal_transformed = normalize(normalMat*surface_normal);
38 |
39 | float diffuse_light = 0.0;
40 | diffuse_light = dot(normal_transformed, light_dir);
41 |
42 | float lum = 1.0*diffuse_light;
43 | lum = clamp(lum, 0.0, 1.0);
44 | frag_surface_normal_color = vec3(lum, lum, lum);
45 |
46 | shadow_coord = shadow_matrix * model*vec4(position, 1.0);
47 | frag_normal = surface_normal;
48 | }
49 |
--------------------------------------------------------------------------------
/tree/glsl/quad_screen_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/triangle/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME triangle)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(include_path "/usr/include/GL /usr/include/glm")
15 | set(lib_path "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${include_path})
18 | LINK_DIRECTORIES(${lib_path})
19 | add_executable(${PROJECT_NAME} main.cpp)
20 |
21 | #copy all glsl files to build folder
22 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
23 | foreach(glsl_file ${GLSL_FILES})
24 | configure_file(${glsl_file} . COPYONLY)
25 | endforeach(glsl_file)
26 |
27 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
28 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
29 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
30 |
--------------------------------------------------------------------------------
/triangle/glsl/fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in float red;
4 | in float green;
5 | in float blue;
6 | out vec3 color;
7 |
8 | void main(){
9 | color = vec3(red, green, blue);
10 | }
11 |
--------------------------------------------------------------------------------
/triangle/glsl/vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 vpoint;
4 | out float red;
5 | out float green;
6 | out float blue;
7 |
8 | void main(){
9 | gl_Position = vec4(vpoint, 1.0);
10 | red = green = blue = 0.0;
11 |
12 | if(gl_VertexID == 0){
13 | red = 1.0;
14 | }
15 | else if(gl_VertexID == 1){
16 | green = 1.0;
17 | }
18 | else{
19 | blue = 1.0;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/volumetric_clouds/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME volumetric_clouds)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Debug)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | find_package(Threads)
15 |
16 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
17 | set(LIB_PATH "/usr/lib")
18 |
19 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
20 | LINK_DIRECTORIES(${LIB_PATH})
21 |
22 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
23 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
24 |
25 | #copy all glsl files to build folder
26 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
27 |
28 | foreach(glsl_file ${GLSL_FILES})
29 | configure_file(${glsl_file} . COPYONLY)
30 | endforeach(glsl_file)
31 |
32 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
34 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
35 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
36 | target_link_libraries(${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT})
37 |
--------------------------------------------------------------------------------
/volumetric_clouds/README.md:
--------------------------------------------------------------------------------
1 | # Volumetric clouds
2 |
3 | 
4 |
5 | 
6 |
7 | Volumetric clouds using semi transparent particles and 3d noise generation.
8 |
9 | The particles are placed in a volume above the ground given the 3d noise generation.
10 | If the values in the noise are above a variable threshold the particle will be placed.
11 |
12 | The particles are 2d squares panes. To give even more depth, a 2d noise is used as a transparent mask
13 | on the particle, a random value is used to shift the position of the alpha mask on the 2d noise.
14 |
15 | Depth testing is deactivated during the particles drawing, to avoid problems with the transparency.
16 | This means that the particles have to be drawn in order of the furthest to the nearest to the camera.
17 | Sorting is done to know this order. Since the sorting is pretty costly but isn't necessary for all frames, it
18 | is done in a separated thread, to avoid lowering the framerate.
19 |
20 | Shading the clouds is done by integrating on the ray from the particle to the sun.
21 | The particle will be more or less dark depending if the ray interestects a lot of clouds (using the 3d noise).
22 |
23 | # Controls
24 | - WASD: moves the camera
25 | - IJKL: change camera view direction
26 | - MN: more or less clouds
27 | - X: midday sun
28 | - C: evening sun
29 |
--------------------------------------------------------------------------------
/volumetric_clouds/glsl/cloud_particles_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | uniform mat4 model;
4 | uniform mat4 view;
5 | uniform mat4 projection;
6 |
7 | uniform vec3 light_colour;
8 | uniform vec3 shadow_colour;
9 |
10 | uniform vec3 light_position;
11 | uniform sampler2D tex_noise_2d;
12 |
13 | in vec2 frag_uv;
14 | in float frag_colour;
15 | in float random;
16 | flat in uint frag_active;
17 |
18 | out vec4 color;
19 |
20 | void main(){
21 |
22 | if(frag_active == 0u){
23 | discard;
24 | }
25 |
26 | vec2 transf_frag_uv = (frag_uv-0.5)*2;
27 |
28 | float dist_to_centre = dot(transf_frag_uv, transf_frag_uv);
29 | float cloud = 1-dist_to_centre;
30 |
31 | // round particle
32 | if(dist_to_centre > 1){
33 | discard;
34 | }
35 |
36 | color = vec4(frag_colour, frag_colour, frag_colour, 0.5*cloud);
37 |
38 | //alpha transparency from a noise texture, at random position
39 | float alpha = (texture(tex_noise_2d, (frag_uv)*0.25+random*0.75).r+0.5)*(1-pow(dist_to_centre,2));
40 | // float alpha = 1;
41 |
42 | //if frag colour == 1 will take light_colour
43 | vec3 final_rgb = mix(shadow_colour, light_colour, frag_colour);
44 |
45 | color = vec4(final_rgb, alpha);
46 | }
47 |
--------------------------------------------------------------------------------
/volumetric_clouds/glsl/cloud_particles_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec2 uv;
5 | in vec3 pos_point;
6 | in vec2 life_age;
7 | in float particle_colour;
8 | in float particle_random;
9 | in uint particle_active;
10 | uniform mat4 model;
11 | uniform mat4 view;
12 | uniform mat4 projection;
13 | uniform vec3 light_position;
14 | uniform vec4 clip_coord;
15 |
16 | out vec2 frag_uv;
17 | out float frag_colour;
18 | out float random;
19 | flat out uint frag_active;
20 |
21 | void main(){
22 |
23 |
24 | frag_active = particle_active;
25 |
26 | //from http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/billboards/
27 | //to have billboards sprites
28 | vec3 CameraRight_worldspace = vec3(view[0][0], view[1][0], view[2][0]);
29 | vec3 CameraUp_worldspace = vec3(view[0][1], view[1][1], view[2][1]);
30 |
31 | float size = 24;
32 |
33 | vec3 transf_pos_point = vec3(model*vec4(pos_point, 1.0));
34 |
35 | vec3 vertexPosition_worldspace =
36 | transf_pos_point
37 | + CameraRight_worldspace * position.x * size
38 | + CameraUp_worldspace * position.z * size;
39 |
40 | gl_Position = projection*view*vec4(vertexPosition_worldspace, 1.0);
41 | random = particle_random;
42 | frag_uv = uv;
43 | frag_colour = particle_colour;
44 | }
45 |
--------------------------------------------------------------------------------
/volumetric_clouds/glsl/cube_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 frag_surface_normal_color;
4 |
5 | uniform sampler2D shadow_buffer_tex;
6 |
7 | uniform mat4 model;
8 | uniform mat4 view;
9 | uniform mat4 projection;
10 |
11 | uniform vec3 light_position;
12 | uniform vec3 sun_dir;
13 |
14 | in float red;
15 | in float green;
16 | in float blue;
17 | out vec4 color;
18 |
19 | in vec3 frag_position;
20 | in vec3 frag_normal;
21 | in vec4 shadow_coord;
22 |
23 | uniform uint window_width;
24 | uniform uint window_height;
25 | uniform uint shadow_mapping_effect;
26 |
27 | uniform vec3 shape_color;
28 |
29 | uniform uint shadow_buffer_tex_size;
30 |
31 | void main(){
32 |
33 | // vec3 light_dir = normalize(light_position-frag_position);
34 | vec3 light_dir = sun_dir;
35 | float diffuse_light = dot(frag_normal, light_dir);
36 |
37 | color = vec4(diffuse_light*shape_color, 1.0);
38 | }
39 |
--------------------------------------------------------------------------------
/volumetric_clouds/glsl/cube_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 | uniform vec3 light_position;
8 | uniform vec3 sun_dir;
9 | uniform vec4 clip_coord;
10 | in vec3 surface_normal;
11 |
12 | uniform mat4 shadow_matrix; //bias*P*V
13 |
14 | out vec3 frag_surface_normal_color;
15 | out vec3 frag_position;
16 | out vec3 frag_normal;
17 | out float red;
18 | out float green;
19 | out float blue;
20 |
21 | out vec4 shadow_coord;
22 | out float gl_ClipDistance[1];
23 |
24 | void main(){
25 | // model = mat4(5);
26 | // model[3][3] = 1;
27 | gl_Position = projection*view*model*vec4(position, 1.0);
28 | //dont display anything under water, negative means outside clip plane
29 | gl_ClipDistance[0] = dot(model*vec4(position, 1.0), clip_coord);
30 | frag_position = vec3(model*vec4(position, 1.0));
31 |
32 | mat3 normalMat = mat3(model);
33 | normalMat = transpose(inverse(normalMat));
34 |
35 | // vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
36 | vec3 light_dir = sun_dir;
37 |
38 | vec3 normal_transformed = vec3(0.0);
39 | normal_transformed = normalize(normalMat*surface_normal);
40 |
41 | float diffuse_light = 0.0;
42 | diffuse_light = dot(normal_transformed, light_dir);
43 |
44 | float lum = 1.0*diffuse_light;
45 | lum = clamp(lum, 0.0, 1.0);
46 | frag_surface_normal_color = vec3(lum, lum, lum);
47 |
48 | shadow_coord = shadow_matrix * model*vec4(position, 1.0);
49 | frag_normal = surface_normal;
50 | }
51 |
--------------------------------------------------------------------------------
/volumetric_clouds/glsl/quad_screen_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/volumetric_clouds/glsl/sphere_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 frag_surface_normal_color;
4 |
5 | in vec3 frag_normal_transformed;
6 | in float frag_spot_range;
7 | in float frag_spot_pow;
8 |
9 | uniform vec3 camera_position;
10 | uniform vec3 light_position;
11 | uniform vec3 sun_dir;
12 | uniform bool activate_spot;
13 |
14 | out vec4 color;
15 |
16 | void main(){
17 | vec3 light_dir = sun_dir;
18 | float diffuse_light = 0.0;
19 |
20 | diffuse_light = dot(frag_normal_transformed, light_dir);
21 |
22 | float lum = 0.8*diffuse_light;
23 |
24 | color = vec4(lum, lum, lum, 1.0);
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/volumetric_clouds/glsl/sphere_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec3 surface_normal;
5 | in vec3 vertex_normal;
6 | uniform vec3 light_position;
7 | uniform vec3 camera_position;
8 |
9 | uniform mat4 model;
10 | uniform mat4 view;
11 | uniform mat4 projection;
12 |
13 | out vec3 frag_normal_transformed;
14 |
15 | void main(){
16 | gl_Position = projection*view*model*vec4(position, 1.0);
17 |
18 | //model matrix for normals needs to be ((mat)⁻¹)^T
19 | mat3 normalMat = mat3(model);
20 | normalMat = transpose(inverse(normalMat));
21 |
22 | vec3 normal_transformed = normalize(normalMat*vertex_normal);
23 | normal_transformed = clamp(normal_transformed, 0.0, 1.0);
24 |
25 | frag_normal_transformed = normal_transformed;
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/volumetric_light/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME volumetric_light)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 |
26 | foreach(glsl_file ${GLSL_FILES})
27 | configure_file(${glsl_file} . COPYONLY)
28 | endforeach(glsl_file)
29 |
30 | #configure_file(${GLSL_FILES} . COPYONLY)
31 |
32 |
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
34 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
35 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
36 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
37 |
--------------------------------------------------------------------------------
/volumetric_light/README.md:
--------------------------------------------------------------------------------
1 | # Volumetric light
2 |
3 |  
4 |
5 | Extending the shadow map example to add some post processing volumetric light.
6 |
7 | Implementation inspired from: https://developer.nvidia.com/gpugems/gpugems3/part-ii-light-and-shadows/chapter-13-volumetric-light-scattering-post-process
8 |
9 | The implementation is using rays going away from the camera, until it has reached the depth of the scene (and thus we hit a displayed object).
10 | At each step, we will check if the 3d point is viewed from the light, using a depth buffer generated from the point of view of light. When applying the projection matrix to the 3d point on the ray, we can compare the depth of the point to the depth buffer and finding out if the point is visible from the light. If it is the case we increase the value of the pixel, thus giving the volumetric light effect.
11 |
12 | Generating rays from the 2d pixels of the camera quad is explained here: https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-generating-camera-rays/generating-camera-rays
13 |
14 | There should be some balancing between the number of steps in the ray, the distance between each steps and the resolution of the post-processing light to keep acceptable performance and good visual quality.
15 |
16 | # Controls
17 |
18 | - WASD: moves the camera
19 | - IJKL: change camera view direction
20 | - VBNM: Chose different positions of light (moving dynamic light and fixed)
21 | - ERTYUFG: Shadow map types
22 |
--------------------------------------------------------------------------------
/volumetric_light/glsl/cube_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 | uniform vec3 light_position;
8 | in vec3 surface_normal;
9 |
10 | uniform mat4 shadow_matrix; //bias*P*V
11 |
12 | out vec3 frag_surface_normal_color;
13 | out float red;
14 | out float green;
15 | out float blue;
16 |
17 | out vec4 shadow_coord;
18 |
19 | void main(){
20 | gl_Position = projection*view*model*vec4(position, 1.0);
21 | // gl_Position = projection*view*vec4(0,0,0, 1.0);
22 |
23 | mat3 normalMat = mat3(model);
24 | normalMat = transpose(inverse(normalMat));
25 |
26 | vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
27 |
28 | vec3 normal_transformed = vec3(0.0);
29 | normal_transformed = normalize(normalMat*surface_normal);
30 |
31 | float diffuse_light = 0.0;
32 | diffuse_light = dot(normal_transformed, light_dir);
33 |
34 | float lum = 1.0*diffuse_light;
35 | lum = clamp(lum, 0.0, 1.0);
36 | frag_surface_normal_color = vec3(lum, lum, lum);
37 |
38 | shadow_coord = shadow_matrix * model*vec4(position, 1.0);
39 | }
40 |
41 | void main_colors_const(){
42 | gl_Position = projection*view*model*vec4(position, 1.0);
43 | red = green = blue = 0.0;
44 |
45 | if(gl_VertexID == 0){
46 | red = 1.0;
47 | }
48 | else if(gl_VertexID == 1){
49 | green = 1.0;
50 | }
51 | else if(gl_VertexID == 2){
52 | blue = 1.0;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/volumetric_light/glsl/quad_screen_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | uniform sampler2D tex;
3 | uniform sampler2D depth_tex;
4 | uniform sampler2D shadow_map_depth_tex;
5 | uniform float tex_width;
6 | uniform float tex_height;
7 | in vec2 uv;
8 | out vec3 color;
9 |
10 | uniform uint effect_select;
11 | uniform float fov_angle;
12 |
13 | uniform mat4 camera_transform_matrix;
14 | uniform mat4 proj_transform_matrix;
15 | //contains projection + camera transf
16 | uniform mat4 shadow_map_transform_mat;
17 |
18 | void main() {
19 | vec3 color_out = vec3(0.5, 1.0, 0.0);
20 |
21 | //method to find world coord from camera pixel coords: https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-generating-camera-rays/generating-camera-rays
22 | float aspect_ratio = tex_width/tex_height;
23 |
24 | float point_x = (2*uv.x-1)*aspect_ratio*tan(fov_angle/2);
25 | float point_y = (2*uv.y-1)*tan(fov_angle/2);
26 |
27 | vec3 vector_pixel = vec3(point_x, point_y, -1);
28 |
29 | //find world pos of the pixel and the camera origin, then we have the vector of the ray in world
30 | vec3 vector_pixel_world = vec3(inverse(camera_transform_matrix)*vec4(vector_pixel, 1.0));
31 | vec3 vector_origin_world = vec3(inverse(camera_transform_matrix)*vec4(0.0, 0.0, 0.0, 1.0));
32 | vec3 vector_dir = vector_pixel_world-vector_origin_world;
33 |
34 | if(effect_select == 0u){ //normal
35 | color_out = texture(tex, uv).rgb;
36 | vec3 cur_vec = vector_pixel_world;
37 |
38 | mat4 PV_mat = proj_transform_matrix*camera_transform_matrix;
39 |
40 | //this will increase resolution of volumetric light but be computationally heavy
41 | int max_iterations = 300;
42 |
43 | for(int i = 0; i < max_iterations; i++){
44 | vec4 end_vec = PV_mat*vec4(cur_vec, 1.0);
45 |
46 | //find corresponding pixel of the 3d world point on the shadow depth map
47 | vec4 shadow_coord_tex = shadow_map_transform_mat*vec4(cur_vec, 1.0);
48 |
49 | float fog = 0;
50 | float fog_altitude = 5 ;
51 |
52 | //have some fog effect at low altitude
53 | float fog_calc = 1;
54 | if(cur_vec.y > fog_altitude-1 && cur_vec.y < fog_altitude){
55 | fog_calc = fog_altitude-cur_vec.y;
56 | }
57 | else if(cur_vec.y >= fog_altitude){
58 | fog_calc = 0;
59 | }
60 |
61 | if(fog_calc > 0){
62 | //bias for the shadow map, helps against aliasing
63 | float BIAS = 0.002;
64 | //bias for the camera depth, avoid seeing lights "through" the objects
65 | float BIAS_DEPTH = 0.02;
66 | //check that the end of the vector is not further than the depth map (behind an object)
67 | if(end_vec.z/end_vec.w+BIAS_DEPTH < texture(depth_tex, uv).r){
68 | //check that the ray from the end vector to the light has no obstruction with the help of the shadow depth map
69 | if ( texture( shadow_map_depth_tex, (shadow_coord_tex.xy/shadow_coord_tex.w) ).x > shadow_coord_tex.z/shadow_coord_tex.w-BIAS){
70 | //if ray not obstructed from cam to end_vec and then to light, then add a bit of colour (vol light)
71 | color_out += fog_calc*vec3(0.016);
72 | }
73 | }
74 | }
75 | //increment for the ray tracing
76 | cur_vec = cur_vec + 0.15*vector_dir;
77 | }
78 | }
79 |
80 | color = color_out;
81 | }
82 |
--------------------------------------------------------------------------------
/volumetric_light/glsl/quad_screen_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/volumetric_light/glsl/sphere_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec3 surface_normal;
5 | in vec3 vertex_normal;
6 | uniform vec3 light_position;
7 | uniform vec3 camera_position;
8 | uniform uint lighting_mode;
9 | uniform bool activate_specular;
10 | uniform vec3 spot_direction;
11 | uniform bool activate_spot;
12 |
13 | uniform mat4 shadow_matrix; //bias*P*V
14 |
15 | uniform mat4 model;
16 | uniform mat4 view;
17 | uniform mat4 projection;
18 |
19 | out vec3 frag_position;
20 | out vec3 frag_surface_normal_color;
21 | out vec3 frag_normal_transformed;
22 | out float frag_spot_range;
23 | out float frag_spot_pow;
24 |
25 | out vec4 shadow_coord;
26 |
27 | const float spot_range = 0.98; //hhow wide the spot should be (in term of dot(light_dir, -spot_dir))
28 | const float spot_pow = 128;
29 |
30 | void main(){
31 | gl_Position = projection*view*model*vec4(position, 1.0);
32 | // gl_Position = projection*view*vec4(0,0,0, 1.0);
33 |
34 | mat3 normalMat = mat3(model);
35 | normalMat = transpose(inverse(normalMat));
36 |
37 | vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
38 | vec3 view_dir = normalize(camera_position-vec3(model*vec4(position, 1.0)));
39 |
40 | vec3 normal_transformed = vec3(0.0);
41 | float diffuse_light = 0.0;
42 | float spec_light = 0.0;
43 |
44 | if(lighting_mode == 0u){ // per surface
45 | normal_transformed = normalize(normalMat*surface_normal);
46 | }
47 | else if(lighting_mode == 1u){
48 | normal_transformed = normalize(normalMat*vertex_normal);
49 | }
50 | else{
51 | normal_transformed = normalize(normalMat*vertex_normal);
52 | }
53 |
54 | //normal_transformed = clamp(normal_transformed, 0.0, 1.0);
55 |
56 | diffuse_light = dot(normal_transformed, light_dir);
57 |
58 | if(activate_specular == true){
59 | vec3 reflexion = 2*normal_transformed*dot(normal_transformed, light_dir)-light_dir;
60 | reflexion = clamp(reflexion, 0.0, 1.0);
61 | spec_light = pow(dot(reflexion, view_dir), 64);
62 | spec_light = clamp(spec_light, 0.0, 1.0);
63 | }
64 |
65 | float spot_brightness = 1.0;
66 |
67 | if(activate_spot == true){
68 | vec3 spot_direction_norm = normalize(spot_direction);
69 | float cos_spot = dot(-spot_direction_norm, light_dir);
70 |
71 | if(cos_spot > spot_range){
72 | spot_brightness = 1.0;
73 | }
74 | else{
75 | spot_brightness = pow(cos_spot+(1.0-spot_range), spot_pow);
76 | }
77 | }
78 |
79 | float lum = 0.8*diffuse_light+0.8*spec_light;
80 | lum = lum*spot_brightness;
81 | lum = clamp(lum, 0.0, 1.0);
82 |
83 | shadow_coord = shadow_matrix * model*vec4(position, 1.0);
84 |
85 | frag_normal_transformed = normal_transformed;
86 | frag_position = vec3(model*vec4(position, 1.0));
87 | frag_surface_normal_color = vec3(lum, lum, lum);
88 | frag_spot_range = spot_range;
89 | frag_spot_pow = spot_pow;
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/water/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | set(PROJECT_NAME water)
4 |
5 | project(${PROJECT_NAME})
6 |
7 | set (CMAKE_BUILD_TYPE Release)
8 |
9 | set (CMAKE_CXX_STANDARD 11)
10 | set (CMAKE_CXX_FLAGS "-Wall -Wextra")
11 | set (CMAKE_CXX_FLAGS_DEBUG "-g")
12 | set (CMAKE_CXX_FLAGS_RELEASE "-O3")
13 |
14 | set(INCLUDE_PATH "/usr/include/GL" "/usr/include/glm" "${CMAKE_CURRENT_SOURCE_DIR}/../common")
15 | set(LIB_PATH "/usr/lib")
16 |
17 | INCLUDE_DIRECTORIES(${INCLUDE_PATH})
18 | LINK_DIRECTORIES(${LIB_PATH})
19 |
20 | file(GLOB SOURCE_FILES "*.cpp" "*.h")
21 | add_executable(${PROJECT_NAME} ${SOURCE_FILES})
22 |
23 | #copy all glsl files to build folder
24 | file(GLOB_RECURSE GLSL_FILES "*.glsl")
25 |
26 | foreach(glsl_file ${GLSL_FILES})
27 | configure_file(${glsl_file} . COPYONLY)
28 | endforeach(glsl_file)
29 |
30 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GLEW)
31 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} glfw)
32 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} GL)
33 | TARGET_LINK_LIBRARIES(${PROJECT_NAME} IL)
34 |
--------------------------------------------------------------------------------
/water/README.md:
--------------------------------------------------------------------------------
1 | # Water
2 |
3 |  
4 |
5 | Water is simulated as a plane on which shaders use various framebuffers to display refractions and reflexions.
6 |
7 | Waves are done with addition of sine waves, normals are calculated for each pixel of the water in the pixel shader
8 | in order to display the specular lighting.
9 |
10 | Reflexion is done with a flipped camera, which displays the scene upside down in a framebuffer, while discarding everything underwater.
11 | When displaying the water, the reflexion is displayed as a texture and ripples are created by shifting the texture lookup by the amount of wave
12 |
13 | Refraction is done the same way as the reflexion, but the camera isn't flipped. A framebuffer containing the objects underwater is displayed
14 | on the water plane and ripples displayed in a similar manner.
15 |
16 | Whether the reflexion or the refraction framebuffer will be displayed depends on the angle formed between the camera and the water.
17 | If the angle is near 0 (camera on the surface of the water), only reflexion will be displayed, if the angle is 90 (camera looking down),
18 | only stuff underwater will be shown, this is a very rough estimation on how water behaves.
19 |
20 | A depth buffer is also used to find if an object is more or less underwater, and alter its colour depending on the depth, but this wasn't very successful.
21 |
22 | The water display is pretty costly, needing multiple drawing steps in buffers, a simplification could be to use only the reflexion framebuffer and the
23 | result would be good enough.
24 |
25 | # Controls
26 | - WASD: moves the camera
27 | - IJKL: change camera view direction
28 | - ERTY: various water effects (more or less waves)
29 | - VBNM: change light position
30 |
--------------------------------------------------------------------------------
/water/_water/water_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec2 uv;
5 | uniform mat4 model;
6 | uniform mat4 view;
7 | uniform mat4 projection;
8 | uniform vec3 light_position;
9 |
10 | uniform mat4 shadow_matrix; //bias*P*V
11 |
12 | in vec3 surface_normal;
13 |
14 | out vec3 frag_position;
15 | out vec3 frag_normal_transformed;
16 | out vec2 uv_frag;
17 | out float red;
18 | out float green;
19 | out float blue;
20 |
21 | out vec4 shadow_coord;
22 |
23 | void main(){
24 | gl_Position = projection*view*model*vec4(position, 1.0);
25 |
26 | mat3 normalMat = mat3(model);
27 | normalMat = transpose(inverse(normalMat));
28 |
29 | vec3 normal_transformed = vec3(0.0);
30 | normal_transformed = normalize(normalMat*surface_normal);
31 |
32 | frag_normal_transformed = normal_transformed;
33 | frag_position = vec3(model*vec4(position, 1.0));
34 |
35 | shadow_coord = shadow_matrix * model*vec4(position, 1.0);
36 |
37 | uv_frag = uv;
38 | }
39 |
--------------------------------------------------------------------------------
/water/glsl/cube_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 frag_surface_normal_color;
4 |
5 | uniform sampler2D shadow_buffer_tex;
6 |
7 | uniform mat4 model;
8 | uniform mat4 view;
9 | uniform mat4 projection;
10 |
11 | uniform vec3 light_position;
12 |
13 | in float red;
14 | in float green;
15 | in float blue;
16 | out vec4 color;
17 |
18 | in vec3 frag_position;
19 | in vec3 frag_normal;
20 | in vec4 shadow_coord;
21 |
22 | uniform uint window_width;
23 | uniform uint window_height;
24 | uniform uint shadow_mapping_effect;
25 |
26 | uniform vec3 shape_color;
27 |
28 | uniform uint shadow_buffer_tex_size;
29 |
30 | void main(){
31 |
32 | vec3 light_dir = normalize(light_position-frag_position);
33 | float diffuse_light = dot(frag_normal, light_dir);
34 |
35 | color = vec4(diffuse_light*shape_color, 1.0);
36 | }
37 |
--------------------------------------------------------------------------------
/water/glsl/cube_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | uniform mat4 model;
5 | uniform mat4 view;
6 | uniform mat4 projection;
7 | uniform vec3 light_position;
8 | uniform vec4 clip_coord;
9 | in vec3 surface_normal;
10 |
11 | uniform mat4 shadow_matrix; //bias*P*V
12 |
13 | out vec3 frag_surface_normal_color;
14 | out vec3 frag_position;
15 | out vec3 frag_normal;
16 | out float red;
17 | out float green;
18 | out float blue;
19 |
20 | out vec4 shadow_coord;
21 | out float gl_ClipDistance[1];
22 |
23 | void main(){
24 | gl_Position = projection*view*model*vec4(position, 1.0);
25 | //dont display anything under water, negative means outside clip plane
26 | gl_ClipDistance[0] = dot(model*vec4(position, 1.0), clip_coord);
27 | frag_position = vec3(model*vec4(position, 1.0));
28 |
29 | mat3 normalMat = mat3(model);
30 | normalMat = transpose(inverse(normalMat));
31 |
32 | vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
33 |
34 | vec3 normal_transformed = vec3(0.0);
35 | normal_transformed = normalize(normalMat*surface_normal);
36 |
37 | float diffuse_light = 0.0;
38 | diffuse_light = dot(normal_transformed, light_dir);
39 |
40 | float lum = 1.0*diffuse_light;
41 | lum = clamp(lum, 0.0, 1.0);
42 | frag_surface_normal_color = vec3(lum, lum, lum);
43 |
44 | shadow_coord = shadow_matrix * model*vec4(position, 1.0);
45 | frag_normal = surface_normal;
46 | }
47 |
--------------------------------------------------------------------------------
/water/glsl/quad_screen_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 | in vec3 vpoint;
3 | in vec2 vtexcoord;
4 | out vec2 uv;
5 |
6 | void main() {
7 | gl_Position = vec4(vpoint, 1.0);
8 | uv = vtexcoord;
9 | }
10 |
--------------------------------------------------------------------------------
/water/glsl/sphere_fshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 frag_surface_normal_color;
4 |
5 | in vec3 frag_normal_transformed;
6 | in vec3 frag_position;
7 | in float frag_spot_range;
8 | in float frag_spot_pow;
9 |
10 | uniform sampler2D shadow_buffer_tex;
11 |
12 | uniform vec3 camera_position;
13 | uniform vec3 light_position;
14 | uniform uint lighting_mode;
15 | uniform bool activate_specular;
16 | uniform vec3 spot_direction;
17 | uniform bool activate_spot;
18 |
19 | out vec4 color;
20 |
21 | in vec4 shadow_coord;
22 |
23 | uniform uint shadow_mapping_effect;
24 | uniform uint shadow_buffer_tex_size;
25 |
26 | void main(){
27 | if(lighting_mode == 0u || lighting_mode == 1u){ //surface or vertex shading
28 | color = vec4(frag_surface_normal_color, 1.0);
29 | }
30 | else{
31 | vec3 light_dir = normalize(light_position-frag_position);
32 | float diffuse_light = 0.0;
33 | float spec_light = 0.0;
34 |
35 | if(activate_specular == true){
36 | vec3 reflexion = 2*frag_normal_transformed*dot(frag_normal_transformed, light_dir)-light_dir;
37 | reflexion = normalize(reflexion);
38 | vec3 view_dir = normalize(camera_position-frag_position);
39 |
40 | spec_light = pow(max(dot(reflexion, view_dir), 0.0), 128);
41 | spec_light = clamp(spec_light, 0.0, 1.0);
42 | }
43 |
44 | diffuse_light = dot(frag_normal_transformed, light_dir);
45 |
46 | float lum = 0.8*diffuse_light+spec_light;
47 | lum = lum;
48 |
49 | color = vec4(lum, lum, lum, 1.0);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/water/glsl/sphere_vshader.glsl:
--------------------------------------------------------------------------------
1 | #version 330 core
2 |
3 | in vec3 position;
4 | in vec3 surface_normal;
5 | in vec3 vertex_normal;
6 | uniform vec3 light_position;
7 | uniform vec3 camera_position;
8 | uniform vec4 clip_coord;
9 | uniform uint lighting_mode;
10 | uniform bool activate_specular;
11 | uniform vec3 spot_direction;
12 | uniform bool activate_spot;
13 |
14 | uniform mat4 shadow_matrix; //bias*P*V
15 |
16 | uniform mat4 model;
17 | uniform mat4 view;
18 | uniform mat4 projection;
19 |
20 | out vec3 frag_position;
21 | out vec3 frag_surface_normal_color;
22 | out vec3 frag_normal_transformed;
23 | out float frag_spot_range;
24 | out float frag_spot_pow;
25 |
26 | out vec4 shadow_coord;
27 |
28 | const float spot_range = 0.98; //hhow wide the spot should be (in term of dot(light_dir, -spot_dir))
29 | const float spot_pow = 128;
30 |
31 | void main(){
32 | gl_Position = projection*view*model*vec4(position, 1.0);
33 | gl_ClipDistance[0] = dot(model*vec4(position, 1.0), clip_coord);
34 |
35 | mat3 normalMat = mat3(model);
36 | normalMat = transpose(inverse(normalMat));
37 |
38 | vec3 light_dir = normalize(light_position-vec3(model*vec4(position, 1.0)));
39 | vec3 view_dir = normalize(camera_position-vec3(model*vec4(position, 1.0)));
40 |
41 | vec3 normal_transformed = vec3(0.0);
42 | float diffuse_light = 0.0;
43 | float spec_light = 0.0;
44 |
45 | if(lighting_mode == 0u){ // per surface
46 | normal_transformed = normalize(normalMat*surface_normal);
47 | }
48 | else if(lighting_mode == 1u){
49 | normal_transformed = normalize(normalMat*vertex_normal);
50 | }
51 | else{
52 | normal_transformed = normalize(normalMat*vertex_normal);
53 | }
54 |
55 | //normal_transformed = clamp(normal_transformed, 0.0, 1.0);
56 |
57 | diffuse_light = dot(normal_transformed, light_dir);
58 |
59 | if(activate_specular == true){
60 | vec3 reflexion = 2*normal_transformed*dot(normal_transformed, light_dir)-light_dir;
61 | reflexion = clamp(reflexion, 0.0, 1.0);
62 | spec_light = pow(dot(reflexion, view_dir), 64);
63 | spec_light = clamp(spec_light, 0.0, 1.0);
64 | }
65 |
66 | float spot_brightness = 1.0;
67 |
68 | if(activate_spot == true){
69 | vec3 spot_direction_norm = normalize(spot_direction);
70 | float cos_spot = dot(-spot_direction_norm, light_dir);
71 |
72 | if(cos_spot > spot_range){
73 | spot_brightness = 1.0;
74 | }
75 | else{
76 | spot_brightness = pow(cos_spot+(1.0-spot_range), spot_pow);
77 | }
78 | }
79 |
80 | float lum = 0.8*diffuse_light+0.8*spec_light;
81 | lum = lum*spot_brightness;
82 | lum = clamp(lum, 0.0, 1.0);
83 |
84 | shadow_coord = shadow_matrix * model*vec4(position, 1.0);
85 |
86 | frag_normal_transformed = normal_transformed;
87 | frag_position = vec3(model*vec4(position, 1.0));
88 | frag_surface_normal_color = vec3(lum, lum, lum);
89 | frag_spot_range = spot_range;
90 | frag_spot_pow = spot_pow;
91 |
92 | }
93 |
--------------------------------------------------------------------------------