+uniform Params
+{
+ float start_height;
+ float max_height;
+ float min_height;
+ float step_size;
+};
+
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+void main()
+{
+ gl_Position = position;
+ out vec3 dir = vec3(position.xy, 1.0);
+}
+
+#pragma MSP stage(fragment)
+layout(location=0) out vec4 frag_color;
+void main()
+{
+ vec3 ndir = normalize(dir);
+ vec3 pos = vec3(0.0, 0.0, start_height);
+ float luminance = 0.0;
+ float extinction = 0.0;
+ while(true)
+ {
+ if(pos.z<min_height || pos.z>max_height)
+ break;
+
+ float density = exp(pos.z/-1000.0);
+ luminance += density*exp(-extinction);
+
+ extinction += density*step_size;
+ pos += ndir*step_size;
+ }
+
+ frag_color = vec4(vec3(luminance), 1.0);
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+layout(location=0) out vec3 dir;
+void main()
+{
+ gl_Position = position;
+ dir = vec3(position.xy, 1.0);
+}
+*/
+
+/* Expected output: fragment
+layout(binding=80) uniform Params
+{
+ float start_height;
+ float max_height;
+ float min_height;
+ float step_size;
+};
+layout(location=0) out vec4 frag_color;
+layout(location=0) in vec3 dir;
+void main()
+{
+ vec3 ndir = normalize(dir);
+ vec3 pos = vec3(0.0, 0.0, start_height);
+ float luminance = 0.0;
+ float extinction = 0.0;
+ while(true)
+ {
+ if(pos.z<min_height || pos.z>max_height)
+ break;
+ float density = exp(pos.z/-1000.0);
+ luminance += density*exp(-extinction);
+ extinction += density*step_size;
+ pos += ndir*step_size;
+ }
+ frag_color = vec4(vec3(luminance), 1.0);
+}
+*/