fluid work
Some checks reported errors
studiorailgun/Renderer/pipeline/head Something is wrong with the build of this commit

This commit is contained in:
austin 2024-11-29 21:19:59 -05:00
parent 080cdeca33
commit dfc59e0ea6
12 changed files with 110 additions and 176 deletions

View File

@ -92,6 +92,36 @@
"offsetZ" : 0 "offsetZ" : 0
}, },
"iconPath" : "Textures/icons/itemIconItemGeneric.png" "iconPath" : "Textures/icons/itemIconItemGeneric.png"
},
{
"id" : "waterSpawner",
"tokens" : [
"GRAVITY",
"TARGETABLE"
],
"equipData": {
"equipClass" : "tool"
},
"graphicsTemplate": {
"model": {
"path" : "Models/basic/geometry/unitvector.glb"
}
},
"clientSideSecondary": "SPAWN_WATER",
"collidable": {
"type" : "CUBE",
"dimension1" : 0.1,
"dimension2" : 0.1,
"dimension3" : 0.35,
"rotX": 0,
"rotY": 0,
"rotZ": 0,
"rotW": 1,
"offsetX" : 0,
"offsetY" : 0.05,
"offsetZ" : 0
},
"iconPath" : "Textures/icons/itemIconItemGeneric.png"
} }
], ],
"files" : [ "files" : [

View File

@ -34,5 +34,11 @@ export const clientHooks: Hook[] = [
callback: (engine: Engine) => { callback: (engine: Engine) => {
engine.classes.levelEditorUtils.static.inspectEntity() engine.classes.levelEditorUtils.static.inspectEntity()
} }
},
{
signal: "SPAWN_WATER",
callback: (engine: Engine) => {
engine.classes.voxelUtils.static.spawnWater()
}
} }
] ]

View File

@ -8,4 +8,9 @@ export interface ClientVoxelUtils {
*/ */
readonly applyEdit: () => void readonly applyEdit: () => void
/**
* Spawns water at the player's cursor
*/
readonly spawnWater: () => void
} }

View File

