diff --git a/assets/Shaders/entities/foliage/foliage.vs b/assets/Shaders/entities/foliage/foliage.vs index 962df24a..a3bb74a9 100644 --- a/assets/Shaders/entities/foliage/foliage.vs +++ b/assets/Shaders/entities/foliage/foliage.vs @@ -36,6 +36,11 @@ uniform vec3 modelWorldPos; uniform float time; +/** +Size of a column of data +*/ +uniform int colSize; + //output buffers out vec3 Normal; @@ -70,12 +75,15 @@ void main() { ivec2 texSize = textureSize(material.diffuse,0); + int sampleX = (gl_InstanceID / colSize) * 5; + int sampleY = (gl_InstanceID % colSize); + //grab data out of texture - float xOffset = texelFetch(material.diffuse,ivec2(0,gl_InstanceID),0).r; - float yOffset = texelFetch(material.diffuse,ivec2(1,gl_InstanceID),0).r; - float zOffset = texelFetch(material.diffuse,ivec2(2,gl_InstanceID),0).r; - float rotVar = texelFetch(material.diffuse,ivec2(3,gl_InstanceID),0).r; - float rotVar2 = texelFetch(material.diffuse,ivec2(4,gl_InstanceID),0).r; + float xOffset = texelFetch(material.diffuse,ivec2(0 + sampleX,sampleY),0).r; + float yOffset = texelFetch(material.diffuse,ivec2(1 + sampleX,sampleY),0).r; + float zOffset = texelFetch(material.diffuse,ivec2(2 + sampleX,sampleY),0).r; + float rotVar = texelFetch(material.diffuse,ivec2(3 + sampleX,sampleY),0).r; + float rotVar2 = texelFetch(material.diffuse,ivec2(4 + sampleX,sampleY),0).r; // //curve float noise diff --git a/buildNumber.properties b/buildNumber.properties index 6c48ef73..0e12f248 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Wed Nov 20 21:32:04 EST 2024 -buildNumber=399 +#Thu Nov 21 19:02:13 EST 2024 +buildNumber=400 diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 62202e5c..6c78edb2 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1114,6 +1114,7 @@ Fix allocations on FoliageChunk child iterations Reduce near clip to remove flickering on far chunks Complete overhaul of foliage management Fix foliage inconsistently placing on varied terrain +Fix foliage texture wrapping when drawing too many foliage items # TODO diff --git a/src/main/java/electrosphere/client/terrain/foliage/FoliageModel.java b/src/main/java/electrosphere/client/terrain/foliage/FoliageModel.java index 2a819a99..5bb93824 100644 --- a/src/main/java/electrosphere/client/terrain/foliage/FoliageModel.java +++ b/src/main/java/electrosphere/client/terrain/foliage/FoliageModel.java @@ -48,27 +48,7 @@ public class FoliageModel { /** * The interval to space along */ - static final int TARGET_FOLIAGE_SPACING = 25; - - /** - * The target number of foliage to place per cell - */ - static final int TARGET_FOLIAGE_PER_CELL = TARGET_FOLIAGE_SPACING * TARGET_FOLIAGE_SPACING + BUFFER_WIGGLE_ROOM; - - /** - * The length of the ray to ground test with - */ - static final float RAY_LENGTH = 2.5f; - - /** - * The height above the chunk to start from when sampling downwards - */ - static final float SAMPLE_START_HEIGHT = 1.0f; - - /** - * The ID of the air voxel - */ - static final int AIR_VOXEL_ID = 0; + static final int TARGET_FOLIAGE_SPACING = 200; /** *

