Added planet atmosphere shader
This commit is contained in:
120
core/assets/shaders/atmosphere.frag
Normal file
120
core/assets/shaders/atmosphere.frag
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
const float PI = 3.14159265359;
|
||||||
|
const float MAX = 10000.0;
|
||||||
|
|
||||||
|
const float PEAK = 0.1;
|
||||||
|
const float FLARE = 0.0025;
|
||||||
|
const float INTENSITY = 14.3;
|
||||||
|
const float G_M = -0.85;
|
||||||
|
|
||||||
|
const float INNER_RADIUS = 1.02;
|
||||||
|
const float OUTER_RADIUS = 1.3;
|
||||||
|
|
||||||
|
const int numOutScatter = 10;
|
||||||
|
const float fNumOutScatter = 10.0;
|
||||||
|
const int numInScatter = 10;
|
||||||
|
const float fNumInScatter = 10.0;
|
||||||
|
|
||||||
|
varying vec4 v_position;
|
||||||
|
varying mat4 v_model;
|
||||||
|
|
||||||
|
uniform vec3 u_color;
|
||||||
|
uniform vec2 u_resolution;
|
||||||
|
uniform float u_time;
|
||||||
|
uniform vec3 u_campos;
|
||||||
|
uniform vec3 u_rcampos;
|
||||||
|
uniform mat4 u_invproj;
|
||||||
|
uniform vec3 u_light;
|
||||||
|
|
||||||
|
vec2 rayIntersection(vec3 p, vec3 dir, float radius) {
|
||||||
|
float b = dot(p, dir);
|
||||||
|
float c = dot(p, p) - radius * radius;
|
||||||
|
|
||||||
|
float d = b * b - c;
|
||||||
|
if (d < 0.0) {
|
||||||
|
return vec2(MAX, -MAX);
|
||||||
|
}
|
||||||
|
d = sqrt(d);
|
||||||
|
|
||||||
|
float near = -b - d;
|
||||||
|
float far = -b + d;
|
||||||
|
|
||||||
|
return vec2(near, far);
|
||||||
|
}
|
||||||
|
|
||||||
|
float miePhase(float g, float c, float cc) {
|
||||||
|
float gg = g * g;
|
||||||
|
|
||||||
|
float a = (1.0 - gg) * (1.0 + cc);
|
||||||
|
|
||||||
|
float b = 1.0 + gg - 2.0 * g * c;
|
||||||
|
b *= sqrt(b);
|
||||||
|
b *= 2.0 + gg;
|
||||||
|
|
||||||
|
return 1.5 * a / b;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rayleighPhase(float cc) {
|
||||||
|
return 0.75 * (1.0 + cc);
|
||||||
|
}
|
||||||
|
|
||||||
|
float density(vec3 p) {
|
||||||
|
return exp(-(length(p) - INNER_RADIUS) * (4.0 / (OUTER_RADIUS - INNER_RADIUS)));
|
||||||
|
}
|
||||||
|
|
||||||
|
float optic(vec3 p, vec3 q) {
|
||||||
|
vec3 step = (q - p) / fNumOutScatter;
|
||||||
|
vec3 v = p + step * 0.5;
|
||||||
|
|
||||||
|
float sum = 0.0;
|
||||||
|
for (int i = 0; i < numOutScatter; i++) {
|
||||||
|
sum += density(v);
|
||||||
|
v += step;
|
||||||
|
}
|
||||||
|
sum *= length(step)*(1.0 / (OUTER_RADIUS - INNER_RADIUS));
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 inScatter(vec3 o, vec3 dir, vec2 e, vec3 l) {
|
||||||
|
float len = (e.y - e.x) / fNumInScatter;
|
||||||
|
vec3 step = dir * len;
|
||||||
|
vec3 p = o + dir * e.x;
|
||||||
|
vec3 v = p + dir * (len * 0.5);
|
||||||
|
|
||||||
|
vec3 sum = vec3(0.0);
|
||||||
|
for(int i = 0; i < numInScatter; i++){
|
||||||
|
vec2 f = rayIntersection(v, l, OUTER_RADIUS);
|
||||||
|
vec3 u = v + l * f.y;
|
||||||
|
float n = (optic(p, v) + optic(v, u))*(PI * 4.0);
|
||||||
|
|
||||||
|
sum += density(v) * exp(-n * (PEAK * u_color + FLARE));
|
||||||
|
v += step;
|
||||||
|
}
|
||||||
|
sum *= len * (1.0 / (OUTER_RADIUS - INNER_RADIUS));
|
||||||
|
float c = dot(dir, -l);
|
||||||
|
float cc = c * c;
|
||||||
|
return sum * (PEAK * u_color * rayleighPhase(cc) + FLARE * miePhase(G_M, c, cc)) * INTENSITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 rayDirection(){
|
||||||
|
vec4 ray = v_model*v_position - vec4(u_campos, 1.0);
|
||||||
|
return normalize(vec3(ray));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec3 dir = rayDirection();
|
||||||
|
vec3 eye = u_rcampos;
|
||||||
|
|
||||||
|
vec3 l = u_light;
|
||||||
|
|
||||||
|
vec2 e = rayIntersection(eye, dir, OUTER_RADIUS);
|
||||||
|
if (e.x > e.y){
|
||||||
|
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vec2 f = rayIntersection(eye, dir, INNER_RADIUS);
|
||||||
|
e.y = min(e.y, f.x);
|
||||||
|
|
||||||
|
vec3 result = inScatter(eye, dir, e, l);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(result, 1.0);
|
||||||
|
}
|
||||||
13
core/assets/shaders/atmosphere.vert
Normal file
13
core/assets/shaders/atmosphere.vert
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
attribute vec4 a_position;
|
||||||
|
|
||||||
|
varying vec4 v_position;
|
||||||
|
varying mat4 v_model;
|
||||||
|
|
||||||
|
uniform mat4 u_model;
|
||||||
|
uniform mat4 u_projection;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
v_position = a_position;
|
||||||
|
v_model = u_model;
|
||||||
|
gl_Position = u_projection*u_model*a_position;
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ uniform vec3 u_ambientColor;
|
|||||||
|
|
||||||
varying vec4 v_col;
|
varying vec4 v_col;
|
||||||
|
|
||||||
const vec3 diffuse = vec3(0.2);
|
const vec3 diffuse = vec3(0);
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
vec3 norc = u_ambientColor * (diffuse + vec3(clamp((dot(a_normal, u_lightdir) + 1.0) / 2.0, 0.0, 1.0)));
|
vec3 norc = u_ambientColor * (diffuse + vec3(clamp((dot(a_normal, u_lightdir) + 1.0) / 2.0, 0.0, 1.0)));
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class Planets implements ContentList{
|
|||||||
starter = new Planet("TODO", sun, 3, 1){{
|
starter = new Planet("TODO", sun, 3, 1){{
|
||||||
generator = new TODOPlanetGenerator();
|
generator = new TODOPlanetGenerator();
|
||||||
meshLoader = () -> new HexMesh(this, 6);
|
meshLoader = () -> new HexMesh(this, 6);
|
||||||
|
atmosphereColor = Color.valueOf("3c1b8f");
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,14 @@ package mindustry.graphics;
|
|||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
|
import arc.graphics.g3d.*;
|
||||||
import arc.graphics.gl.*;
|
import arc.graphics.gl.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
|
import mindustry.type.*;
|
||||||
|
|
||||||
public class Shaders{
|
public class Shaders{
|
||||||
public static Shadow shadow;
|
public static Shadow shadow;
|
||||||
@@ -22,6 +24,7 @@ public class Shaders{
|
|||||||
public static PlanetShader planet;
|
public static PlanetShader planet;
|
||||||
public static PlanetGridShader planetGrid;
|
public static PlanetGridShader planetGrid;
|
||||||
public static SunShader sun;
|
public static SunShader sun;
|
||||||
|
public static AtmosphereShader atmosphere;
|
||||||
|
|
||||||
public static void init(){
|
public static void init(){
|
||||||
shadow = new Shadow();
|
shadow = new Shadow();
|
||||||
@@ -43,6 +46,33 @@ public class Shaders{
|
|||||||
planet = new PlanetShader();
|
planet = new PlanetShader();
|
||||||
planetGrid = new PlanetGridShader();
|
planetGrid = new PlanetGridShader();
|
||||||
sun = new SunShader();
|
sun = new SunShader();
|
||||||
|
atmosphere = new AtmosphereShader();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AtmosphereShader extends LoadShader{
|
||||||
|
public Camera3D camera;
|
||||||
|
public Planet planet;
|
||||||
|
|
||||||
|
Mat3D mat = new Mat3D();
|
||||||
|
|
||||||
|
public AtmosphereShader(){
|
||||||
|
super("atmosphere", "atmosphere");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void apply(){
|
||||||
|
setUniformf("u_resolution", Core.graphics.getWidth(), Core.graphics.getHeight());
|
||||||
|
|
||||||
|
setUniformf("u_time", Time.globalTime() / 10f);
|
||||||
|
setUniformf("u_campos", camera.position);
|
||||||
|
setUniformf("u_rcampos", Tmp.v31.set(camera.position).sub(planet.position));
|
||||||
|
setUniformf("u_light", planet.getLightNormal());
|
||||||
|
setUniformf("u_color", planet.atmosphereColor.r, planet.atmosphereColor.g, planet.atmosphereColor.b);
|
||||||
|
|
||||||
|
setUniformMatrix4("u_model", planet.getTransform(mat).val);
|
||||||
|
setUniformMatrix4("u_projection", camera.combined.val);
|
||||||
|
setUniformMatrix4("u_invproj", camera.invProjectionView.val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PlanetShader extends LoadShader{
|
public static class PlanetShader extends LoadShader{
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import arc.math.geom.*;
|
|||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import arc.util.*;
|
||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
@@ -49,6 +50,8 @@ public class Planet extends UnlockableContent{
|
|||||||
public boolean bloom = false;
|
public boolean bloom = false;
|
||||||
/** For suns, this is the color that shines on other planets. Does nothing for children. */
|
/** For suns, this is the color that shines on other planets. Does nothing for children. */
|
||||||
public Color lightColor = Color.white.cpy();
|
public Color lightColor = Color.white.cpy();
|
||||||
|
/** Atmosphere tint for landable planets. */
|
||||||
|
public Color atmosphereColor = new Color(0.3f, 0.7f, 1.0f);
|
||||||
/** Parent body that this planet orbits around. If null, this planet is considered to be in the middle of the solar system.*/
|
/** Parent body that this planet orbits around. If null, this planet is considered to be in the middle of the solar system.*/
|
||||||
public @Nullable Planet parent;
|
public @Nullable Planet parent;
|
||||||
/** The root parent of the whole solar system this planet is in. */
|
/** The root parent of the whole solar system this planet is in. */
|
||||||
@@ -128,6 +131,10 @@ public class Planet extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vec3 getLightNormal(){
|
||||||
|
return Tmp.v31.set(solarSystem.position).sub(position).nor();
|
||||||
|
}
|
||||||
|
|
||||||
/** Calculates orbital rotation based on universe time.*/
|
/** Calculates orbital rotation based on universe time.*/
|
||||||
public float getOrbitAngle(){
|
public float getOrbitAngle(){
|
||||||
//applies random offset to prevent planets from starting out in a line
|
//applies random offset to prevent planets from starting out in a line
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.ui.dialogs;
|
package mindustry.ui.dialogs;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
|
import arc.fx.util.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.graphics.g3d.*;
|
import arc.graphics.g3d.*;
|
||||||
@@ -51,7 +52,19 @@ public class PlanetDialog extends FloatingDialog{
|
|||||||
private Planet planet = Planets.starter;
|
private Planet planet = Planets.starter;
|
||||||
private float lastX, lastY;
|
private float lastX, lastY;
|
||||||
private @Nullable Sector selected, hovered;
|
private @Nullable Sector selected, hovered;
|
||||||
private Table stable, infoTable;
|
private Table stable;
|
||||||
|
private ScreenQuad quad = new ScreenQuad();
|
||||||
|
private Mesh atmosphere = MeshBuilder.buildHex(new HexMesher(){
|
||||||
|
@Override
|
||||||
|
public float getHeight(Vec3 position){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Color getColor(Vec3 position){
|
||||||
|
return Color.white;
|
||||||
|
}
|
||||||
|
}, 3, false, 1.5f, 0f);
|
||||||
|
|
||||||
public PlanetDialog(){
|
public PlanetDialog(){
|
||||||
super("", Styles.fullDialog);
|
super("", Styles.fullDialog);
|
||||||
@@ -103,17 +116,8 @@ public class PlanetDialog extends FloatingDialog{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
infoTable = new Table();
|
stable = new Table();
|
||||||
|
stable.background(Styles.black3);
|
||||||
stable = new Table(t -> {
|
|
||||||
t.background(Styles.black3);
|
|
||||||
t.margin(12f);
|
|
||||||
t.add("this is some arbitrary text.");
|
|
||||||
});
|
|
||||||
|
|
||||||
stable.act(1f);
|
|
||||||
stable.pack();
|
|
||||||
stable.setPosition(0, 0, Align.center);
|
|
||||||
|
|
||||||
shown(this::setup);
|
shown(this::setup);
|
||||||
}
|
}
|
||||||
@@ -145,14 +149,11 @@ public class PlanetDialog extends FloatingDialog{
|
|||||||
projector.proj(cam.combined());
|
projector.proj(cam.combined());
|
||||||
batch.proj(cam.combined());
|
batch.proj(cam.combined());
|
||||||
|
|
||||||
bloom.capture();
|
//bloom.capture();
|
||||||
|
|
||||||
renderPlanet(solarSystem);
|
renderPlanet(solarSystem);
|
||||||
if(planet.isLandable()){
|
|
||||||
renderSectors(planet);
|
|
||||||
}
|
|
||||||
|
|
||||||
bloom.render();
|
//bloom.render();
|
||||||
|
|
||||||
Gl.enable(Gl.blend);
|
Gl.enable(Gl.blend);
|
||||||
|
|
||||||
@@ -189,10 +190,28 @@ public class PlanetDialog extends FloatingDialog{
|
|||||||
private void renderPlanet(Planet planet){
|
private void renderPlanet(Planet planet){
|
||||||
//render planet at offsetted position in the world
|
//render planet at offsetted position in the world
|
||||||
|
|
||||||
planet.mesh.render(cam.combined(), planet.getTransform(mat));
|
planet.mesh.render(cam.combined, planet.getTransform(mat));
|
||||||
|
|
||||||
renderOrbit(planet);
|
renderOrbit(planet);
|
||||||
|
|
||||||
|
if(planet.isLandable() && planet == this.planet){
|
||||||
|
renderSectors(planet);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(planet.parent != null){
|
||||||
|
Gl.blendFunc(Gl.one, Gl.one);
|
||||||
|
Gl.enable(Gl.blend);
|
||||||
|
|
||||||
|
Shaders.atmosphere.camera = cam;
|
||||||
|
Shaders.atmosphere.planet = planet;
|
||||||
|
Shaders.atmosphere.bind();
|
||||||
|
Shaders.atmosphere.apply();
|
||||||
|
|
||||||
|
atmosphere.render(Shaders.atmosphere, Gl.triangles);
|
||||||
|
|
||||||
|
Gl.blendFunc(Blending.normal.src, Blending.normal.dst);
|
||||||
|
}
|
||||||
|
|
||||||
for(Planet child : planet.children){
|
for(Planet child : planet.children){
|
||||||
renderPlanet(child);
|
renderPlanet(child);
|
||||||
}
|
}
|
||||||
@@ -218,7 +237,7 @@ public class PlanetDialog extends FloatingDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(sec.hostility >= 0.02f){
|
if(sec.hostility >= 0.02f){
|
||||||
drawSelection(sec, Color.scarlet, 0.11f * sec.hostility);
|
//drawSelection(sec, Color.scarlet, 0.11f * sec.hostility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,6 +249,7 @@ public class PlanetDialog extends FloatingDialog{
|
|||||||
if(selected != null){
|
if(selected != null){
|
||||||
drawSelection(selected);
|
drawSelection(selected);
|
||||||
drawBorders(selected, borderColor);
|
drawBorders(selected, borderColor);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
batch.flush(Gl.triangles);
|
batch.flush(Gl.triangles);
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import mindustry.type.*;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.charset.*;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
@@ -31,15 +30,9 @@ import static mindustry.Vars.*;
|
|||||||
public class DesktopLauncher extends ClientLauncher{
|
public class DesktopLauncher extends ClientLauncher{
|
||||||
public final static String discordID = "610508934456934412";
|
public final static String discordID = "610508934456934412";
|
||||||
|
|
||||||
boolean useDiscord = OS.is64Bit, loadError = false;
|
boolean useDiscord = OS.is64Bit && !OS.hasProp("nodiscord"), loadError = false;
|
||||||
Throwable steamError;
|
Throwable steamError;
|
||||||
|
|
||||||
static{
|
|
||||||
if(!Charset.forName("US-ASCII").newEncoder().canEncode(System.getProperty("user.name", ""))){
|
|
||||||
System.setProperty("com.codedisaster.steamworks.SharedLibraryExtractPath", new File("").getAbsolutePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] arg){
|
public static void main(String[] arg){
|
||||||
try{
|
try{
|
||||||
Vars.loadLogger();
|
Vars.loadLogger();
|
||||||
|
|||||||
Reference in New Issue
Block a user