@ -1,36 +1,8 @@
#version 330 core #version 450 core
#extension GL_ARB_shading_language_include : require
#define NR_POINT_LIGHTS 10 #include "../../lib/lights.fs"
out vec4 FragColor;
layout (std140) uniform Lights {
// this is how many because we have to align
// bytes it SHOULD in multiples of 16, this
// take it where it ACTUALLY is
//
//refer: https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL
//
// base alignment aligned offset
//direct light
vec3 dLDirection; // 16 0
vec3 dLAmbient; // 16 16
vec3 dLDiffuse; // 16 32
vec3 dLSpecular; // 16 48
//point light
vec3 pLposition[NR_POINT_LIGHTS]; // 16*10 64
float pLconstant[NR_POINT_LIGHTS]; // 16*10 224
float pLlinear[NR_POINT_LIGHTS]; // 16*10 384
float pLquadratic[NR_POINT_LIGHTS]; // 16*10 544
vec3 pLambient[NR_POINT_LIGHTS]; // 16*10 704
vec3 pLdiffuse[NR_POINT_LIGHTS]; // 16*10 864
vec3 pLspecular[NR_POINT_LIGHTS]; // 16*10 1024
//for a total size of 1184
};
struct Material { struct Material {
sampler2D diffuse; sampler2D diffuse;
@ -47,26 +19,12 @@ in vec4 FragPosLightSpace;
uniform vec3 viewPos; uniform vec3 viewPos;
// uniform DirLight dirLight;
// uniform PointLight pointLights[NR_POINT_LIGHTS];
// uniform SpotLight spotLight;
uniform Material material; uniform Material material;
//texture stuff
// uniform sampler2D ourTexture;
uniform int hasTransparency;
// uniform sampler2D specularTexture;
//light depth map
uniform sampler2D shadowMap;
out vec4 FragColor;
// function prototypes // function prototypes
// vec3 CalcDirLight(vec3 normal, vec3 viewDir);
// vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir);
// vec3 CalcSpotLight(vec3 normal, vec3 fragPos, vec3 viewDir);
float calcLightIntensityTotal(vec3 normal);
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal);
vec3 getColor(vec2 texPlane1, vec2 texPlane2, vec2 texPlane3, vec3 normal, Material material); vec3 getColor(vec2 texPlane1, vec2 texPlane2, vec2 texPlane3, vec3 normal, Material material);
void main(){ void main(){
@ -80,14 +38,10 @@ void main(){
vec3 textureColor = vec3(0.6, 0.92, 0.92);//getColor(texPlane1, texPlane2, texPlane3, norm, material); vec3 textureColor = vec3(0.6, 0.92, 0.92);//getColor(texPlane1, texPlane2, texPlane3, norm, material);
//shadow //shadow
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-dLDirection), norm); float shadow = ShadowCalculation(FragPosLightSpace, normalize(-directLight.direction), norm);
//calculate final color //calculate final color
vec3 finalColor = textureColor * lightIntensity * max(shadow,0.4); vec3 finalColor = textureColor * lightIntensity * max(shadow,0.4);
// vec3 lightAmount = CalcDirLight(norm, viewDir);
// for(int i = 0; i < NR_POINT_LIGHTS; i++){
// lightAmount += CalcPointLight(i, norm, FragPos, viewDir);
// }
//this final calculation is for transparency //this final calculation is for transparency
FragColor = vec4(finalColor, 0.2); FragColor = vec4(finalColor, 0.2);
@ -104,105 +58,4 @@ vec3 getColor(vec2 texPlane1, vec2 texPlane2, vec2 texPlane3, vec3 normal, Mater
return (albedoX * weights.x + albedoY * weights.y + albedoZ * weights.z); return (albedoX * weights.x + albedoY * weights.y + albedoZ * weights.z);
}
//
float calcLightIntensityAmbient(){
//calculate average of ambient light
float avg = (dLAmbient.x + dLAmbient.y + dLAmbient.z)/3.0;
return avg;
}
//
float calcLightIntensityDir(vec3 normal){
vec3 lightDir = normalize(-dLDirection);
// diffuse shading
float diff = max(dot(normal, lightDir), 0.0);
return diff;
}
//
float calcLightIntensityTotal(vec3 normal){
//ambient intensity
float ambientLightIntensity = calcLightIntensityAmbient();
//get direct intensity
float directLightIntensity = calcLightIntensityDir(normal);
//sum
float total = ambientLightIntensity + directLightIntensity;
return total;
}
//
vec3 getTotalLightColor(vec3 normal){
//get the direct light color adjusted for intensity
vec3 diffuseLightColor = dLDiffuse * calcLightIntensityDir(normal);
//sum light colors
vec3 totalLightColor = diffuseLightColor;
return totalLightColor;
}
vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){
vec3 lightDir = normalize(pLposition[i] - fragPos);
// diffuse shading
float diff = max(dot(normal, lightDir), 0.0);
// specular shading
// vec3 reflectDir = reflect(-lightDir, normal);
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
// attenuation
float distance = length(pLposition[i] - fragPos);
float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (distance * distance));
// combine results
vec3 ambient = pLambient[i];
vec3 diffuse = pLdiffuse[i] * diff;
ambient *= attenuation;
diffuse *= attenuation;
// specular *= attenuation;
vec3 specular = vec3(0,0,0);
vec3 finalValue = (ambient + diffuse + specular);
finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
return finalValue;
}
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){
// perform perspective divide
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
//transform to NDC
projCoords = projCoords * 0.5 + 0.5;
//get closest depth from light's POV
float closestDepth = texture(shadowMap, projCoords.xy).r;
//get depth of current fragment
float currentDepth = projCoords.z;
//calculate bias
float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005);
//calculate shadow value
float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
if(projCoords.z > 1.0){
shadow = 0.0;
}
//calculate dot product, if it is >0 we know they're parallel-ish therefore should disregard the shadow mapping
//ie the fragment is already facing away from the light source
float dotprod = dot(normalize(lightDir),normalize(normal));
if(dotprod > 0.0){
shadow = 0.0;
}
// shadow = currentDepth;
return shadow;
} }