@@ -86,6 +66,36 @@ public class FoliageModel { */ static final int SINGLE_FOLIAGE_DATA_SIZE_BYTES = 3 * 4 + 2 * 4; + /** + * The target number of foliage to place per cell + */ + static final int TARGET_FOLIAGE_PER_CELL = TARGET_FOLIAGE_SPACING * TARGET_FOLIAGE_SPACING + BUFFER_WIGGLE_ROOM; + + /** + * Maximum allowed height of the data texture + */ + static final int MAX_TEXTURE_HEIGHT = 2048; + + /** + * The target width of the image + */ + static final int TARGET_WIDTH_OF_IMAGE = TARGET_FOLIAGE_PER_CELL / MAX_TEXTURE_HEIGHT * (SINGLE_FOLIAGE_DATA_SIZE_BYTES / 4); + + /** + * The length of the ray to ground test with + */ + static final float RAY_LENGTH = 2.5f; + + /** + * The height above the chunk to start from when sampling downwards + */ + static final float SAMPLE_START_HEIGHT = 1.0f; + + /** + * The ID of the air voxel + */ + static final int AIR_VOXEL_ID = 0; + /** * Offset to sample by */ @@ -136,7 +146,7 @@ public class FoliageModel { FoliageType foliageType = Globals.gameConfigCurrent.getFoliageMap().getFoliage(foliageTypeName); //create cell and buffer - ByteBuffer buffer = BufferUtils.createByteBuffer(TARGET_FOLIAGE_PER_CELL * SINGLE_FOLIAGE_DATA_SIZE_BYTES); + ByteBuffer buffer = BufferUtils.createByteBuffer(MAX_TEXTURE_HEIGHT * TARGET_WIDTH_OF_IMAGE * SINGLE_FOLIAGE_DATA_SIZE_BYTES); if(buffer.capacity() < TARGET_FOLIAGE_PER_CELL * SINGLE_FOLIAGE_DATA_SIZE_BYTES){ LoggerInterface.loggerEngine.WARNING("Failed to allocate data for foliage cell! " + buffer.limit()); } @@ -183,11 +193,18 @@ public class FoliageModel { if(drawCount > 0){ buffer.position(0); buffer.limit(TARGET_FOLIAGE_PER_CELL * SINGLE_FOLIAGE_DATA_SIZE_BYTES); + + int textureHeight = MAX_TEXTURE_HEIGHT; + if(drawCount < MAX_TEXTURE_HEIGHT){ + textureHeight = drawCount; + } + int textureWidth = (1 + (drawCount / MAX_TEXTURE_HEIGHT)) * (SINGLE_FOLIAGE_DATA_SIZE_BYTES / 4); + //construct data texture - QueuedTexture queuedAsset = new QueuedTexture(buffer,SINGLE_FOLIAGE_DATA_SIZE_BYTES / 4,TARGET_FOLIAGE_PER_CELL); + QueuedTexture queuedAsset = new QueuedTexture(buffer,textureWidth,textureHeight); Globals.assetManager.queuedAsset(queuedAsset); - TextureInstancedActor.attachTextureInstancedActor(modelEntity, foliageType.getGraphicsTemplate().getModel().getPath(), vertexPath, fragmentPath, queuedAsset, drawCount); + TextureInstancedActor.attachTextureInstancedActor(modelEntity, foliageType.getGraphicsTemplate().getModel().getPath(), vertexPath, fragmentPath, queuedAsset, drawCount, textureHeight); ClientEntityUtils.initiallyPositionEntity(modelEntity, realPos, new Quaterniond()); EntityUtils.getScale(modelEntity).set(1,1,1); //add ambient foliage behavior tree diff --git a/src/main/java/electrosphere/renderer/actor/instance/TextureInstancedActor.java b/src/main/java/electrosphere/renderer/actor/instance/TextureInstancedActor.java index c0f44af1..970fffb9 100644 --- a/src/main/java/electrosphere/renderer/actor/instance/TextureInstancedActor.java +++ b/src/main/java/electrosphere/renderer/actor/instance/TextureInstancedActor.java @@ -19,6 +19,11 @@ import electrosphere.renderer.texture.Texture; */ public class TextureInstancedActor { + /** + * Uniform location for the column size uniform + */ + static final String uniformColSize = "colSize"; + //path of the model that this instanced actor uses String modelPath; @@ -28,6 +33,11 @@ public class TextureInstancedActor { //the draw count of the texture instanced actor int drawCount; + /** + * Size of a column of data + */ + int colSize = 1; + /** * The queued texture */ @@ -59,11 +69,12 @@ public class TextureInstancedActor { * Creates an instanced actor * @param modelPath The path of the model this actor uses */ - protected TextureInstancedActor(String modelPath, String vertexShaderPath, String fragmentShaderPath, QueuedTexture dataTexture, int drawCount){ + protected TextureInstancedActor(String modelPath, String vertexShaderPath, String fragmentShaderPath, QueuedTexture dataTexture, int drawCount, int colSize){ this.modelPath = modelPath; this.material = new Material(); this.queuedTexture = dataTexture; this.drawCount = drawCount; + this.colSize = colSize; this.vertexShaderPath = vertexShaderPath; this.fragmentShaderPath = fragmentShaderPath; } @@ -85,8 +96,8 @@ public class TextureInstancedActor { * @param modelPath The path to the model for this instanced actor * @param dataTexture The data texture containing data for this actor */ - public static void attachTextureInstancedActor(Entity parent, String modelPath, String vertexShaderPath, String fragmentShaderPath, QueuedTexture dataTexture, int drawCount){ - TextureInstancedActor newActor = new TextureInstancedActor(modelPath, vertexShaderPath, fragmentShaderPath, dataTexture, drawCount); + public static void attachTextureInstancedActor(Entity parent, String modelPath, String vertexShaderPath, String fragmentShaderPath, QueuedTexture dataTexture, int drawCount, int colSize){ + TextureInstancedActor newActor = new TextureInstancedActor(modelPath, vertexShaderPath, fragmentShaderPath, dataTexture, drawCount, colSize); parent.putData(EntityDataStrings.TEXTURE_INSTANCED_ACTOR, newActor); } @@ -131,6 +142,7 @@ public class TextureInstancedActor { openGLState.setActiveShader(renderPipelineState, shader); + shader.setUniform(openGLState, uniformColSize, colSize); this.material.apply_material(openGLState); model.draw(renderPipelineState, openGLState); diff --git a/src/main/java/electrosphere/renderer/light/LightManager.java b/src/main/java/electrosphere/renderer/light/LightManager.java index 1004da2c..4ecc9dee 100644 --- a/src/main/java/electrosphere/renderer/light/LightManager.java +++ b/src/main/java/electrosphere/renderer/light/LightManager.java @@ -258,8 +258,10 @@ public class LightManager { pointLightBuffer.putFloat(light.getQuadratic()); pointLightBuffer.putFloat(light.getRadius()); } - pointLightBuffer.flip(); - pointLightSSBO.upload(openGLState); + if(pointLightBuffer.position() > 0){ + pointLightBuffer.flip(); + pointLightSSBO.upload(openGLState); + } // //push direct light