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
},
"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" : [

View File

@ -34,5 +34,11 @@ export const clientHooks: Hook[] = [
callback: (engine: Engine) => {
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
/**
* Spawns water at the player's cursor
*/
readonly spawnWater: () => void
}

View File

@ -1,36 +1,8 @@
#version 330 core
#define NR_POINT_LIGHTS 10
out vec4 FragColor;
#version 450 core
#extension GL_ARB_shading_language_include : require
#include "../../lib/lights.fs"
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 {
sampler2D diffuse;
@ -47,26 +19,12 @@ in vec4 FragPosLightSpace;
uniform vec3 viewPos;
// uniform DirLight dirLight;
// uniform PointLight pointLights[NR_POINT_LIGHTS];
// uniform SpotLight spotLight;
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
// 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);
void main(){
@ -80,14 +38,10 @@ void main(){
vec3 textureColor = vec3(0.6, 0.92, 0.92);//getColor(texPlane1, texPlane2, texPlane3, norm, material);
//shadow
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-dLDirection), norm);
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-directLight.direction), norm);
//calculate final color
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
FragColor = vec4(finalColor, 0.2);
@ -105,104 +59,3 @@ vec3 getColor(vec2 texPlane1, vec2 texPlane2, vec2 texPlane3, vec3 normal, Mater
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
Store characters in database
Spawn characters from database
Fluid spawning item
Fix fluid shader
Re-enable fluid simulation
# TODO

View File

@ -2,12 +2,14 @@ package electrosphere.client.script;
import org.graalvm.polyglot.HostAccess.Export;
import org.joml.Vector3d;
import org.joml.Vector3i;
import electrosphere.client.entity.camera.CameraEntityUtils;
import electrosphere.client.terrain.editing.TerrainEditing;
import electrosphere.collision.CollisionEngine;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
/**
* 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("1", new ToolbarItem(72, "spawningPalette"));
template.getCreatureToolbarData().setSlotItem("2", new ToolbarItem(73, "entityinspector"));
template.getCreatureToolbarData().setSlotItem("3", new ToolbarItem(74, "waterSpawner"));
//set player character template
serverPlayerConnection.setCreatureTemplate(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("1", new ToolbarItem(72, "spawningPalette"));
template.getCreatureToolbarData().setSlotItem("2", new ToolbarItem(73, "entityinspector"));
template.getCreatureToolbarData().setSlotItem("3", new ToolbarItem(74, "waterSpawner"));
//set player character template
connectionHandler.setCreatureTemplate(template);
} else {
@ -186,6 +187,7 @@ public class CharacterProtocol implements ServerProtocolTemplate<CharacterMessag
template.getCreatureToolbarData().setSlotItem("0", new ToolbarItem(71, "terrainTool"));
template.getCreatureToolbarData().setSlotItem("1", new ToolbarItem(72, "spawningPalette"));
template.getCreatureToolbarData().setSlotItem("2", new ToolbarItem(73, "entityinspector"));
template.getCreatureToolbarData().setSlotItem("3", new ToolbarItem(74, "waterSpawner"));
//set player character template
connectionHandler.setCreatureTemplate(template);
}

View File

@ -542,7 +542,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
Vector3i cellPos = this.getCellWorldPosition(cell);
boolean update = this.serverFluidManager.simulate(cellPos.x,cellPos.y,cellPos.z);
if(update){
rebroadcastFluidChunk(cellPos);
this.rebroadcastFluidChunk(cellPos);
}
}
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];
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;
}

View File

@ -79,6 +79,17 @@ public class ServerFluidChunk {
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
public float[][][] getVelocityX() {
return velocityX;

View File

@ -7,6 +7,7 @@ import electrosphere.server.fluid.diskmap.FluidDiskMap;
import electrosphere.server.fluid.generation.FluidGenerator;
import electrosphere.server.fluid.models.FluidModel;
import electrosphere.server.fluid.simulator.ServerFluidSimulator;
import electrosphere.server.fluid.simulator.cellularautomata.FluidCellularAutomataSimulator;
import electrosphere.server.terrain.manager.ServerTerrainChunk;
import electrosphere.server.terrain.manager.ServerTerrainManager;
import electrosphere.util.FileUtils;
@ -52,7 +53,7 @@ public class ServerFluidManager {
ServerTerrainManager serverTerrainManager;
//controls whether fluid simulation should actually happen or not
boolean simulate = true;
boolean simulate = false;
/**
* The parent world data
@ -75,6 +76,7 @@ public class ServerFluidManager {
this.chunkCacheContents = new CopyOnWriteArrayList<String>();
this.seed = seed;
this.chunkGenerator = chunkGenerator;
this.serverFluidSimulator = new FluidCellularAutomataSimulator();
}
ServerFluidManager(){
@ -85,14 +87,6 @@ public class ServerFluidManager {
* Generates a fluid model for the manager
*/
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);
// 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){
boolean rVal = false;
Globals.profiler.beginAggregateCpuSample("ServerFluidManager.simulate");
// if(simulate){
// ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ);
// ServerTerrainChunk terrainChunk = this.serverTerrainManager.getChunk(worldX, worldY, worldZ);
// if(fluidChunk != null && terrainChunk != null && this.serverFluidSimulator != null){
// rVal = this.serverFluidSimulator.simulate(fluidChunk,terrainChunk,worldX,worldY,worldZ);
// }
// }
if(simulate){
ServerFluidChunk fluidChunk = this.getChunk(worldX, worldY, worldZ);
ServerTerrainChunk terrainChunk = this.serverTerrainManager.getChunk(worldX, worldY, worldZ);
if(fluidChunk != null && terrainChunk != null && this.serverFluidSimulator != null){
rVal = this.serverFluidSimulator.simulate(fluidChunk,terrainChunk,worldX,worldY,worldZ);
}
}
Globals.profiler.endCpuSample();
return rVal;
}