View File

@ -1186,6 +1186,9 @@ Fix AABB calculation from assimp-loaded models
Fix singleplayer launching at all Fix singleplayer launching at all
Store characters in database Store characters in database
Spawn characters from database Spawn characters from database
Fluid spawning item
Fix fluid shader
Re-enable fluid simulation
# TODO # TODO

View File

@ -2,12 +2,14 @@ package electrosphere.client.script;
import org.graalvm.polyglot.HostAccess.Export; import org.graalvm.polyglot.HostAccess.Export;
import org.joml.Vector3d; import org.joml.Vector3d;
import org.joml.Vector3i;
import electrosphere.client.entity.camera.CameraEntityUtils; import electrosphere.client.entity.camera.CameraEntityUtils;
import electrosphere.client.terrain.editing.TerrainEditing; import electrosphere.client.terrain.editing.TerrainEditing;
import electrosphere.collision.CollisionEngine; import electrosphere.collision.CollisionEngine;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
/** /**
* Utilities for interacting with voxels from the client * Utilities for interacting with voxels from the client
@ -39,4 +41,36 @@ public class ScriptClientVoxelUtils {
} }
} }
/**
* Applies the current voxel palette where the player's cursor is looking
*/
@Export
public static void spawnWater(){
CollisionEngine collisionEngine = Globals.clientSceneWrapper.getCollisionEngine();
Entity camera = Globals.playerCamera;
if(
collisionEngine != null &&
camera != null &&
Globals.realmManager != null &&
Globals.realmManager.first() != null &&
Globals.realmManager.first().getServerWorldData() != null &&
Globals.realmManager.first().getServerWorldData().getServerFluidManager() != null
){
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(camera));
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(camera));
Vector3d cursorPos = collisionEngine.rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), CollisionEngine.DEFAULT_INTERACT_DISTANCE);
Vector3i worldPos = new Vector3i(
(int)(cursorPos.x / ServerTerrainChunk.CHUNK_DIMENSION),
(int)(cursorPos.y / ServerTerrainChunk.CHUNK_DIMENSION),
(int)(cursorPos.z / ServerTerrainChunk.CHUNK_DIMENSION)
);
Vector3i voxelPos = new Vector3i(
(int)(cursorPos.x % ServerTerrainChunk.CHUNK_DIMENSION),
(int)(cursorPos.y % ServerTerrainChunk.CHUNK_DIMENSION),
(int)(cursorPos.z % ServerTerrainChunk.CHUNK_DIMENSION)
);
Globals.realmManager.first().getServerWorldData().getServerFluidManager().deformFluidAtLocationToValue(worldPos, voxelPos, 1.0f, 0);
}
}
} }

View File

@ -166,6 +166,7 @@ public class LoadingUtils {
template.getCreatureToolbarData().setSlotItem("0", new ToolbarItem(71, "terrainTool")); template.getCreatureToolbarData().setSlotItem("0", new ToolbarItem(71, "terrainTool"));
template.getCreatureToolbarData().setSlotItem("1", new ToolbarItem(72, "spawningPalette")); template.getCreatureToolbarData().setSlotItem("1", new ToolbarItem(72, "spawningPalette"));
template.getCreatureToolbarData().setSlotItem("2", new ToolbarItem(73, "entityinspector")); template.getCreatureToolbarData().setSlotItem("2", new ToolbarItem(73, "entityinspector"));
template.getCreatureToolbarData().setSlotItem("3", new ToolbarItem(74, "waterSpawner"));
//set player character template //set player character template
serverPlayerConnection.setCreatureTemplate(template); serverPlayerConnection.setCreatureTemplate(template);
Globals.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestSpawnCharacterMessage(CharacterProtocol.SPAWN_EXISTING_TEMPLATE + "")); Globals.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestSpawnCharacterMessage(CharacterProtocol.SPAWN_EXISTING_TEMPLATE + ""));

