@@ -29,10 +29,15 @@ const char *fs3D = "#version 330\n"
2929 "out vec4 finalColor;\n"
3030 "uniform sampler2D texture0;\n"
3131 "uniform sampler2D texture1;\n"
32+ "uniform sampler2D texture2;\n"
3233 "uniform vec3 sunDir;\n"
3334 "uniform vec3 moonPos;\n"
3435 "uniform float moonRadius;\n"
3536 "uniform float earthRadius;\n"
37+ "uniform vec3 viewPos;\n"
38+ "uniform float cloudUVOffset;\n"
39+ "uniform int advancedScatter;\n"
40+ "uniform int showClouds;\n"
3641 "void main() {\n"
3742 " vec4 day = texture(texture0, fragTexCoord);\n"
3843 " vec4 night = texture(texture1, fragTexCoord);\n"
@@ -43,6 +48,29 @@ const char *fs3D = "#version 330\n"
4348 " float blend = smoothstep(-0.15, 0.15, intensity);\n"
4449 " vec3 fragPos = normal * earthRadius;\n"
4550 " vec3 scatteredDay = day.rgb;\n"
51+ " \n"
52+ " if (advancedScatter == 1) {\n"
53+ " vec3 viewDir = normalize(viewPos - fragPos);\n"
54+ " vec3 halfDir = normalize(sunDir + viewDir);\n"
55+ " float NdotV = max(dot(normal, viewDir), 0.0);\n"
56+ " float fresnel = pow(1.0 - NdotV, 4.0);\n"
57+ " float specPower = mix(48.0, 12.0, fresnel);\n"
58+ " float spec = pow(max(dot(normal, halfDir), 0.0), specPower);\n"
59+ " float water = clamp((day.b - day.r) * 2.5, 0.0, 1.0);\n"
60+ " float glareBoost = mix(0.6, 4.0, fresnel);\n"
61+ " vec3 specular = vec3(1.0, 0.9, 0.8) * spec * water * glareBoost * max(intensity, 0.0);\n"
62+ " \n"
63+ " float cShadow = 1.0;\n"
64+ " if (showClouds == 1) {\n"
65+ " vec2 cUV = fragTexCoord + vec2(sunDir.x, -sunDir.y) * 0.005;\n"
66+ " cUV.x = fract(cUV.x + cloudUVOffset);\n"
67+ " float cAlpha = texture(texture2, cUV).a;\n"
68+ " cShadow = mix(1.0, 0.4, cAlpha * smoothstep(-0.1, 0.2, intensity));\n"
69+ " }\n"
70+ " \n"
71+ " scatteredDay = (scatteredDay * cShadow) + specular;\n"
72+ " }\n"
73+ " \n"
4674 " vec3 toMoon = moonPos - fragPos;\n"
4775 " float distSunward = dot(toMoon, sunDir);\n"
4876 " float shadow = 1.0;\n"
@@ -51,7 +79,7 @@ const char *fs3D = "#version 330\n"
5179 " float distSq = dot(proj - moonPos, proj - moonPos);\n"
5280 " float rSq = moonRadius * moonRadius;\n"
5381 " if (distSq < rSq * 4.0) {\n"
54- " shadow = mix(0.03, 1.0, smoothstep(rSq * 0.1, rSq * 4.0, distSq));\n"
82+ " shadow = mix(0.03, 1.0, smoothstep(rSq * 0.1, rSq * 4.0, distSq));\n"
5583 " }\n"
5684 " }\n"
5785 " vec4 dayColor = mix(night, vec4(scatteredDay, day.a), shadow);\n"
@@ -524,6 +552,11 @@ int main(void)
524552 Shader shader3D = LoadShaderFromMemory (NULL , fs3D );
525553 int sunDirLoc3D = GetShaderLocation (shader3D , "sunDir" );
526554 shader3D .locs [SHADER_LOC_MAP_EMISSION ] = GetShaderLocation (shader3D , "texture1" );
555+ shader3D .locs [SHADER_LOC_MAP_SPECULAR ] = GetShaderLocation (shader3D , "texture2" );
556+ int viewPosLoc3D = GetShaderLocation (shader3D , "viewPos" );
557+ int cloudUVOffsetLoc3D = GetShaderLocation (shader3D , "cloudUVOffset" );
558+ int advScatLoc3D = GetShaderLocation (shader3D , "advancedScatter" );
559+ int showCloudsLoc3D = GetShaderLocation (shader3D , "showClouds" );
527560
528561 Shader shader2D = LoadShaderFromMemory (NULL , fs2D );
529562 int sunDirLoc2D = GetShaderLocation (shader2D , "sunDir" );
@@ -563,6 +596,7 @@ int main(void)
563596 cloudTexture = LoadTexture (GetAssetPath (cfg .theme , "clouds.png" ));
564597 SetTextureFilter (cloudTexture , TEXTURE_FILTER_BILINEAR );
565598 cloudModel .materials [0 ].maps [MATERIAL_MAP_DIFFUSE ].texture = cloudTexture ;
599+ earthModel .materials [0 ].maps [MATERIAL_MAP_SPECULAR ].texture = cloudTexture ;
566600 Shader defaultCloudShader = cloudModel .materials [0 ].shader ;
567601
568602 float draw_atmosphere_radius = (EARTH_RADIUS_KM + 80.0f ) / DRAW_SCALE ;
@@ -697,6 +731,7 @@ int main(void)
697731 cloudTexture = LoadTexture (GetAssetPath (cfg .theme , "clouds.png" ));
698732 SetTextureFilter (cloudTexture , TEXTURE_FILTER_BILINEAR );
699733 cloudModel .materials [0 ].maps [MATERIAL_MAP_DIFFUSE ].texture = cloudTexture ;
734+ earthModel .materials [0 ].maps [MATERIAL_MAP_SPECULAR ].texture = cloudTexture ;
700735
701736 skyboxTexture = LoadTexture (GetAssetPath (cfg .theme , "skybox.png" ));
702737 SetTextureFilter (skyboxTexture , TEXTURE_FILTER_BILINEAR );
@@ -1652,11 +1687,24 @@ int main(void)
16521687
16531688 earthModel .transform = MatrixRotateY (earth_rot_rad );
16541689
1690+ double continuous_cloud_angle = fmod (gmst_deg + cfg .earth_rotation_offset + (current_epoch * 360.0 * 0.04 ), 360.0 );
1691+ float cloud_rot_rad = (float )(continuous_cloud_angle * DEG2RAD );
1692+
16551693 if (cfg .show_night_lights )
16561694 {
16571695 earthModel .materials [0 ].shader = shader3D ;
16581696 SetShaderValue (shader3D , sunDirLoc3D , & sunEcef , SHADER_UNIFORM_VEC3 );
16591697 SetShaderValue (shader3D , moonPosLoc3D , & moonEcef , SHADER_UNIFORM_VEC3 );
1698+
1699+ int doAdvScat = cfg .show_scattering ? 1 : 0 ;
1700+ SetShaderValue (shader3D , advScatLoc3D , & doAdvScat , SHADER_UNIFORM_INT );
1701+ SetShaderValue (shader3D , viewPosLoc3D , & viewEcef , SHADER_UNIFORM_VEC3 );
1702+
1703+ float uv_offset = (earth_rot_rad - cloud_rot_rad ) / (2.0f * PI );
1704+ SetShaderValue (shader3D , cloudUVOffsetLoc3D , & uv_offset , SHADER_UNIFORM_FLOAT );
1705+
1706+ int doShowClouds = cfg .show_clouds ? 1 : 0 ;
1707+ SetShaderValue (shader3D , showCloudsLoc3D , & doShowClouds , SHADER_UNIFORM_INT );
16601708 }
16611709 else
16621710 {
@@ -1668,8 +1716,6 @@ int main(void)
16681716 /* atmosphere/cloud layer */
16691717 if (cfg .show_clouds )
16701718 {
1671- double continuous_cloud_angle = fmod (gmst_deg + cfg .earth_rotation_offset + (current_epoch * 360.0 * 0.04 ), 360.0 );
1672- float cloud_rot_rad = (float )(continuous_cloud_angle * DEG2RAD );
16731719 cloudModel .transform = MatrixRotateY (cloud_rot_rad );
16741720
16751721 if (cfg .show_night_lights )
0 commit comments