commonMain.earth.worldwind.layer.atmosphere.GroundProgram.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of worldwind-jvm Show documentation
Show all versions of worldwind-jvm Show documentation
The WorldWind Kotlin SDK (WWK) includes the library, examples and tutorials for building multiplatform 3D virtual globe applications for Android, Web and Java.
The newest version!
package earth.worldwind.layer.atmosphere
open class GroundProgram: AbstractAtmosphereProgram() {
override var programSources = arrayOf(
"""
precision mediump int; /* fragMode is used in both shaders, so we must use a common precision */
const int FRAGMODE_PRIMARY = 1;
const int FRAGMODE_SECONDARY = 2;
const int FRAGMODE_PRIMARY_TEX_BLEND = 3;
const int SAMPLE_COUNT = 2;
const float SAMPLES = 2.0;
uniform int fragMode;
uniform mat4 mvpMatrix;
uniform mat3 texCoordMatrix;
uniform vec3 vertexOrigin;
uniform vec3 eyePoint;
uniform float eyeMagnitude; /* The eye point's magnitude */
uniform float eyeMagnitude2; /* eyeMagnitude^2 */
uniform vec3 lightDirection; /* The direction vector to the light source */
uniform vec3 invWavelength; /* 1 / pow(wavelength, 4) for the red, green, and blue channels */
uniform float atmosphereRadius; /* The outer (atmosphere) radius */
uniform float atmosphereRadius2; /* atmosphereRadius^2 */
uniform float globeRadius; /* The inner (planetary) radius */
uniform float KrESun; /* Kr * ESun */
uniform float KmESun; /* Km * ESun */
uniform float Kr4PI; /* Kr * 4 * PI */
uniform float Km4PI; /* Km * 4 * PI */
uniform float scale; /* 1 / (atmosphereRadius - globeRadius) */
uniform float scaleDepth; /* The scale depth (i.e. the altitude at which the atmosphere's average density is found) */
uniform float scaleOverScaleDepth; /* fScale / fScaleDepth */
attribute vec4 vertexPoint;
attribute vec2 vertexTexCoord;
varying vec3 primaryColor;
varying vec3 secondaryColor;
varying vec3 direction;
varying vec2 texCoord;
float scaleFunc(float cos) {
float x = 1.0 - cos;
return scaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));
}
void main() {
/* Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the
atmosphere) */
vec3 point = vertexPoint.xyz + vertexOrigin;
vec3 ray = point - eyePoint;
float far = length(ray);
ray /= far;
vec3 start;
if (eyeMagnitude < atmosphereRadius) {
start = eyePoint;
} else {
/* Calculate the closest intersection of the ray with the outer atmosphere (which is the near point of the ray
passing through the atmosphere) */
float B = 2.0 * dot(eyePoint, ray);
float C = eyeMagnitude2 - atmosphereRadius2;
float det = max(0.0, B*B - 4.0 * C);
float near = 0.5 * (-B - sqrt(det));
/* Calculate the ray's starting point, then calculate its scattering offset */
start = eyePoint + ray * near;
far -= near;
}
float depth = exp((globeRadius - atmosphereRadius) / scaleDepth);
float eyeAngle = dot(-ray, point) / length(point);
float lightAngle = dot(lightDirection, point) / length(point);
float eyeScale = scaleFunc(eyeAngle);
float lightScale = scaleFunc(lightAngle);
float eyeOffset = depth*eyeScale;
float temp = (lightScale + eyeScale);
/* Initialize the scattering loop variables */
float sampleLength = far / SAMPLES;
float scaledLength = sampleLength * scale;
vec3 sampleRay = ray * sampleLength;
vec3 samplePoint = start + sampleRay * 0.5;
/* Now loop through the sample rays */
vec3 frontColor = vec3(0.0, 0.0, 0.0);
vec3 attenuate = vec3(0.0, 0.0, 0.0);
for(int i=0; i
© 2015 - 2024 Weber Informatics LLC | Privacy Policy