View File

@ -166,6 +166,7 @@ public class CharacterProtocol implements ServerProtocolTemplate<CharacterMessag
template.getCreatureToolbarData().setSlotItem("0", new ToolbarItem(71, "terrainTool")); template.getCreatureToolbarData().setSlotItem("0", new ToolbarItem(71, "terrainTool"));
template.getCreatureToolbarData().setSlotItem("1", new ToolbarItem(72, "spawningPalette")); template.getCreatureToolbarData().setSlotItem("1", new ToolbarItem(72, "spawningPalette"));
template.getCreatureToolbarData().setSlotItem("2", new ToolbarItem(73, "entityinspector")); template.getCreatureToolbarData().setSlotItem("2", new ToolbarItem(73, "entityinspector"));
template.getCreatureToolbarData().setSlotItem("3", new ToolbarItem(74, "waterSpawner"));
//set player character template //set player character template
connectionHandler.setCreatureTemplate(template); connectionHandler.setCreatureTemplate(template);
} else { } else {
@ -186,6 +187,7 @@ public class CharacterProtocol implements ServerProtocolTemplate<CharacterMessag
template.getCreatureToolbarData().setSlotItem("0", new ToolbarItem(71, "terrainTool")); template.getCreatureToolbarData().setSlotItem("0", new ToolbarItem(71, "terrainTool"));
template.getCreatureToolbarData().setSlotItem("1", new ToolbarItem(72, "spawningPalette")); template.getCreatureToolbarData().setSlotItem("1", new ToolbarItem(72, "spawningPalette"));
template.getCreatureToolbarData().setSlotItem("2", new ToolbarItem(73, "entityinspector")); template.getCreatureToolbarData().setSlotItem("2", new ToolbarItem(73, "entityinspector"));
template.getCreatureToolbarData().setSlotItem("3", new ToolbarItem(74, "waterSpawner"));
//set player character template //set player character template
connectionHandler.setCreatureTemplate(template); connectionHandler.setCreatureTemplate(template);
} }

View File

@ -542,7 +542,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
Vector3i cellPos = this.getCellWorldPosition(cell); Vector3i cellPos = this.getCellWorldPosition(cell);
boolean update = this.serverFluidManager.simulate(cellPos.x,cellPos.y,cellPos.z); boolean update = this.serverFluidManager.simulate(cellPos.x,cellPos.y,cellPos.z);
if(update){ if(update){
rebroadcastFluidChunk(cellPos); this.rebroadcastFluidChunk(cellPos);
} }
} }
loadedCellsLock.release(); loadedCellsLock.release();

View File

@ -14,13 +14,6 @@ public class DefaultFluidGenerator implements FluidGenerator {
float[][][] velocityZ = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION]; float[][][] velocityZ = new float[ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION][ServerTerrainChunk.CHUNK_DIMENSION];
ServerFluidChunk chunk = new ServerFluidChunk(worldX, worldY, worldZ, weights, velocityX, velocityY, velocityZ); ServerFluidChunk chunk = new ServerFluidChunk(worldX, worldY, worldZ, weights, velocityX, velocityY, velocityZ);
for(int x = 0; x < ServerTerrainChunk.CHUNK_DIMENSION; x++){
for(int y = 0; y < ServerTerrainChunk.CHUNK_DIMENSION; y++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DIMENSION; z++){
weights[x][y][z] = 0f;
}
}
}
return chunk; return chunk;
} }

View File

