├── AdQSM-V1.0.exe ├── AdQSM-V1.5.exe ├── AdQSM-V1.6.1.exe ├── AdQSM-V1.7.5..exe ├── AdQSM-V1.7.exe ├── Introduction.pdf ├── README.md ├── gmp-10.dll ├── msvcp140.dll ├── resource └── shaders │ ├── lines_color.frag │ ├── lines_color.vert │ ├── points_color.frag │ ├── points_color.vert │ ├── shadow │ ├── shadow_generate.frag │ ├── shadow_generate.vert │ ├── shadow_rendering.frag │ ├── shadow_rendering.vert │ ├── soft_shadow_generate.frag │ ├── soft_shadow_generate.vert │ ├── soft_shadow_rendering.frag │ └── soft_shadow_rendering.vert │ ├── surface_color.frag │ └── surface_color.vert ├── vcruntime140.dll └── vcruntime140_1.dll /AdQSM-V1.0.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuangpengFan/AdQSM/3c99e8e4480c6e4f82a2d1866b2c7dc27ec0cfd8/AdQSM-V1.0.exe -------------------------------------------------------------------------------- /AdQSM-V1.5.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuangpengFan/AdQSM/3c99e8e4480c6e4f82a2d1866b2c7dc27ec0cfd8/AdQSM-V1.5.exe -------------------------------------------------------------------------------- /AdQSM-V1.6.1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuangpengFan/AdQSM/3c99e8e4480c6e4f82a2d1866b2c7dc27ec0cfd8/AdQSM-V1.6.1.exe -------------------------------------------------------------------------------- /AdQSM-V1.7.5..exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuangpengFan/AdQSM/3c99e8e4480c6e4f82a2d1866b2c7dc27ec0cfd8/AdQSM-V1.7.5..exe -------------------------------------------------------------------------------- /AdQSM-V1.7.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuangpengFan/AdQSM/3c99e8e4480c6e4f82a2d1866b2c7dc27ec0cfd8/AdQSM-V1.7.exe -------------------------------------------------------------------------------- /Introduction.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuangpengFan/AdQSM/3c99e8e4480c6e4f82a2d1866b2c7dc27ec0cfd8/Introduction.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AdQSM 2 | AdQSM is a new tree quantitative structure model (QSM) that can reconstruct the 3D branch geometry of individual tree from Terrestrial Laser Scanner (TLS) point clouds. Many attributes of the trunk or branch can also be quantitatively calculated (as shown in the "Introduction.pdf"). For example, tree volume (trunk and branch), DBH and tree height parameters can be extracted directly. It allows point clouds collected by different sensors to serve as input point clouds. In addition to TLS, UAV-based Laser Scanner, Mobile Laser Scanner, SLAM and even Photogrammetry are also included under the premise of appropriate point cloud density. 3 | At present, AdQSM is attracting more and more attention. Due to the need to further test and improve AdQSM, we provided AdQSM (Test Version) to worldwide as an open tool with an end-user interface. In order to facilitate the use of AdQSM, we released the software (test version) that runs on Windows and provided part of the tree parameter quantitative calculation function. Now, you can download, install, and quickly display your modeling results for free. 4 | 5 | … … 6 | 7 | 1. The current test version of the software can support the tree point cloud in (.xyz) format 8 | 9 | 2. There are two important parameters (Height_Segmentation(HS) and Clound Parameter (CP)) in the process of modeling. HS represents the height of each segment of the point cloud, and CP represents the extraction rate of the point cloud. The default values are 0.50 and 0.003, respectively. According to the existing experimental results, we recommend that people set the value of CP as 0.003 (the default value) when rebuilding the point cloud of a single tree. 10 | We recommend setting different values of HS for multiple reconstruction (e.g. 0.5, 0.6, 0.7, 0.8, 0.9, 1.0) and calculating the average value of each parameter as the final tree reconstruction result. 11 | According to our test results, we do not recommend to change the value of “Cloud Parameter” frequently (except in case of non modeling, large deviation, etc.) 12 | 13 | 14 | 15 | 16 | 3. After setting the parameter values of HS and CP, click "Reconstruct" and the modeling result data will be saved in "treesparams.csv", "treesparams.txt" and "branchinfo.txt" under the installation path. 17 | 18 | 19 | The following paper implements AdQSM. If you use AdQSM or any part of it, we would appreciate your acknowledgement and citation of our paper. 20 | 21 | ```bibtex 22 | @article{fan2020adqsm, 23 | title={AdQSM: A New Method for Estimating Above-Ground Biomass from TLS Point Clouds}, 24 | author={Fan, Guangpeng and Nan, Liangliang and Dong, Yanqi and Su, Xiaohui and Chen, Feixiang}, 25 | journal={Remote Sensing}, 26 | volume={12}, 27 | number={18}, 28 | pages={3089}, 29 | year={2020}, 30 | publisher={Multidisciplinary Digital Publishing Institute} 31 | } 32 | ``` 33 | 34 | At present, only 29 destructive sampled trees have tested the accuracy of adqsm in calculating branch volume and trunk volume. Therefore, in the current open source version, we can not guarantee that AdQSM has enough accuracy and stability. 35 | 36 | *The right of interpretation of AdQSM belongs to its author and R&D team. To further improve AdQSM, we welcome any invitation for collaboration and test feedback from those who need AdQSM research. 37 | -------------------------------------------------------------------------------- /gmp-10.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuangpengFan/AdQSM/3c99e8e4480c6e4f82a2d1866b2c7dc27ec0cfd8/gmp-10.dll -------------------------------------------------------------------------------- /msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuangpengFan/AdQSM/3c99e8e4480c6e4f82a2d1866b2c7dc27ec0cfd8/msvcp140.dll -------------------------------------------------------------------------------- /resource/shaders/lines_color.frag: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | in vec3 vOutColor; 4 | out vec4 outputF; 5 | 6 | void main() 7 | { 8 | outputF = vec4(vOutColor, 1.0); 9 | } 10 | -------------------------------------------------------------------------------- /resource/shaders/lines_color.vert: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | in vec3 vtx_position; // point position 4 | in vec3 vtx_color; // point color 5 | 6 | uniform mat4 MVP; 7 | uniform vec3 default_color = vec3(0.0f, 0.0f, 0.0f); 8 | uniform bool per_vertex_color = false; 9 | 10 | out vec3 vOutColor; 11 | 12 | void main() 13 | { 14 | gl_Position = MVP * vec4(vtx_position, 1.0); 15 | 16 | if (per_vertex_color) 17 | vOutColor = vtx_color; 18 | else 19 | vOutColor = default_color; 20 | } 21 | -------------------------------------------------------------------------------- /resource/shaders/points_color.frag: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | uniform vec3 wLightPos; 4 | uniform vec3 wCamPos; 5 | uniform vec3 ambient = vec3(0.05f, 0.05f, 0.05f); 6 | uniform vec3 specular = vec3(0.4f, 0.4f, 0.4f); 7 | uniform float shininess = 64.0f; 8 | uniform bool lighting = true; 9 | 10 | // SSAO 11 | uniform sampler2D ssaoTexture; 12 | uniform bool ssaoEnabled = false; 13 | 14 | in vec3 vsPosition; 15 | in vec3 vsColor; 16 | in vec3 vsNormal; 17 | 18 | out vec4 outputF; 19 | 20 | void main(void) { 21 | vec3 view_dir = normalize(wCamPos - vsPosition); // compute view direction and normalize it 22 | vec3 normal = vsNormal; 23 | vec3 color = vsColor; 24 | if (lighting) { 25 | vec3 light_dir = normalize(wLightPos); 26 | float df = max(dot(light_dir, normal), 0); 27 | float sf = 0.0; // specular factor 28 | if (df > 0.0) { // if the vertex is lit compute the specular color 29 | vec3 half_vector = normalize(light_dir + view_dir); // compute the half vector 30 | sf = max(dot(half_vector, normal), 0.0); 31 | sf = pow(sf, shininess); 32 | } 33 | 34 | color = color * df + specular * sf + ambient; 35 | if (ssaoEnabled) { 36 | vec2 texCoord = gl_FragCoord.xy / textureSize(ssaoTexture, 0); 37 | float coeff = texture(ssaoTexture, texCoord).r; 38 | color = color * coeff; 39 | } 40 | } 41 | else 42 | color = color + ambient; 43 | 44 | outputF = vec4(color, 1.0f); 45 | } 46 | -------------------------------------------------------------------------------- /resource/shaders/points_color.vert: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | in vec3 vtx_position; // point position 4 | in vec3 vtx_color; // point color 5 | in vec3 vtx_normal;// point normal 6 | 7 | uniform mat4 MVP; 8 | uniform vec3 default_color = vec3(0.0f, 0.0f, 1.0f); 9 | uniform bool per_vertex_color = false; 10 | 11 | // the data to be sent to the fragment shader 12 | out vec3 vsPosition; 13 | out vec3 vsColor; 14 | out vec3 vsNormal; 15 | 16 | void main(void) { 17 | vsPosition = vtx_position; 18 | vsNormal = vtx_normal; 19 | vsColor = default_color; 20 | if (per_vertex_color) 21 | vsColor = vtx_color; 22 | gl_Position = MVP * vec4(vtx_position, 1.0); 23 | } 24 | -------------------------------------------------------------------------------- /resource/shaders/shadow/shadow_generate.frag: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | void main(void) { 4 | } 5 | -------------------------------------------------------------------------------- /resource/shaders/shadow/shadow_generate.vert: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | in vec3 vtx_position; // vertex position 4 | 5 | uniform mat4 MVP; 6 | 7 | void main() { 8 | gl_Position = MVP * vec4(vtx_position, 1.0); 9 | } 10 | -------------------------------------------------------------------------------- /resource/shaders/shadow/shadow_rendering.frag: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | uniform vec3 wLightPos; 4 | uniform vec3 wCamPos; 5 | uniform vec3 ambient = vec3(0.05f, 0.05f, 0.05f); 6 | uniform vec3 specular = vec3(0.4f, 0.4f, 0.4f); 7 | uniform float shininess = 64.0f; 8 | 9 | uniform bool is_background = false; 10 | 11 | uniform sampler2DShadow shadowMap; 12 | uniform float darkness; 13 | 14 | in Data{ 15 | vec3 color; 16 | vec3 normal; 17 | vec3 position; 18 | vec4 shadowCoord; 19 | } DataIn; 20 | 21 | 22 | out vec4 FragColor; // Ouput data 23 | 24 | 25 | vec3 shade(vec3 worldPos) 26 | { 27 | if (is_background) 28 | return DataIn.color; 29 | 30 | else { 31 | vec3 normal = normalize(DataIn.normal); 32 | 33 | vec3 view_dir = normalize(wCamPos - DataIn.position); 34 | vec3 light_dir = normalize(wLightPos); 35 | float df = abs(dot(light_dir, normal)); 36 | 37 | vec3 half_vector = normalize(light_dir + view_dir); // compute the half vector 38 | float sf = abs(dot(half_vector, normal)); 39 | sf = pow(sf, shininess); 40 | 41 | vec3 color = DataIn.color; 42 | color = color * df + specular * sf; 43 | return color; 44 | } 45 | } 46 | 47 | 48 | 49 | void main(void) { 50 | vec3 color = shade(DataIn.position); 51 | 52 | vec3 coords = DataIn.shadowCoord.xyz / DataIn.shadowCoord.w; 53 | // to avoid shadow acne: See: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/ 54 | coords.z -= 0.005; 55 | float visibility = texture(shadowMap, coords); 56 | 57 | // give control over darkness; 58 | visibility = (visibility < 0.9) ? (1.0 - darkness) : 1.0f; 59 | 60 | if (is_background) 61 | FragColor = vec4(color * visibility, 1.0); 62 | else 63 | FragColor = vec4(color * visibility + ambient, 1.0); 64 | } 65 | 66 | -------------------------------------------------------------------------------- /resource/shaders/shadow/shadow_rendering.vert: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | in vec3 vtx_position; // vertex position 4 | in vec3 vtx_normal; // vertex normal 5 | in vec3 vtx_color; // vertex color 6 | 7 | uniform mat4 MVP; 8 | uniform mat4 SHADOW; 9 | 10 | uniform vec3 default_color = vec3(0.3, 0.3, 0.7); 11 | uniform bool per_vertex_color = false; 12 | 13 | // the data to be sent to the fragment shader 14 | out Data { 15 | vec3 color; 16 | vec3 normal; 17 | vec3 position; 18 | vec4 shadowCoord; 19 | } DataOut; 20 | 21 | 22 | void main() { 23 | if (per_vertex_color) 24 | DataOut.color = vtx_color; 25 | else 26 | DataOut.color = default_color; 27 | 28 | DataOut.normal = vtx_normal; 29 | DataOut.position = vtx_position; 30 | DataOut.shadowCoord = SHADOW * vec4(vtx_position, 1.0); 31 | 32 | // the position of the vertex as seen from the current camera, in clip space 33 | gl_Position = MVP * vec4(vtx_position, 1.0); 34 | } 35 | -------------------------------------------------------------------------------- /resource/shaders/shadow/soft_shadow_generate.frag: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | out vec4 FragColor; // Ouput data 4 | 5 | 6 | void main(void) { 7 | // write the depth into the RED component 8 | FragColor = vec4(gl_FragCoord.z, 0, 0, 1.0); 9 | } 10 | -------------------------------------------------------------------------------- /resource/shaders/shadow/soft_shadow_generate.vert: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | in vec3 vtx_position; // vertex position 4 | 5 | uniform mat4 MVP; 6 | 7 | void main() { 8 | gl_Position = MVP * vec4(vtx_position, 1.0); 9 | } 10 | -------------------------------------------------------------------------------- /resource/shaders/shadow/soft_shadow_rendering.frag: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | 4 | in Data{ 5 | vec3 color; 6 | vec3 normal; 7 | vec3 position; 8 | vec4 shadowCoord; 9 | } DataIn; 10 | 11 | 12 | uniform vec3 wLightPos; 13 | uniform vec3 wCamPos; 14 | uniform vec3 ambient = vec3(0.05f, 0.05f, 0.05f); 15 | uniform vec3 specular = vec3(0.4f, 0.4f, 0.4f); 16 | uniform float shininess = 64.0f; 17 | 18 | uniform bool distinct_back_color = false; 19 | uniform vec3 back_color = vec3(1.0f, 0.0f, 0.0f); 20 | 21 | uniform int samplePattern; 22 | 23 | uniform sampler2DShadow shadowMapPCF; 24 | uniform sampler2D shadowMapDepth; 25 | 26 | uniform vec2 lightRadiusUV; 27 | uniform float lightZNear; 28 | uniform float lightZFar; 29 | uniform float darkness; 30 | uniform mat4 lightViewMatrix; 31 | 32 | uniform bool two_sides_lighting = true; 33 | 34 | uniform bool is_background = false; 35 | 36 | out vec4 FragColor; // Ouput data 37 | 38 | 39 | #define POISSON_25_25 0 40 | #define POISSON_32_64 1 41 | #define POISSON_64_128 2 42 | #define POISSON_100_100 3 43 | #define REGULAR_49_225 4 44 | 45 | const vec2 Poisson25[25] = vec2[]( 46 | vec2(-0.978698, -0.0884121), 47 | vec2(-0.841121, 0.521165), 48 | vec2(-0.71746, -0.50322), 49 | vec2(-0.702933, 0.903134), 50 | vec2(-0.663198, 0.15482), 51 | vec2(-0.495102, -0.232887), 52 | vec2(-0.364238, -0.961791), 53 | vec2(-0.345866, -0.564379), 54 | vec2(-0.325663, 0.64037), 55 | vec2(-0.182714, 0.321329), 56 | vec2(-0.142613, -0.0227363), 57 | vec2(-0.0564287, -0.36729), 58 | vec2(-0.0185858, 0.918882), 59 | vec2(0.0381787, -0.728996), 60 | vec2(0.16599, 0.093112), 61 | vec2(0.253639, 0.719535), 62 | vec2(0.369549, -0.655019), 63 | vec2(0.423627, 0.429975), 64 | vec2(0.530747, -0.364971), 65 | vec2(0.566027, -0.940489), 66 | vec2(0.639332, 0.0284127), 67 | vec2(0.652089, 0.669668), 68 | vec2(0.773797, 0.345012), 69 | vec2(0.968871, 0.840449), 70 | vec2(0.991882, -0.657338) 71 | ); 72 | 73 | const vec2 Poisson32[32] = vec2[]( 74 | vec2(-0.975402, -0.0711386), 75 | vec2(-0.920347, -0.41142), 76 | vec2(-0.883908, 0.217872), 77 | vec2(-0.884518, 0.568041), 78 | vec2(-0.811945, 0.90521), 79 | vec2(-0.792474, -0.779962), 80 | vec2(-0.614856, 0.386578), 81 | vec2(-0.580859, -0.208777), 82 | vec2(-0.53795, 0.716666), 83 | vec2(-0.515427, 0.0899991), 84 | vec2(-0.454634, -0.707938), 85 | vec2(-0.420942, 0.991272), 86 | vec2(-0.261147, 0.588488), 87 | vec2(-0.211219, 0.114841), 88 | vec2(-0.146336, -0.259194), 89 | vec2(-0.139439, -0.888668), 90 | vec2(0.0116886, 0.326395), 91 | vec2(0.0380566, 0.625477), 92 | vec2(0.0625935, -0.50853), 93 | vec2(0.125584, 0.0469069), 94 | vec2(0.169469, -0.997253), 95 | vec2(0.320597, 0.291055), 96 | vec2(0.359172, -0.633717), 97 | vec2(0.435713, -0.250832), 98 | vec2(0.507797, -0.916562), 99 | vec2(0.545763, 0.730216), 100 | vec2(0.56859, 0.11655), 101 | vec2(0.743156, -0.505173), 102 | vec2(0.736442, -0.189734), 103 | vec2(0.843562, 0.357036), 104 | vec2(0.865413, 0.763726), 105 | vec2(0.872005, -0.927) 106 | ); 107 | 108 | const vec2 Poisson64[64] = vec2[]( 109 | vec2(-0.934812, 0.366741), 110 | vec2(-0.918943, -0.0941496), 111 | vec2(-0.873226, 0.62389), 112 | vec2(-0.8352, 0.937803), 113 | vec2(-0.822138, -0.281655), 114 | vec2(-0.812983, 0.10416), 115 | vec2(-0.786126, -0.767632), 116 | vec2(-0.739494, -0.535813), 117 | vec2(-0.681692, 0.284707), 118 | vec2(-0.61742, -0.234535), 119 | vec2(-0.601184, 0.562426), 120 | vec2(-0.607105, 0.847591), 121 | vec2(-0.581835, -0.00485244), 122 | vec2(-0.554247, -0.771111), 123 | vec2(-0.483383, -0.976928), 124 | vec2(-0.476669, -0.395672), 125 | vec2(-0.439802, 0.362407), 126 | vec2(-0.409772, -0.175695), 127 | vec2(-0.367534, 0.102451), 128 | vec2(-0.35313, 0.58153), 129 | vec2(-0.341594, -0.737541), 130 | vec2(-0.275979, 0.981567), 131 | vec2(-0.230811, 0.305094), 132 | vec2(-0.221656, 0.751152), 133 | vec2(-0.214393, -0.0592364), 134 | vec2(-0.204932, -0.483566), 135 | vec2(-0.183569, -0.266274), 136 | vec2(-0.123936, -0.754448), 137 | vec2(-0.0859096, 0.118625), 138 | vec2(-0.0610675, 0.460555), 139 | vec2(-0.0234687, -0.962523), 140 | vec2(-0.00485244, -0.373394), 141 | vec2(0.0213324, 0.760247), 142 | vec2(0.0359813, -0.0834071), 143 | vec2(0.0877407, -0.730766), 144 | vec2(0.14597, 0.281045), 145 | vec2(0.18186, -0.529649), 146 | vec2(0.188208, -0.289529), 147 | vec2(0.212928, 0.063509), 148 | vec2(0.23661, 0.566027), 149 | vec2(0.266579, 0.867061), 150 | vec2(0.320597, -0.883358), 151 | vec2(0.353557, 0.322733), 152 | vec2(0.404157, -0.651479), 153 | vec2(0.410443, -0.413068), 154 | vec2(0.413556, 0.123325), 155 | vec2(0.46556, -0.176183), 156 | vec2(0.49266, 0.55388), 157 | vec2(0.506333, 0.876888), 158 | vec2(0.535875, -0.885556), 159 | vec2(0.615894, 0.0703452), 160 | vec2(0.637135, -0.637623), 161 | vec2(0.677236, -0.174291), 162 | vec2(0.67626, 0.7116), 163 | vec2(0.686331, -0.389935), 164 | vec2(0.691031, 0.330729), 165 | vec2(0.715629, 0.999939), 166 | vec2(0.8493, -0.0485549), 167 | vec2(0.863582, -0.85229), 168 | vec2(0.890622, 0.850581), 169 | vec2(0.898068, 0.633778), 170 | vec2(0.92053, -0.355693), 171 | vec2(0.933348, -0.62981), 172 | vec2(0.95294, 0.156896) 173 | ); 174 | 175 | const vec2 Poisson100[100] = vec2[]( 176 | vec2(-0.9891574, -0.1059512), 177 | vec2(-0.9822294, 0.05140843), 178 | vec2(-0.961332, 0.2562195), 179 | vec2(-0.9149657, -0.2404464), 180 | vec2(-0.8896608, -0.4183828), 181 | vec2(-0.8398135, 0.3748641), 182 | vec2(-0.8149028, 0.1989844), 183 | vec2(-0.8046502, 0.5212684), 184 | vec2(-0.7970151, -0.5834194), 185 | vec2(-0.7484995, -0.3153634), 186 | vec2(-0.738582, -0.09323367), 187 | vec2(-0.695694, 0.08865929), 188 | vec2(-0.6868832, 0.6336682), 189 | vec2(-0.6751406, 0.2777427), 190 | vec2(-0.666558, -0.6801786), 191 | vec2(-0.631489, -0.4702293), 192 | vec2(-0.5870083, 0.518836), 193 | vec2(-0.5744062, -0.06333278), 194 | vec2(-0.5667221, 0.1699501), 195 | vec2(-0.5537653, 0.7677022), 196 | vec2(-0.5337034, 0.3299558), 197 | vec2(-0.5201509, -0.2033358), 198 | vec2(-0.4873925, -0.8545401), 199 | vec2(-0.4712743, -0.3607009), 200 | vec2(-0.4524891, -0.5142469), 201 | vec2(-0.4421883, -0.6830674), 202 | vec2(-0.4293752, 0.6299667), 203 | vec2(-0.4240644, 0.8706763), 204 | vec2(-0.4139857, 0.1598689), 205 | vec2(-0.3838707, 0.4078749), 206 | vec2(-0.3688077, -0.0358762), 207 | vec2(-0.3432877, -0.2311365), 208 | vec2(-0.3256257, -0.9325441), 209 | vec2(-0.2751555, 0.302412), 210 | vec2(-0.2679778, -0.654425), 211 | vec2(-0.2554769, -0.4441924), 212 | vec2(-0.243476, -0.8034022), 213 | vec2(-0.2367678, -0.108045), 214 | vec2(-0.2196257, 0.8243803), 215 | vec2(-0.2119443, 0.06230118), 216 | vec2(-0.1708038, -0.9437978), 217 | vec2(-0.1694005, 0.5692244), 218 | vec2(-0.136494, 0.3937041), 219 | vec2(-0.1318274, -0.2166154), 220 | vec2(-0.09781472, -0.5743775), 221 | vec2(-0.09480921, 0.2369129), 222 | vec2(-0.07638182, -0.0571501), 223 | vec2(-0.06661344, -0.7966294), 224 | vec2(-0.06305461, -0.3521975), 225 | vec2(-0.04525706, 0.6982157), 226 | vec2(-0.04149697, 0.9666064), 227 | vec2(-0.003192461, -0.9693027), 228 | vec2(0.0104818, 0.5000805), 229 | vec2(0.03228819, -0.1681713), 230 | vec2(0.03715288, -0.673852), 231 | vec2(0.08470399, -0.3922319), 232 | vec2(0.09848712, -0.8374477), 233 | vec2(0.09940207, 0.1117471), 234 | vec2(0.1395643, 0.313647), 235 | vec2(0.1565993, 0.8555924), 236 | vec2(0.1772605, -0.5248074), 237 | vec2(0.1899546, 0.5249656), 238 | vec2(0.1952665, -0.9595091), 239 | vec2(0.213078, -0.07045701), 240 | vec2(0.2277649, -0.3361143), 241 | vec2(0.247221, 0.7353553), 242 | vec2(0.2493455, -0.6874771), 243 | vec2(0.269915, 0.07673722), 244 | vec2(0.3039587, 0.9087375), 245 | vec2(0.3189922, 0.3008468), 246 | vec2(0.3215453, -0.1954931), 247 | vec2(0.3593478, 0.4527411), 248 | vec2(0.3745022, -0.597945), 249 | vec2(0.3879738, -0.7821383), 250 | vec2(0.4522015, 0.6819367), 251 | vec2(0.4591872, -0.4484442), 252 | vec2(0.4626173, -0.03955235), 253 | vec2(0.4751598, 0.2083394), 254 | vec2(0.4894366, 0.8694122), 255 | vec2(0.4896614, -0.2676601), 256 | vec2(0.5070116, -0.6733028), 257 | vec2(0.5525513, 0.436241), 258 | vec2(0.5542312, -0.8262905), 259 | vec2(0.6012187, 0.7003717), 260 | vec2(0.6075609, -0.1610506), 261 | vec2(0.6291932, 0.2213627), 262 | vec2(0.6300695, -0.5324634), 263 | vec2(0.6613995, -0.7056449), 264 | vec2(0.6699739, -0.3828001), 265 | vec2(0.6705787, 0.01011722), 266 | vec2(0.6814164, 0.5618623), 267 | vec2(0.7808329, 0.261445), 268 | vec2(0.7830279, -0.1817809), 269 | vec2(0.8006546, -0.5266678), 270 | vec2(0.8030878, 0.4266291), 271 | vec2(0.8259325, 0.08734058), 272 | vec2(0.8621388, -0.3646038), 273 | vec2(0.9531851, 0.3011991), 274 | vec2(0.9578334, -0.1584408), 275 | vec2(0.9898114, 0.1029227) 276 | ); 277 | 278 | const vec2 Poisson128[128] = vec2[]( 279 | vec2(-0.9406119, 0.2160107), 280 | vec2(-0.920003, 0.03135762), 281 | vec2(-0.917876, -0.2841548), 282 | vec2(-0.9166079, -0.1372365), 283 | vec2(-0.8978907, -0.4213504), 284 | vec2(-0.8467999, 0.5201505), 285 | vec2(-0.8261013, 0.3743192), 286 | vec2(-0.7835162, 0.01432008), 287 | vec2(-0.779963, 0.2161933), 288 | vec2(-0.7719588, 0.6335353), 289 | vec2(-0.7658782, -0.3316436), 290 | vec2(-0.7341912, -0.5430729), 291 | vec2(-0.6825727, -0.1883408), 292 | vec2(-0.6777467, 0.3313724), 293 | vec2(-0.662191, 0.5155144), 294 | vec2(-0.6569989, -0.7000636), 295 | vec2(-0.6021447, 0.7923283), 296 | vec2(-0.5980815, -0.5529259), 297 | vec2(-0.5867089, 0.09857152), 298 | vec2(-0.5774597, -0.8154474), 299 | vec2(-0.5767041, -0.2656419), 300 | vec2(-0.575091, -0.4220052), 301 | vec2(-0.5486979, -0.09635002), 302 | vec2(-0.5235587, 0.6594529), 303 | vec2(-0.5170338, -0.6636339), 304 | vec2(-0.5114055, 0.4373561), 305 | vec2(-0.4844725, 0.2985838), 306 | vec2(-0.4803245, 0.8482798), 307 | vec2(-0.4651957, -0.5392771), 308 | vec2(-0.4529685, 0.09942394), 309 | vec2(-0.4523471, -0.3125569), 310 | vec2(-0.4268422, 0.5644538), 311 | vec2(-0.4187512, -0.8636028), 312 | vec2(-0.4160798, -0.0844868), 313 | vec2(-0.3751733, 0.2196607), 314 | vec2(-0.3656596, -0.7324334), 315 | vec2(-0.3286595, -0.2012637), 316 | vec2(-0.3147397, -0.0006635741), 317 | vec2(-0.3135846, 0.3636878), 318 | vec2(-0.3042951, -0.4983553), 319 | vec2(-0.2974239, 0.7496996), 320 | vec2(-0.2903037, 0.8890813), 321 | vec2(-0.2878664, -0.8622097), 322 | vec2(-0.2588971, -0.653879), 323 | vec2(-0.2555692, 0.5041648), 324 | vec2(-0.2553292, -0.3389159), 325 | vec2(-0.2401368, 0.2306108), 326 | vec2(-0.2124457, -0.09935001), 327 | vec2(-0.1877905, 0.1098409), 328 | vec2(-0.1559879, 0.3356432), 329 | vec2(-0.1499449, 0.7487829), 330 | vec2(-0.146661, -0.9256138), 331 | vec2(-0.1342774, 0.6185387), 332 | vec2(-0.1224529, -0.3887629), 333 | vec2(-0.116467, 0.8827716), 334 | vec2(-0.1157598, -0.539999), 335 | vec2(-0.09983152, -0.2407187), 336 | vec2(-0.09953719, -0.78346), 337 | vec2(-0.08604223, 0.4591112), 338 | vec2(-0.02128129, 0.1551989), 339 | vec2(-0.01478849, 0.6969455), 340 | vec2(-0.01231739, -0.6752576), 341 | vec2(-0.005001599, -0.004027164), 342 | vec2(0.00248426, 0.567932), 343 | vec2(0.00335562, 0.3472346), 344 | vec2(0.009554717, -0.4025437), 345 | vec2(0.02231783, -0.1349781), 346 | vec2(0.04694207, -0.8347212), 347 | vec2(0.05412609, 0.9042216), 348 | vec2(0.05812819, -0.9826952), 349 | vec2(0.1131321, -0.619306), 350 | vec2(0.1170737, 0.6799788), 351 | vec2(0.1275105, 0.05326218), 352 | vec2(0.1393405, -0.2149568), 353 | vec2(0.1457873, 0.1991508), 354 | vec2(0.1474208, 0.5443151), 355 | vec2(0.1497117, -0.3899909), 356 | vec2(0.1923773, 0.3683496), 357 | vec2(0.2110928, -0.7888536), 358 | vec2(0.2148235, 0.9586087), 359 | vec2(0.2152219, -0.1084362), 360 | vec2(0.2189204, -0.9644538), 361 | vec2(0.2220028, -0.5058427), 362 | vec2(0.2251696, 0.779461), 363 | vec2(0.2585723, 0.01621339), 364 | vec2(0.2612841, -0.2832426), 365 | vec2(0.2665483, -0.6422054), 366 | vec2(0.2939872, 0.1673226), 367 | vec2(0.3235748, 0.5643662), 368 | vec2(0.3269232, 0.6984669), 369 | vec2(0.3425438, -0.1783788), 370 | vec2(0.3672505, 0.4398117), 371 | vec2(0.3755714, -0.8814359), 372 | vec2(0.379463, 0.2842356), 373 | vec2(0.3822978, -0.381217), 374 | vec2(0.4057849, -0.5227674), 375 | vec2(0.4168737, -0.6936938), 376 | vec2(0.4202749, 0.8369391), 377 | vec2(0.4252189, 0.03818182), 378 | vec2(0.4445904, -0.09360636), 379 | vec2(0.4684285, 0.5885228), 380 | vec2(0.4952184, -0.2319764), 381 | vec2(0.5072351, 0.3683765), 382 | vec2(0.5136194, -0.3944138), 383 | vec2(0.519893, 0.7157083), 384 | vec2(0.5277841, 0.1486474), 385 | vec2(0.5474944, -0.7618791), 386 | vec2(0.5692734, 0.4852227), 387 | vec2(0.582229, -0.5125455), 388 | vec2(0.583022, 0.008507785), 389 | vec2(0.6500257, 0.3473313), 390 | vec2(0.6621304, -0.6280518), 391 | vec2(0.6674218, -0.2260806), 392 | vec2(0.6741871, 0.6734863), 393 | vec2(0.6753459, 0.1119422), 394 | vec2(0.7083091, -0.4393666), 395 | vec2(0.7106963, -0.102099), 396 | vec2(0.7606754, 0.5743545), 397 | vec2(0.7846709, 0.2282225), 398 | vec2(0.7871446, 0.3891495), 399 | vec2(0.8071781, -0.5257092), 400 | vec2(0.8230689, 0.002674922), 401 | vec2(0.8531976, -0.3256475), 402 | vec2(0.8758298, -0.1824844), 403 | vec2(0.8797691, 0.1284946), 404 | vec2(0.926309, 0.3576975), 405 | vec2(0.9608918, -0.03495717), 406 | vec2(0.972032, 0.2271516) 407 | ); 408 | 409 | 410 | 411 | bool isBlack(vec3 c) 412 | { 413 | return (dot(c, c) == 0.0); 414 | } 415 | 416 | float borderDepthTexture(sampler2D tex, vec2 uv) 417 | { 418 | return ((uv.x <= 1.0) && (uv.y <= 1.0) && 419 | (uv.x >= 0.0) && (uv.y >= 0.0)) ? texture(tex, uv).x : 1.0; 420 | } 421 | 422 | float borderPCFTexture(sampler2DShadow tex, vec3 uvz) 423 | { 424 | return ((uvz.x <= 1.0) && (uvz.y <= 1.0) && 425 | (uvz.x >= 0.0) && (uvz.y >= 0.0)) ? texture(tex, uvz) : 426 | ((uvz.z <= 1.0) ? 1.0 : 0.0); 427 | } 428 | 429 | 430 | // Using similar triangles from the surface point to the area light 431 | vec2 searchRegionRadiusUV(float zWorld) 432 | { 433 | return lightRadiusUV * (zWorld - lightZNear) / zWorld; 434 | } 435 | 436 | // Using similar triangles between the area light, the blocking plane and the surface point 437 | vec2 penumbraRadiusUV(float zReceiver, float zBlocker) 438 | { 439 | return lightRadiusUV * (zReceiver - zBlocker) / zBlocker; 440 | } 441 | 442 | // Project UV size to the near plane of the light 443 | vec2 projectToLightUV(vec2 sizeUV, float zWorld) 444 | { 445 | return sizeUV * lightZNear / zWorld; 446 | } 447 | 448 | // Derivatives of light-space depth with respect to texture2D coordinates 449 | vec2 depthGradient(vec2 uv, float z) 450 | { 451 | vec2 dz_duv = vec2(0.0, 0.0); 452 | 453 | vec3 duvdist_dx = dFdx(vec3(uv, z)); 454 | vec3 duvdist_dy = dFdy(vec3(uv, z)); 455 | 456 | dz_duv.x = duvdist_dy.y * duvdist_dx.z; 457 | dz_duv.x -= duvdist_dx.y * duvdist_dy.z; 458 | 459 | dz_duv.y = duvdist_dx.x * duvdist_dy.z; 460 | dz_duv.y -= duvdist_dy.x * duvdist_dx.z; 461 | 462 | float det = (duvdist_dx.x * duvdist_dy.y) - (duvdist_dx.y * duvdist_dy.x); 463 | dz_duv /= det; 464 | 465 | return dz_duv; 466 | } 467 | 468 | float biasedZ(float z0, vec2 dz_duv, vec2 offset) 469 | { 470 | return z0 + dot(dz_duv, offset) - 0.005; 471 | } 472 | 473 | float zClipToEye(float z) 474 | { 475 | return lightZFar * lightZNear / (lightZFar - z * (lightZFar - lightZNear)); 476 | } 477 | 478 | // Returns average blocker depth in the search region, as well as the number of found blockers. 479 | // Blockers are defined as shadow-map samples between the surface point and the light. 480 | void findBlocker( 481 | out float accumBlockerDepth, 482 | out float numBlockers, 483 | out float maxBlockers, 484 | vec2 uv, 485 | float z0, 486 | vec2 dz_duv, 487 | vec2 searchRadiusUV) 488 | { 489 | accumBlockerDepth = 0.0; 490 | numBlockers = 0.0; 491 | maxBlockers = 300.0; 492 | 493 | switch (samplePattern) 494 | { 495 | case POISSON_25_25: 496 | { 497 | maxBlockers = 25.0; 498 | for (int i = 0; i < 25; ++i) { 499 | vec2 offset = Poisson25[i] * searchRadiusUV; 500 | float shadowMapDepth = borderDepthTexture(shadowMapDepth, uv + offset); 501 | float z = biasedZ(z0, dz_duv, offset); 502 | if (shadowMapDepth < z) { 503 | accumBlockerDepth += shadowMapDepth; 504 | numBlockers++; 505 | } 506 | } 507 | } 508 | break; 509 | 510 | case POISSON_32_64: 511 | { 512 | maxBlockers = 32.0; 513 | for (int i = 0; i < 32; ++i) { 514 | vec2 offset = Poisson32[i] * searchRadiusUV; 515 | float shadowMapDepth = borderDepthTexture(shadowMapDepth, uv + offset); 516 | float z = biasedZ(z0, dz_duv, offset); 517 | if (shadowMapDepth < z) { 518 | accumBlockerDepth += shadowMapDepth; 519 | numBlockers++; 520 | } 521 | } 522 | } 523 | break; 524 | 525 | case POISSON_100_100: 526 | { 527 | maxBlockers = 100.0; 528 | for (int i = 0; i < 100; ++i) { 529 | vec2 offset = Poisson100[i] * searchRadiusUV; 530 | float shadowMapDepth = borderDepthTexture(shadowMapDepth, uv + offset); 531 | float z = biasedZ(z0, dz_duv, offset); 532 | if (shadowMapDepth < z) { 533 | accumBlockerDepth += shadowMapDepth; 534 | numBlockers++; 535 | } 536 | } 537 | } 538 | break; 539 | 540 | case POISSON_64_128: 541 | { 542 | maxBlockers = 64.0; 543 | for (int i = 0; i < 64; ++i) { 544 | vec2 offset = Poisson64[i] * searchRadiusUV; 545 | float shadowMapDepth = borderDepthTexture(shadowMapDepth, uv + offset); 546 | float z = biasedZ(z0, dz_duv, offset); 547 | if (shadowMapDepth < z) { 548 | accumBlockerDepth += shadowMapDepth; 549 | numBlockers++; 550 | } 551 | } 552 | } 553 | break; 554 | 555 | case REGULAR_49_225: 556 | { 557 | maxBlockers = 49.0; 558 | vec2 stepUV = searchRadiusUV / 3.0; 559 | for (int x = -3; x <= 3; ++x) { 560 | for (int y = -3; y <= 3; ++y) { 561 | vec2 offset = vec2(x, y) * stepUV; 562 | float shadowMapDepth = borderDepthTexture(shadowMapDepth, uv + offset); 563 | float z = biasedZ(z0, dz_duv, offset); 564 | if (shadowMapDepth < z) { 565 | accumBlockerDepth += shadowMapDepth; 566 | numBlockers++; 567 | } 568 | } 569 | } 570 | } 571 | break; 572 | } 573 | } 574 | 575 | // Performs PCF filtering on the shadow map using multiple taps in the filter region. 576 | float pcfFilter(vec2 uv, float z0, vec2 dz_duv, vec2 filterRadiusUV) 577 | { 578 | float sum = 0.0; 579 | 580 | switch (samplePattern) 581 | { 582 | case POISSON_25_25: 583 | { 584 | for (int i = 0; i < 25; ++i) { 585 | vec2 offset = Poisson25[i] * filterRadiusUV; 586 | float z = biasedZ(z0, dz_duv, offset); 587 | sum += borderPCFTexture(shadowMapPCF, vec3(uv + offset, z)); 588 | } 589 | return sum / 25.0; 590 | } 591 | 592 | case POISSON_32_64: 593 | { 594 | for (int i = 0; i < 64; ++i) { 595 | vec2 offset = Poisson64[i] * filterRadiusUV; 596 | float z = biasedZ(z0, dz_duv, offset); 597 | sum += borderPCFTexture(shadowMapPCF, vec3(uv + offset, z)); 598 | } 599 | return sum / 64.0; 600 | } 601 | 602 | case POISSON_100_100: 603 | { 604 | for (int i = 0; i < 100; ++i) { 605 | vec2 offset = Poisson100[i] * filterRadiusUV; 606 | float z = biasedZ(z0, dz_duv, offset); 607 | sum += borderPCFTexture(shadowMapPCF, vec3(uv + offset, z)); 608 | } 609 | return sum / 100.0; 610 | } 611 | 612 | case POISSON_64_128: 613 | { 614 | for (int i = 0; i < 128; ++i) { 615 | vec2 offset = Poisson128[i] * filterRadiusUV; 616 | float z = biasedZ(z0, dz_duv, offset); 617 | sum += borderPCFTexture(shadowMapPCF, vec3(uv + offset, z)); 618 | } 619 | return sum / 128.0; 620 | } 621 | 622 | case REGULAR_49_225: 623 | { 624 | vec2 stepUV = filterRadiusUV / 7.0; 625 | for (int x = -7; x <= 7; ++x) { 626 | for (int y = -7; y <= 7; ++y) { 627 | vec2 offset = vec2(x, y) * stepUV; 628 | float z = biasedZ(z0, dz_duv, offset); 629 | sum += borderPCFTexture(shadowMapPCF, vec3(uv + offset, z)); 630 | } 631 | } 632 | float numSamples = 7.0 * 2.0 + 1.0; 633 | return sum / (numSamples * numSamples); 634 | } 635 | 636 | default: 637 | return 1.0; 638 | } 639 | } 640 | 641 | float pcssShadow(vec2 uv, float z, vec2 dz_duv, float zEye) 642 | { 643 | // ------------------------ 644 | // STEP 1: blocker search 645 | // ------------------------ 646 | float accumBlockerDepth, numBlockers, maxBlockers; 647 | vec2 searchRadiusUV = searchRegionRadiusUV(zEye); 648 | findBlocker(accumBlockerDepth, numBlockers, maxBlockers, uv, z, dz_duv, searchRadiusUV); 649 | 650 | // Early out if not in the penumbra 651 | if (numBlockers == 0.0) 652 | return 1.0; 653 | 654 | // This is for dubug: visualize the percentage of occlusion 655 | //return numBlockers / maxBlockers; 656 | 657 | // ------------------------ 658 | // STEP 2: penumbra size 659 | // ------------------------ 660 | float avgBlockerDepth = accumBlockerDepth / numBlockers; 661 | float avgBlockerDepthWorld = zClipToEye(avgBlockerDepth); 662 | vec2 penumbraRadius = penumbraRadiusUV(zEye, avgBlockerDepthWorld); 663 | vec2 filterRadius = projectToLightUV(penumbraRadius, zEye); 664 | 665 | // ------------------------ 666 | // STEP 3: filtering 667 | // ------------------------ 668 | return pcfFilter(uv, z, dz_duv, filterRadius); 669 | } 670 | 671 | 672 | vec3 shade(vec3 worldPos) 673 | { 674 | if (is_background) 675 | return DataIn.color; 676 | 677 | else { 678 | vec3 normal = normalize(DataIn.normal); 679 | 680 | vec3 view_dir = normalize(wCamPos - worldPos); 681 | vec3 light_dir = normalize(wLightPos); // directional light 682 | //vec3 light_dir = normalize(wLightPos - worldPos); // point light 683 | 684 | float df = 0.0; // diffuse factor 685 | if (two_sides_lighting) 686 | df = abs(dot(light_dir, normal)); 687 | else 688 | df = max(dot(light_dir, normal), 0); 689 | 690 | float sf = 0.0; // specular factor 691 | if (df > 0.0) { // if the vertex is lit compute the specular color 692 | vec3 half_vector = normalize(light_dir + view_dir); // compute the half vector 693 | if (two_sides_lighting) 694 | sf = abs(dot(half_vector, normal)); 695 | else 696 | sf = max(dot(half_vector, normal), 0.0); 697 | sf = pow(sf, shininess); 698 | } 699 | 700 | vec3 color; 701 | if (!gl_FrontFacing && distinct_back_color) 702 | color = back_color; 703 | else { 704 | color = DataIn.color; 705 | } 706 | 707 | color = color * df + specular * sf; 708 | 709 | return color; 710 | } 711 | } 712 | 713 | 714 | void main(void) { 715 | vec3 color = shade(DataIn.position); 716 | 717 | // transforming from clip space to NDC space 718 | vec3 ProjCoords = DataIn.shadowCoord.xyz / DataIn.shadowCoord.w; 719 | // It seems checking Z is sufficient (implies X and Y)? 720 | if ((isBlack(color.rgb)) || 721 | //(ProjCoords.x <= 0 || ProjCoords.x >= 1) || 722 | //(ProjCoords.y <= 0 || ProjCoords.y >= 1) || 723 | (ProjCoords.z <= 0 || ProjCoords.z >= 1)) 724 | { 725 | if (is_background) 726 | FragColor = vec4(color, 1.0); 727 | else 728 | FragColor = vec4(color + ambient, 1.0); 729 | } 730 | else { 731 | vec2 uv = ProjCoords.xy; 732 | float z = ProjCoords.z; 733 | 734 | // Compute gradient using ddx/ddy before any branching 735 | vec2 dz_duv = depthGradient(uv, z); 736 | 737 | // Eye-space z from the light's point of view 738 | float zEye = -(lightViewMatrix * vec4(DataIn.position, 1.0)).z; 739 | float shadow = pcssShadow(uv, z, dz_duv, zEye); 740 | 741 | // I don't want the shadow regions to be completely dark. 742 | shadow = (1.0 - darkness) + shadow * darkness; 743 | 744 | if (is_background) 745 | FragColor = vec4(color * shadow, 1.0); 746 | else 747 | FragColor = vec4(color * shadow + ambient, 1.0); 748 | } 749 | } 750 | -------------------------------------------------------------------------------- /resource/shaders/shadow/soft_shadow_rendering.vert: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | in vec3 vtx_position; // vertex position 4 | in vec3 vtx_normal; // vertex normal 5 | in vec3 vtx_color; // vertex color 6 | 7 | uniform mat4 MVP; 8 | uniform mat4 SHADOW; 9 | 10 | uniform vec3 default_color = vec3(0.3, 0.3, 0.7); 11 | uniform bool per_vertex_color = false; 12 | 13 | // the data to be sent to the fragment shader 14 | out Data { 15 | vec3 color; 16 | vec3 normal; 17 | vec3 position; 18 | vec4 shadowCoord; 19 | } DataOut; 20 | 21 | 22 | void main() { 23 | if (per_vertex_color) 24 | DataOut.color = vtx_color; 25 | else 26 | DataOut.color = default_color; 27 | 28 | DataOut.normal = vtx_normal; 29 | DataOut.position = vtx_position; 30 | DataOut.shadowCoord = SHADOW * vec4(vtx_position, 1.0); 31 | 32 | // the position of the vertex as seen from the current camera, in clip space 33 | gl_Position = MVP * vec4(vtx_position, 1.0); 34 | } 35 | -------------------------------------------------------------------------------- /resource/shaders/surface_color.frag: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | uniform vec3 wLightPos; 4 | uniform vec3 wCamPos; 5 | uniform vec3 ambient = vec3(0.05f, 0.05f, 0.05f); 6 | uniform vec3 specular = vec3(0.4f, 0.4f, 0.4f); 7 | uniform float shininess = 64.0f; 8 | uniform vec3 defaultColor = vec3(0.4f, 0.8f, 0.8f); 9 | 10 | // SSAO 11 | uniform sampler2D ssaoTexture; 12 | uniform bool ssaoEnabled = false; 13 | 14 | 15 | // two sides 16 | uniform bool two_sides_lighting = true; 17 | 18 | in Data{ 19 | vec3 color; 20 | vec3 position; 21 | vec3 normal; 22 | } DataIn; 23 | 24 | out vec4 outputF; 25 | 26 | void main(void) { 27 | vec3 color = DataIn.color; 28 | vec3 normal = normalize(DataIn.normal); 29 | 30 | vec3 view_dir = normalize(wCamPos - DataIn.position); 31 | vec3 light_dir = normalize(wLightPos); 32 | 33 | float df = 0.0; // diffuse factor 34 | if (two_sides_lighting) 35 | df = abs(dot(light_dir, normal)); 36 | else 37 | df = max(dot(light_dir, normal), 0); 38 | 39 | float sf = 0.0; // specular factor 40 | if (df > 0.0) { // if the vertex is lit compute the specular color 41 | vec3 half_vector = normalize(light_dir + view_dir); // compute the half vector 42 | 43 | if (two_sides_lighting) 44 | sf = abs(dot(half_vector, normal)); 45 | else 46 | sf = max(dot(half_vector, normal), 0.0); 47 | 48 | sf = pow(sf, shininess); 49 | } 50 | 51 | if (ssaoEnabled) { 52 | vec2 texCoord = gl_FragCoord.xy / textureSize(ssaoTexture, 0); 53 | float coeff = texture(ssaoTexture, texCoord).r; 54 | outputF = vec4(vec3(color * df + specular * sf + ambient) * coeff, 1.0); 55 | } 56 | else 57 | outputF = vec4(color * df + specular * sf + ambient, 1.0); 58 | } 59 | -------------------------------------------------------------------------------- /resource/shaders/surface_color.vert: -------------------------------------------------------------------------------- 1 | #version 150 2 | 3 | in vec3 vtx_position; 4 | in vec3 vtx_normal; 5 | in vec3 vtx_color; 6 | 7 | uniform mat4 MVP; 8 | uniform mat4 MANIP = mat4(1.0); 9 | uniform vec3 default_color = vec3(0.4f, 0.8f, 0.8f); 10 | uniform bool per_vertex_color = false; 11 | 12 | out Data{ 13 | vec3 color; 14 | vec3 position; 15 | vec3 normal; 16 | } DataOut; 17 | 18 | void main() { 19 | if (per_vertex_color) 20 | DataOut.color = vtx_color; 21 | else 22 | DataOut.color = default_color; 23 | DataOut.position = vtx_position; 24 | DataOut.normal = vtx_normal; 25 | gl_Position = MVP * MANIP * vec4(vtx_position, 1.0); 26 | } 27 | -------------------------------------------------------------------------------- /vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuangpengFan/AdQSM/3c99e8e4480c6e4f82a2d1866b2c7dc27ec0cfd8/vcruntime140.dll -------------------------------------------------------------------------------- /vcruntime140_1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuangpengFan/AdQSM/3c99e8e4480c6e4f82a2d1866b2c7dc27ec0cfd8/vcruntime140_1.dll --------------------------------------------------------------------------------