├── .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 | ![screenshot1](../screenshots/ambient_occlusion.gif) 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 | ![screenshot](../screenshots/atmosphere_1.png) ![screenshot](../screenshots/atmosphere_2.png) 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 | ![screenshot1](../screenshots/bumpmapping_1.png) ![screenshot1](../screenshots/bumpmapping_2.png) 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 | ![screenshot1](../screenshots/framebuffer_1.png) ![screenshot1](../screenshots/framebuffer_2.png) 4 | ![screenshot1](../screenshots/framebuffer_3.png) 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 | ![screenshot1](../screenshots/grass_1.png) 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 | ![screenshot1](../screenshots/lod_terrain_1.png) ![screenshot2](../screenshots/lod_terrain_2.png) 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 | ![screenshot](../screenshots/particles_example.png) 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 | ![screenshot1](../screenshots/shadow_mapping_1.png) ![screenshot2](../screenshots/shadow_mapping_2.png) 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 | ![screenshot1](../screenshots/sky_1.png) ![screenshot2](../screenshots/sky_2.png) 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 | ![screenshot1](../screenshots/sphere_light_1.png) ![screenshot2](../screenshots/sphere_light_2.png) 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 | ![screenshot1](../screenshots/terrain_camera_1.png) ![screenshot2](../screenshots/terrain_camera_2.png) 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 | ![example](../screenshots/tessellation.png) 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 | | ![nearest](../screenshots/texfiltering_nearest.png) | ![bilinear](../screenshots/texfiltering_bilinear.png) | 8 | 9 | | GL_NEAREST_MIPMAP_LINEAR | Anisotropic 8.0f | 10 | | --------- | ---------- | 11 | | ![trilinear](../screenshots/texfiltering_trilinear.png) | ![anisotropic](../screenshots/texfiltering_anisotropic.png) | 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 | ![screenshot1](../screenshots/texture_plane_1.png) ![screenshot2](../screenshots/texture_plane_2.png) 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 | ![screenshot](../screenshots/tree_1.png) ![screenshot](../screenshots/tree_2.png) 13 | 14 | ![screenshot](../screenshots/tree_3.png) ![screenshot](../screenshots/tree_4.png) 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 | ![screenshot](../screenshots/clouds_1.png) 4 | 5 | ![screenshot](../screenshots/clouds_2.png) 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 | ![screenshot1](../screenshots/volumetric_light_1.png) ![screenshot2](../screenshots/volumetric_light_2.png) 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 | ![screenshot1](../screenshots/water_1.png) ![screenshot2](../screenshots/water_2.png) 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 | --------------------------------------------------------------------------------