@ -79,6 +79,17 @@ public class ServerFluidChunk {
return weights[x][y][z]; return weights[x][y][z];
} }
/**
* Sets a weight
* @param x The x coordinate
* @param y The y coordinate
* @param z The z coordinate
* @param weight The weight
*/
public void setWeight(int x, int y, int z, float weight){
weights[x][y][z] = weight;
}
//get velocity x //get velocity x
public float[][][] getVelocityX() { public float[][][] getVelocityX() {
return velocityX; return velocityX;

View File

@ -7,6 +7,7 @@ import electrosphere.server.fluid.diskmap.FluidDiskMap;
import electrosphere.server.fluid.generation.FluidGenerator; import electrosphere.server.fluid.generation.FluidGenerator;
import electrosphere.server.fluid.models.FluidModel; import electrosphere.server.fluid.models.FluidModel;
import electrosphere.server.fluid.simulator.ServerFluidSimulator; import electrosphere.server.fluid.simulator.ServerFluidSimulator;
import electrosphere.server.fluid.simulator.cellularautomata.FluidCellularAutomataSimulator;
import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.server.terrain.manager.ServerTerrainChunk;
import electrosphere.server.terrain.manager.ServerTerrainManager; import electrosphere.server.terrain.manager.ServerTerrainManager;
import electrosphere.util.FileUtils; import electrosphere.util.FileUtils;
@ -52,7 +53,7 @@ public class ServerFluidManager {
ServerTerrainManager serverTerrainManager; ServerTerrainManager serverTerrainManager;
//controls whether fluid simulation should actually happen or not //controls whether fluid simulation should actually happen or not
boolean simulate = true; boolean simulate = false;
/** /**
* The parent world data * The parent world data
@ -75,6 +76,7 @@ public class ServerFluidManager {
this.chunkCacheContents = new CopyOnWriteArrayList<String>(); this.chunkCacheContents = new CopyOnWriteArrayList<String>();
this.seed = seed; this.seed = seed;
this.chunkGenerator = chunkGenerator; this.chunkGenerator = chunkGenerator;
this.serverFluidSimulator = new FluidCellularAutomataSimulator();
} }
ServerFluidManager(){ ServerFluidManager(){
@ -85,14 +87,6 @@ public class ServerFluidManager {
* Generates a fluid model for the manager * Generates a fluid model for the manager
*/ */
public void generate(){ public void generate(){
// FluidGenerator terrainGen = new FluidGenerator();
// terrainGen.setInterpolationRatio(worldSizeDiscrete/200);
// terrainGen.setVerticalInterpolationRatio(verticalInterpolationRatio);
// terrainGen.setRandomSeed(seed);
// model = terrainGen.generateModel();
// this.chunkGenerator.setModel(model);
// model.setInterpolationRandomDampener(interpolationRandomDampener);
// this.chunkDiskMap = new ChunkDiskMap();
} }
/** /**
@ -265,6 +259,8 @@ public class ServerFluidManager {
// ServerFluidChunk chunk = chunkCache.get(key); // ServerFluidChunk chunk = chunkCache.get(key);
// chunk.addModification(modification); // chunk.addModification(modification);
// } // }
ServerFluidChunk fluidChunk = this.getChunk(worldPos.x, worldPos.y, worldPos.z);
fluidChunk.setWeight(voxelPos.x, voxelPos.y, voxelPos.z, weight);
} }
/** /**
@ -273,13 +269,13 @@ public class ServerFluidManager {
public boolean simulate(int worldX, int worldY, int worldZ){ public boolean simulate(int worldX, int worldY, int worldZ){
boolean rVal = false; boolean rVal = false;
Globals.profiler.beginAggregateCpuSample("ServerFluidManager.simulate"); Globals.profiler.beginAggregateCpuSample("ServerFluidManager.simulate");
// if(simulate){ if(simulate){
// ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ); ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ);
// ServerTerrainChunk terrainChunk = this.serverTerrainManager.getChunk(worldX, worldY, worldZ); ServerTerrainChunk terrainChunk = this.serverTerrainManager.getChunk(worldX, worldY, worldZ);
// if(fluidChunk != null && terrainChunk != null && this.serverFluidSimulator != null){ if(fluidChunk != null && terrainChunk != null && this.serverFluidSimulator != null){
// rVal = this.serverFluidSimulator.simulate(fluidChunk,terrainChunk,worldX,worldY,worldZ); rVal = this.serverFluidSimulator.simulate(fluidChunk,terrainChunk,worldX,worldY,worldZ);
// } }
// } }
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
return rVal; return rVal;
} }