Planet rendering refactoring

This commit is contained in:
Anuken
2021-09-16 14:18:17 -04:00
parent c9fa7356c2
commit ed911d87a3
14 changed files with 172 additions and 140 deletions

View File

@@ -95,6 +95,7 @@ public class Shaders{
public Vec3 lightDir = new Vec3(1, 1, 1).nor();
public Color ambientColor = Color.white.cpy();
public Vec3 camDir = new Vec3();
public Planet planet;
public PlanetShader(){
super("planet", "planet");
@@ -102,7 +103,7 @@ public class Shaders{
@Override
public void apply(){
camDir.set(renderer.planets.cam.direction).rotate(Vec3.Y, renderer.planets.planet.getRotation());
camDir.set(renderer.planets.cam.direction).rotate(Vec3.Y, planet.getRotation());
setUniformf("u_lightdir", lightDir);
setUniformf("u_ambientColor", ambientColor.r, ambientColor.g, ambientColor.b);
@@ -115,6 +116,7 @@ public class Shaders{
public Color ambientColor = Color.white.cpy();
public Vec3 camDir = new Vec3();
public float alpha = 1f;
public Planet planet;
public CloudShader(){
super("planet", "clouds");
@@ -122,7 +124,7 @@ public class Shaders{
@Override
public void apply(){
camDir.set(renderer.planets.cam.direction).rotate(Vec3.Y, renderer.planets.planet.getRotation());
camDir.set(renderer.planets.cam.direction).rotate(Vec3.Y, planet.getRotation());
setUniformf("u_alpha", alpha);
setUniformf("u_lightdir", lightDir);

View File

@@ -3,5 +3,5 @@ package mindustry.graphics.g3d;
import arc.math.geom.*;
public interface GenericMesh{
void render(Mat3D projection, Mat3D transform);
void render(PlanetParams params, Mat3D projection, Mat3D transform);
}

View File

@@ -19,7 +19,8 @@ public class HexMesh extends PlanetMesh{
}
@Override
public void preRender(){
public void preRender(PlanetParams params){
Shaders.planet.planet = planet;
Shaders.planet.lightDir.set(planet.solarSystem.position).sub(planet.position).rotate(Vec3.Y, planet.getRotation()).nor();
Shaders.planet.ambientColor.set(planet.solarSystem.lightColor);
}

View File

@@ -4,7 +4,6 @@ import arc.graphics.*;
import arc.math.geom.*;
import arc.util.*;
import arc.util.noise.*;
import mindustry.*;
import mindustry.graphics.*;
import mindustry.type.*;
@@ -42,8 +41,8 @@ public class HexSkyMesh extends PlanetMesh{
}
@Override
public void render(Mat3D projection, Mat3D transform){
preRender();
public void render(PlanetParams params, Mat3D projection, Mat3D transform){
preRender(params);
shader.bind();
shader.setUniformMatrix4("u_proj", projection.val);
shader.setUniformMatrix4("u_trans", mat.setToTranslation(planet.position).rotate(Vec3.Y, planet.getRotation() + relRot()).val);
@@ -52,9 +51,10 @@ public class HexSkyMesh extends PlanetMesh{
}
@Override
public void preRender(){
public void preRender(PlanetParams params){
Shaders.clouds.planet = planet;
Shaders.clouds.lightDir.set(planet.solarSystem.position).sub(planet.position).rotate(Vec3.Y, planet.getRotation() + relRot()).nor();
Shaders.clouds.ambientColor.set(planet.solarSystem.lightColor);
Shaders.clouds.alpha = 1f - Vars.ui.planet.planets.orbitAlpha;
Shaders.clouds.alpha = 1f - params.uiAlpha;
}
}

View File

@@ -16,7 +16,7 @@ public class MatMesh implements GenericMesh{
}
@Override
public void render(Mat3D projection, Mat3D transform){
mesh.render(projection, tmp.set(transform).mul(mat));
public void render(PlanetParams params, Mat3D projection, Mat3D transform){
mesh.render(params, projection, tmp.set(transform).mul(mat));
}
}

View File

@@ -10,9 +10,9 @@ public class MultiMesh implements GenericMesh{
}
@Override
public void render(Mat3D projection, Mat3D transform){
public void render(PlanetParams params, Mat3D projection, Mat3D transform){
for(var v : meshes){
v.render(projection, transform);
v.render(params, projection, transform);
}
}
}

View File

@@ -19,12 +19,15 @@ public abstract class PlanetMesh implements GenericMesh{
public PlanetMesh(){}
/** Should be overridden to set up any shader parameters such as planet position, normals, etc. */
public abstract void preRender();
/** Should be overridden to set up any shader parameters such as planet position, normals, etc.
* @param params*/
public void preRender(PlanetParams params){
}
@Override
public void render(Mat3D projection, Mat3D transform){
preRender();
public void render(PlanetParams params, Mat3D projection, Mat3D transform){
preRender(params);
shader.bind();
shader.setUniformMatrix4("u_proj", projection.val);
shader.setUniformMatrix4("u_trans", transform.val);

View File

@@ -0,0 +1,35 @@
package mindustry.graphics.g3d;
import arc.math.geom.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.graphics.g3d.PlanetRenderer.*;
import mindustry.type.*;
/** Parameters for rendering a solar system. */
public class PlanetParams{
/** Camera direction relative to the planet. Length is determined by zoom. */
public Vec3 camPos = new Vec3(0f, 0f, 4f);
/** Camera up vector. */
public Vec3 camUp = new Vec3(0f, 1f, 0f);
/** the unit length direction vector of the camera **/
public Vec3 camDir = new Vec3(0, 0, -1);
/** The sun/main planet of the solar system from which everything is rendered. */
public Planet solarSystem = Planets.sun;
/** Planet being looked at. */
public Planet planet = Planets.serpulo;
/** Zoom relative to planet. */
public float zoom = 1f;
/** Alpha of orbit rings and other UI elements. */
public float uiAlpha = 1f;
/** If false, orbit and sector grid are not drawn. */
public boolean drawUi = false;
/** If true, a space skybox is drawn. */
public boolean drawSkybox = true;
/** Handles drawing details. */
public @Nullable transient PlanetInterfaceRenderer renderer;
//TODO:
//- blur
//- transparent background
}

View File

@@ -9,7 +9,6 @@ import arc.math.*;
import arc.math.geom.*;
import arc.struct.*;
import arc.util.*;
import mindustry.content.*;
import mindustry.game.EventType.*;
import mindustry.graphics.*;
import mindustry.graphics.g3d.PlanetGrid.*;
@@ -25,25 +24,15 @@ public class PlanetRenderer implements Disposable{
private static final Seq<Vec3> points = new Seq<>();
/** Camera direction relative to the planet. Length is determined by zoom. */
public final Vec3 camPos = new Vec3();
/** The sun/main planet of the solar system from which everything is rendered. */
public final Planet solarSystem = Planets.sun;
/** Planet being looked at. */
public Planet planet = Planets.serpulo;
/** Camera used for rendering. */
public Camera3D cam = new Camera3D();
public final Camera3D cam = new Camera3D();
/** Raw vertex batch. */
public final VertexBatch3D batch = new VertexBatch3D(20000, false, true, 0);
public float zoom = 1f;
public float orbitAlpha = 1f;
private final Mesh[] outlines = new Mesh[10];
public final PlaneBatch3D projector = new PlaneBatch3D();
public final Mat3D mat = new Mat3D();
public final FrameBuffer buffer = new FrameBuffer(2, 2, true);
public PlanetInterfaceRenderer irenderer;
public final Bloom bloom = new Bloom(Core.graphics.getWidth()/4, Core.graphics.getHeight()/4, true, false){{
setThreshold(0.8f);
@@ -55,16 +44,13 @@ public class PlanetRenderer implements Disposable{
public final CubemapMesh skybox = new CubemapMesh(new Cubemap("cubemaps/stars/"));
public PlanetRenderer(){
camPos.set(0, 0f, camLength);
projector.setScaling(1f / 150f);
cam.fov = 60f;
cam.far = 150f;
}
/** Render the entire planet scene to the screen. */
public void render(PlanetInterfaceRenderer irenderer){
this.irenderer = irenderer;
public void render(PlanetParams params){
Draw.flush();
Gl.clear(Gl.depthBufferBit);
Gl.enable(Gl.depthTest);
@@ -73,14 +59,20 @@ public class PlanetRenderer implements Disposable{
Gl.enable(Gl.cullFace);
Gl.cullFace(Gl.back);
bloom.blending = !params.drawSkybox;
//lock to up vector so it doesn't get confusing
cam.up.set(Vec3.Y);
cam.resize(Core.graphics.getWidth(), Core.graphics.getHeight());
camPos.setLength((planet.radius + planet.camRadius) * camLength + (zoom-1f) * (planet.radius + planet.camRadius) * 2);
cam.position.set(planet.position).add(camPos);
cam.lookAt(planet.position);
params.camPos.setLength((params.planet.radius + params.planet.camRadius) * camLength + (params.zoom-1f) * (params.planet.radius + params.planet.camRadius) * 2);
cam.position.set(params.planet.position).add(params.camPos);
//cam.up.set(params.camUp); //TODO broken
cam.lookAt(params.planet.position);
cam.update();
//write back once it changes.
params.camUp.set(cam.up);
params.camDir.set(cam.direction);
projector.proj(cam.combined);
batch.proj(cam.combined);
@@ -89,25 +81,26 @@ public class PlanetRenderer implements Disposable{
beginBloom();
//render skybox at 0,0,0
Vec3 lastPos = Tmp.v31.set(cam.position);
cam.position.setZero();
cam.update();
if(params.drawSkybox){
//render skybox at 0,0,0
Vec3 lastPos = Tmp.v31.set(cam.position);
cam.position.setZero();
cam.update();
Gl.depthMask(false);
Gl.depthMask(false);
skybox.render(cam.combined);
skybox.render(cam.combined);
Gl.depthMask(true);
Gl.depthMask(true);
cam.position.set(lastPos);
cam.update();
cam.position.set(lastPos);
cam.update();
}
Events.fire(Trigger.universeDraw);
renderPlanet(solarSystem);
renderTransparent(solarSystem);
renderPlanet(params.solarSystem, params);
renderTransparent(params.solarSystem, params);
endBloom();
@@ -115,7 +108,9 @@ public class PlanetRenderer implements Disposable{
Gl.enable(Gl.blend);
irenderer.renderProjections(planet);
if(params.renderer != null){
params.renderer.renderProjections(params.planet);
}
Gl.disable(Gl.cullFace);
Gl.disable(Gl.depthTest);
@@ -133,28 +128,28 @@ public class PlanetRenderer implements Disposable{
}
public void renderPlanet(Planet planet){
public void renderPlanet(Planet planet, PlanetParams params){
if(!planet.visible()) return;
cam.update();
if(cam.frustum.containsSphere(planet.position, planet.clipRadius)){
//render planet at offsetted position in the world
planet.draw(cam.combined, planet.getTransform(mat));
planet.draw(params, cam.combined, planet.getTransform(mat));
}
for(Planet child : planet.children){
renderPlanet(child);
renderPlanet(child, params);
}
}
public void renderTransparent(Planet planet){
public void renderTransparent(Planet planet, PlanetParams params){
if(!planet.visible()) return;
planet.drawClouds(cam.combined, planet.getTransform(mat));
planet.drawClouds(params, cam.combined, planet.getTransform(mat));
if(planet.hasGrid() && planet == this.planet){
renderSectors(planet);
if(planet.hasGrid() && planet == params.planet && params.drawUi){
renderSectors(planet, params);
}
if(cam.frustum.containsSphere(planet.position, planet.clipRadius) && planet.parent != null && planet.hasAtmosphere && Core.settings.getBool("atmosphere")){
@@ -162,31 +157,35 @@ public class PlanetRenderer implements Disposable{
}
for(Planet child : planet.children){
renderTransparent(child);
renderTransparent(child, params);
}
batch.proj(cam.combined);
renderOrbit(planet);
if(params.drawUi){
renderOrbit(planet, params);
}
}
public void renderOrbit(Planet planet){
if(planet.parent == null || !planet.visible() || orbitAlpha <= 0.02f || !planet.drawOrbit) return;
public void renderOrbit(Planet planet, PlanetParams params){
if(planet.parent == null || !planet.visible() || params.uiAlpha <= 0.02f || !planet.drawOrbit) return;
Vec3 center = planet.parent.position;
float radius = planet.orbitRadius;
int points = (int)(radius * 10);
Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray.write(Tmp.c1).a(orbitAlpha)));
Angles.circleVectors(points, radius, (cx, cy) -> batch.vertex(Tmp.v32.set(center).add(cx, 0, cy), Pal.gray.write(Tmp.c1).a(params.uiAlpha)));
batch.flush(Gl.lineLoop);
}
public void renderSectors(Planet planet){
if(orbitAlpha <= 0.02f) return;
public void renderSectors(Planet planet, PlanetParams params){
if(params.uiAlpha <= 0.02f) return;
//apply transformed position
batch.proj().mul(planet.getTransform(mat));
irenderer.renderSectors(planet);
if(params.renderer != null){
params.renderer.renderSectors(planet);
}
//render sector grid
Mesh mesh = outline(planet.grid.size);
@@ -264,12 +263,12 @@ public class PlanetRenderer implements Disposable{
}
public void setPlane(Sector sector){
float rotation = -planet.getRotation();
float rotation = -sector.planet.getRotation();
float length = 0.01f;
projector.setPlane(
//origin on sector position
Tmp.v33.set(sector.tile.v).setLength(outlineRad + length).rotate(Vec3.Y, rotation).add(planet.position),
Tmp.v33.set(sector.tile.v).setLength(outlineRad + length).rotate(Vec3.Y, rotation).add(sector.planet.position),
//face up
sector.plane.project(Tmp.v32.set(sector.tile.v).add(Vec3.Y)).sub(sector.tile.v).rotate(Vec3.Y, rotation).nor(),
//right vector

View File

@@ -8,9 +8,4 @@ public class ShaderSphereMesh extends PlanetMesh{
public ShaderSphereMesh(Planet planet, Shader shader, int divisions){
super(planet, MeshBuilder.buildIcosphere(divisions, planet.radius), shader);
}
@Override
public void preRender(){
}
}

View File

@@ -25,9 +25,4 @@ public class SunMesh extends HexMesh{
}
}, divisions, Shaders.unlit);
}
@Override
public void preRender(){
//do absolutely nothing
}
}