diff --git a/assets/Shaders/entities/skysphere/skysphere.fs b/assets/Shaders/entities/skysphere/skysphere.fs index 5dd9b44e..75a0c461 100644 --- a/assets/Shaders/entities/skysphere/skysphere.fs +++ b/assets/Shaders/entities/skysphere/skysphere.fs @@ -3,90 +3,45 @@ #version 450 core #extension GL_ARB_shading_language_include : require #include "../../lib/standarduniform.fs" +#include "../../lib/math.fs" -/** -Bind points for different SSBOs -*/ -#define DIRECT_LIGHT_SSBO_BIND_POINT 3 - /** transparency */ #define SMALL_EPSILON 0.001 -/** -The direct global light -*/ -struct DirectLight { - vec3 direction; - vec3 color; - vec3 ambientColor; -}; - - -out vec4 FragColor; - -layout(std430, binding = DIRECT_LIGHT_SSBO_BIND_POINT) restrict buffer dirLightSSBO { - DirectLight directLight; -}; - -struct Material { - sampler2D diffuse; - sampler2D specular; - float shininess; -}; +#define EASING_POWER 5 in vec3 FragPos; in vec3 Normal; -in vec2 TexCoord; -in vec4 FragPosLightSpace; uniform vec3 viewPos; -uniform Material material; - -//texture stuff -// uniform sampler2D ourTexture; -uniform int hasTransparency; -// uniform sampler2D specularTexture; //light depth map uniform sampler2D shadowMap; -// function prototypes -float calcLightIntensityTotal(vec3 normal); +out vec4 FragColor; void main(){ - if(hasTransparency == 1){ - if(texture(material.diffuse, TexCoord).a < 0.1){ - discard; - } - } - vec4 textureColor = texture(material.diffuse, TexCoord); - //grab light intensity vec3 norm = normalize(Normal); - vec3 lightIntensity = vec3(calcLightIntensityTotal(norm)); + + //colors for different times of day + vec3 color1 = vec3(0,0,0); + vec3 color2= vec3(0.68,0.93,0.93); + + //calculate color + float timeOfDay = standardUniforms.timeOfDay; + vec3 skyColor = mix( + color1, + color2, + abs((0.5 - timeOfDay)) * 2 + ); //calculate final color - vec3 finalColor = textureColor.rgb * lightIntensity; - FragColor = vec4(finalColor, textureColor.a); + vec3 finalColor = skyColor;//norm.rgb; + FragColor = vec4(finalColor, 1); } - -float calcLightIntensityAmbient(){ - //calculate average of ambient light - float avg = (directLight.color.x + directLight.color.y + directLight.color.z)/3.0; - return avg; -} - -// -float calcLightIntensityTotal(vec3 normal){ - //ambient intensity - float ambientLightIntensity = calcLightIntensityAmbient(); - - //sum - float total = ambientLightIntensity; - return total; -} \ No newline at end of file diff --git a/assets/Shaders/entities/skysphere/skysphere.vs b/assets/Shaders/entities/skysphere/skysphere.vs index 723c5741..b6273a9c 100644 --- a/assets/Shaders/entities/skysphere/skysphere.vs +++ b/assets/Shaders/entities/skysphere/skysphere.vs @@ -18,9 +18,6 @@ uniform mat4 model; //output buffers out vec3 Normal; out vec3 FragPos; -out vec3 ViewFragPos; -out vec2 TexCoord; -out vec4 FragPosLightSpace; @@ -30,16 +27,18 @@ void main() { vec4 FinalVertex = vec4(aPos, 1.0); vec4 FinalNormal = vec4(aNormal, 1.0); + //time-of-day normal rotation + float angle = 3.14 * standardUniforms.timeOfDay; + mat4 rotationAboutZ = mat4( + vec4( cos(angle), -sin(angle), 0.0, 0.0 ), + vec4( sin(angle), cos(angle), 0.0, 0.0 ), + vec4( 0.0, 0.0, 1.0, 0.0 ), + vec4( 0.0, 0.0, 0.0, 1.0 ) ); + //push frag, normal, and texture positions to fragment shader FragPos = vec3(model * FinalVertex); - ViewFragPos = vec3(standardUniforms.view * model * FinalVertex); - Normal = mat3(transpose(inverse(model))) * aNormal; - TexCoord = aTex; - - - //shadow map stuff - FragPosLightSpace = standardUniforms.lightSpaceMatrix * vec4(FragPos, 1.0); + Normal = mat3(transpose(inverse(model))) * mat3(rotationAboutZ) * aNormal; //set final position with opengl space diff --git a/assets/Shaders/lib/math.fs b/assets/Shaders/lib/math.fs new file mode 100644 index 00000000..36fa86a9 --- /dev/null +++ b/assets/Shaders/lib/math.fs @@ -0,0 +1,18 @@ + +/** + * Standard math functions + */ + +/** + * Eases in a value at a given power + */ +float easeInPow(float value, int power){ + return pow(value,power); +} + +/** + * Eases in a value at a given power + */ +float easeOutPow(float value, int power){ + return 1.0f - pow(value,power); +} diff --git a/assets/Shaders/lib/standarduniform.fs b/assets/Shaders/lib/standarduniform.fs index 4b0de5c2..8ac0e87e 100644 --- a/assets/Shaders/lib/standarduniform.fs +++ b/assets/Shaders/lib/standarduniform.fs @@ -32,6 +32,10 @@ struct StandardUniforms { * The current engine time */ float time; + /** + * The time of day of the engine (range 0->1) + */ + float timeOfDay; }; /** diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 729402f0..54ef542f 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -2082,6 +2082,7 @@ Bounding sphere work Don't allocate contact joints for geom-geom Remove potential collision engine footgun Synchronized time-of-day between server and client +Skybox reflects time of day diff --git a/src/main/java/electrosphere/client/service/ClientTemporalService.java b/src/main/java/electrosphere/client/service/ClientTemporalService.java index cb423a0a..fc188276 100644 --- a/src/main/java/electrosphere/client/service/ClientTemporalService.java +++ b/src/main/java/electrosphere/client/service/ClientTemporalService.java @@ -60,5 +60,13 @@ public class ClientTemporalService extends SignalServiceImpl { this.latestServerData = serverData; lock.unlock(); } + + /** + * Gets the time of day of the service + * @return The time of day of the service + */ + public float getTime(){ + return (float)((double)clientTemporalData.getTime() / (double)MacroTemporalData.TIME_PER_DAY) % 1.0f; + } } diff --git a/src/main/java/electrosphere/data/macro/temporal/MacroTemporalData.java b/src/main/java/electrosphere/data/macro/temporal/MacroTemporalData.java index 46cec298..93050319 100644 --- a/src/main/java/electrosphere/data/macro/temporal/MacroTemporalData.java +++ b/src/main/java/electrosphere/data/macro/temporal/MacroTemporalData.java @@ -8,7 +8,7 @@ public class MacroTemporalData { /** * Amount of time per day */ - public static final long TIME_PER_DAY = 60 * 60 * 30; + public static final long TIME_PER_DAY = 60 * 60 * 1; /** * The noon remainder amount diff --git a/src/main/java/electrosphere/engine/assetmanager/AssetDataStrings.java b/src/main/java/electrosphere/engine/assetmanager/AssetDataStrings.java index ca4e3843..b0885dab 100644 --- a/src/main/java/electrosphere/engine/assetmanager/AssetDataStrings.java +++ b/src/main/java/electrosphere/engine/assetmanager/AssetDataStrings.java @@ -108,4 +108,10 @@ public class AssetDataStrings { */ public static final String MODEL_WAYPOINT = "Models/engine/waypoint.glb"; + /** + * Skybox + */ + public static final String SHADER_SKYBOX_VERT = "Shaders/entities/skysphere/skysphere.vs"; + public static final String SHADER_SKYBOX_FRAG = "Shaders/entities/skysphere/skysphere.fs"; + } diff --git a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java index 91771a8e..d0d832b8 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java @@ -19,6 +19,7 @@ import electrosphere.controls.ControlHandler; import electrosphere.controls.cursor.CursorState; import electrosphere.engine.EngineState; import electrosphere.engine.Globals; +import electrosphere.engine.assetmanager.AssetDataStrings; import electrosphere.engine.signal.Signal.SignalType; import electrosphere.engine.threads.LabeledThread.ThreadLabel; import electrosphere.entity.DrawableUtils; @@ -30,6 +31,7 @@ import electrosphere.net.NetUtils; import electrosphere.net.client.ClientNetworking; import electrosphere.net.parser.net.message.CharacterMessage; import electrosphere.net.parser.net.message.LoreMessage; +import electrosphere.renderer.meshgen.GeometryMeshGen; public class ClientLoading { @@ -49,6 +51,21 @@ public class ClientLoading { */ private static final int MAX_DRAW_CELL_WAIT = 1000; + /** + * Slices in skysphere + */ + private static final int SKYSPHERE_SLICES = 20; + + /** + * stack in skysphere + */ + private static final int SKYSPHERE_STACKS = 20; + + /** + * Scale of skysphere + */ + private static final float SKYSPHERE_SCALE = 5000.0f; + /** * Loads the race data from the server @@ -257,15 +274,19 @@ public class ClientLoading { * Skybox */ Entity skybox = EntityCreationUtils.createClientSpatialEntity(); - EntityCreationUtils.makeEntityDrawable(skybox, "Models/environment/skyboxSphere.fbx"); + DrawableUtils.makeEntityDrawable(skybox, () -> { + return GeometryMeshGen.genSphere(SKYSPHERE_SLICES, SKYSPHERE_STACKS); + }); DrawableUtils.disableCulling(skybox); - EntityUtils.getRotation(skybox).rotateX((float)(-Math.PI/2.0f)); - EntityUtils.getScale(skybox).mul(600000.0f); + EntityUtils.getScale(skybox).mul(SKYSPHERE_SCALE); Globals.clientState.clientScene.registerBehaviorTree(() -> { EntityUtils.getPosition(skybox).set(EntityUtils.getPosition(Globals.clientState.playerEntity)); }); - Globals.assetManager.queueOverrideMeshShader("Models/environment/skyboxSphere.fbx", "Sphere", "Shaders/entities/skysphere/skysphere.vs", "Shaders/entities/skysphere/skysphere.fs"); + Globals.assetManager.queueOverrideMeshShader(EntityUtils.getActor(skybox).getBaseModelPath(), GeometryMeshGen.SPHERE_MESH_NAME, AssetDataStrings.SHADER_SKYBOX_VERT, AssetDataStrings.SHADER_SKYBOX_FRAG); + /** + * Cursors + */ CursorState.createCursorEntities(); } diff --git a/src/main/java/electrosphere/renderer/meshgen/GeometryMeshGen.java b/src/main/java/electrosphere/renderer/meshgen/GeometryMeshGen.java index 4cacc814..d8a2a302 100644 --- a/src/main/java/electrosphere/renderer/meshgen/GeometryMeshGen.java +++ b/src/main/java/electrosphere/renderer/meshgen/GeometryMeshGen.java @@ -23,6 +23,11 @@ import electrosphere.renderer.shader.VisualShader; * Routines for generating meshes of basic geometry */ public class GeometryMeshGen { + + /** + * Name of sphere mesh + */ + public static final String SPHERE_MESH_NAME = "sphere"; /** * Meshes a box @@ -479,8 +484,8 @@ public class GeometryMeshGen { * @param stacks The number of stacks of the sphere * @return The model */ - public static Mesh createUnitSphere(int slices, int stacks){ - Mesh sphereMesh = new Mesh("sphere"); + public static Mesh genSphere(int slices, int stacks){ + Mesh sphereMesh = new Mesh(GeometryMeshGen.SPHERE_MESH_NAME); OpenGLState openGLState = Globals.renderingEngine.getOpenGLState(); sphereMesh.generateVAO(openGLState); @@ -515,6 +520,15 @@ public class GeometryMeshGen { sphereMesh.bufferTextureCoords(texCoordsFinal, 2); } + //normals + { + FloatBuffer normals = data.normals(numPoints * 3); + FloatBuffer normalsFinal = BufferUtils.createFloatBuffer(normals.limit()); //reallocating to BufferUtils buffer to help minimize memory errors + normalsFinal.put(normals); + normalsFinal.flip(); + sphereMesh.bufferNormals(normalsFinal, 3); + } + //setup extra structures Material mat = Material.createExisting(AssetDataStrings.TEXTURE_TEAL_TRANSPARENT); diff --git a/src/main/java/electrosphere/renderer/shader/StandardUniformManager.java b/src/main/java/electrosphere/renderer/shader/StandardUniformManager.java index a3669646..91c4abed 100644 --- a/src/main/java/electrosphere/renderer/shader/StandardUniformManager.java +++ b/src/main/java/electrosphere/renderer/shader/StandardUniformManager.java @@ -24,7 +24,7 @@ public class StandardUniformManager { /** * Size of the standard uniform ssbo */ - public static final int STANDARD_UNIFORM_SSBO_SIZE = 216; + public static final int STANDARD_UNIFORM_SSBO_SIZE = 220; /** * The standard uniform ssbo @@ -36,8 +36,9 @@ public class StandardUniformManager { vec4 viewPos; //16 bytes unsigned int frame; //4 bytes float time; //4 bytes + float timeOfDay; //4 bytes } - Totals to 216 bytes + Totals to 220 bytes */ private ShaderStorageBuffer standardUniformSSBO; @@ -148,6 +149,9 @@ public class StandardUniformManager { //put the engine time buff.putFloat((float)Globals.engineState.timekeeper.getCurrentRendererTime()); + //put time of day + buff.putFloat(Globals.clientState.clientTemporalService.getTime()); + buff.flip(); standardUniformSSBO.upload(Globals.renderingEngine.getOpenGLState());