file-controlled foliage coloration
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-03-27 20:16:22 -04:00
parent aec3733429
commit f0179f8507
8 changed files with 117 additions and 7 deletions

View File

@ -11,6 +11,10 @@
"growthModel": { "growthModel": {
"growthRate" : 0.001 "growthRate" : 0.001
}, },
"grassData": {
"baseColor": {"x": 0.05, "y": 0.2, "z": 0.01},
"tipColor": {"x": 0.25, "y": 0.45, "z": 0}
},
"graphicsTemplate": { "graphicsTemplate": {
"model": { "model": {
"path" : "Models/foliage/grass2.fbx" "path" : "Models/foliage/grass2.fbx"

View File

@ -29,6 +29,8 @@ uniform Material material;
// uniform sampler2D ourTexture; // uniform sampler2D ourTexture;
uniform int hasTransparency; uniform int hasTransparency;
// uniform sampler2D specularTexture; // uniform sampler2D specularTexture;
uniform vec3 baseColor;
uniform vec3 tipColor;
uniform mat4 view; uniform mat4 view;
@ -49,8 +51,6 @@ void main(){
float heightPercent = TexCoord.y; float heightPercent = TexCoord.y;
//calculate color //calculate color
vec3 baseColor = vec3(0.05,0.2,0.01);
vec3 tipColor = vec3(0.25,0.45,0);
vec3 textureColor = mix(baseColor,tipColor,easeIn(heightPercent)); vec3 textureColor = mix(baseColor,tipColor,easeIn(heightPercent));
//mix normals //mix normals

View File

@ -1348,6 +1348,7 @@ Title menu navigation work
Fix UI Testing debug menu Fix UI Testing debug menu
Fix orphan tooltips from inventory screen Fix orphan tooltips from inventory screen
Code formatting Code formatting
File-controlled foliage coloration
# TODO # TODO

View File

@ -219,12 +219,18 @@ public class FoliageModel {
QueuedTexture queuedAsset = new QueuedTexture(QueuedTextureType.DATA_BUFF,buffer,textureWidth,textureHeight); QueuedTexture queuedAsset = new QueuedTexture(QueuedTextureType.DATA_BUFF,buffer,textureWidth,textureHeight);
Globals.assetManager.queuedAsset(queuedAsset); Globals.assetManager.queuedAsset(queuedAsset);
TextureInstancedActor.attachTextureInstancedActor(rVal, foliageType.getGraphicsTemplate().getModel().getPath(), vertexPath, fragmentPath, queuedAsset, drawCount, textureHeight); TextureInstancedActor actor = TextureInstancedActor.attachTextureInstancedActor(rVal, foliageType.getGraphicsTemplate().getModel().getPath(), vertexPath, fragmentPath, queuedAsset, drawCount, textureHeight);
ClientEntityUtils.initiallyPositionEntity(rVal, realPos, new Quaterniond()); ClientEntityUtils.initiallyPositionEntity(rVal, realPos, new Quaterniond());
EntityUtils.getScale(rVal).set(1,1,1); EntityUtils.getScale(rVal).set(1,1,1);
//add ambient foliage behavior tree //add ambient foliage behavior tree
AmbientFoliage.attachAmbientFoliageTree(rVal, 1.0f, foliageType.getGrowthModel().getGrowthRate()); AmbientFoliage.attachAmbientFoliageTree(rVal, 1.0f, foliageType.getGrowthModel().getGrowthRate());
Globals.clientScene.registerEntityToTag(rVal, EntityTags.DRAW_FOLIAGE_PASS); Globals.clientScene.registerEntityToTag(rVal, EntityTags.DRAW_FOLIAGE_PASS);
//apply grass uniforms if present in definition
if(foliageType.getGrassData() != null){
actor.setUniformOnMesh("Plane", "baseColor", foliageType.getGrassData().getBaseColor());
actor.setUniformOnMesh("Plane", "tipColor", foliageType.getGrassData().getTipColor());
}
} }
if(toDelete != null){ if(toDelete != null){
ClientEntityUtils.destroyEntity(toDelete); ClientEntityUtils.destroyEntity(toDelete);

View File

@ -9,14 +9,26 @@ import electrosphere.game.data.common.CommonEntityType;
*/ */
public class FoliageType extends CommonEntityType { public class FoliageType extends CommonEntityType {
//Denotes an ambient foliage that will be placed on a voxel /**
* Denotes an ambient foliage that will be placed on a voxel
*/
public static final String TOKEN_AMBIENT = "AMBIENT"; public static final String TOKEN_AMBIENT = "AMBIENT";
//Denotes an tree object
/**
* Denotes an tree object
*/
public static final String TOKEN_TREE = "TREE"; public static final String TOKEN_TREE = "TREE";
//the physics object(s) for the foliage /**
* The physics object(s) for the foliage
*/
List<PhysicsObject> physicsObjects; List<PhysicsObject> physicsObjects;
/**
* Data controlling the procedural grass
*/
GrassData grassData;
/** /**
* Gets the physics object(s) * Gets the physics object(s)
* @return The physics object(s) * @return The physics object(s)
@ -24,5 +36,14 @@ public class FoliageType extends CommonEntityType {
public List<PhysicsObject> getPhysicsObjects() { public List<PhysicsObject> getPhysicsObjects() {
return physicsObjects; return physicsObjects;
} }
/**
* Gets the grass data of the foliage
* @return The grass data
*/
public GrassData getGrassData() {
return grassData;
}
} }

View File

@ -0,0 +1,38 @@
package electrosphere.game.data.foliage.type;
import org.joml.Vector3f;
/**
* Data specific to the grass
*/
public class GrassData {
/**
* Color at the base of the model
*/
Vector3f baseColor;
/**
* Color at the tip of the model
*/
Vector3f tipColor;
/**
* Gets the base color of the grass
* @return The base color
*/
public Vector3f getBaseColor() {
return baseColor;
}
/**
* Gets the tip color of the grass
* @return The tip color
*/
public Vector3f getTipColor() {
return tipColor;
}
}

View File

@ -1,5 +1,7 @@
package electrosphere.renderer.actor.instance; package electrosphere.renderer.actor.instance;
import java.util.List;
import org.joml.Matrix4d; import org.joml.Matrix4d;
import org.joml.Vector3d; import org.joml.Vector3d;
@ -9,6 +11,8 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
import electrosphere.renderer.OpenGLState; import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.RenderPipelineState;
import electrosphere.renderer.actor.ActorUniformMap;
import electrosphere.renderer.actor.ActorUniformMap.UniformValue;
import electrosphere.renderer.model.Material; import electrosphere.renderer.model.Material;
import electrosphere.renderer.model.Model; import electrosphere.renderer.model.Model;
import electrosphere.renderer.shader.VisualShader; import electrosphere.renderer.shader.VisualShader;
@ -52,6 +56,11 @@ public class TextureInstancedActor {
String vertexShaderPath; String vertexShaderPath;
String fragmentShaderPath; String fragmentShaderPath;
/**
* A map of mesh -> uniforms to apply to the mesh
*/
ActorUniformMap uniformMap = new ActorUniformMap();
/** /**
* Creates an instanced actor * Creates an instanced actor
* @param modelPath The path of the model this actor uses * @param modelPath The path of the model this actor uses
@ -94,11 +103,17 @@ public class TextureInstancedActor {
* Attaches a TextureInstancedActor to an entity * Attaches a TextureInstancedActor to an entity
* @param parent The entity * @param parent The entity
* @param modelPath The path to the model for this instanced actor * @param modelPath The path to the model for this instanced actor
* @param vertexShaderPath The path to the vertex shader to use
* @param fragmentShaderPath The path to the fragment shader to use
* @param dataTexture The data texture containing data for this actor * @param dataTexture The data texture containing data for this actor
* @param drawCount The number of instances to draw
* @param colSize The size of a column of data
* @return The TextureInstancedActor that was attached to the entity
*/ */
public static void attachTextureInstancedActor(Entity parent, String modelPath, String vertexShaderPath, String fragmentShaderPath, QueuedTexture dataTexture, int drawCount, int colSize){ public static TextureInstancedActor 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); TextureInstancedActor newActor = new TextureInstancedActor(modelPath, vertexShaderPath, fragmentShaderPath, dataTexture, drawCount, colSize);
parent.putData(EntityDataStrings.TEXTURE_INSTANCED_ACTOR, newActor); parent.putData(EntityDataStrings.TEXTURE_INSTANCED_ACTOR, newActor);
return newActor;
} }
/** /**
@ -144,6 +159,17 @@ public class TextureInstancedActor {
openGLState.setActiveShader(renderPipelineState, shader); openGLState.setActiveShader(renderPipelineState, shader);
shader.setUniform(openGLState, uniformColSize, colSize); shader.setUniform(openGLState, uniformColSize, colSize);
this.material.apply_material(openGLState); this.material.apply_material(openGLState);
//apply uniform overrides
if(this.uniformMap.getMeshes() != null && this.uniformMap.getMeshes().size() > 0){
for(String meshName : this.uniformMap.getMeshes()){
List<UniformValue> uniforms = this.uniformMap.getUniforms(meshName);
for(UniformValue uniform : uniforms){
model.pushUniformToMesh(meshName, uniform.getUniformName(), uniform.getValue());
}
}
}
model.draw(renderPipelineState, openGLState); model.draw(renderPipelineState, openGLState);
//reset render pipeline state //reset render pipeline state
@ -186,6 +212,16 @@ public class TextureInstancedActor {
} }
} }
/**
* Sets the value of a uniform on a given mesh within this actor
* @param meshName The name of the mesh
* @param uniformName The name of the uniform
* @param value The value of the uniform
*/
public void setUniformOnMesh(String meshName, String uniformName, Object value){
this.uniformMap.setUniform(meshName, uniformName, value);
}
/** /**
* Frees the texture instanced actor * Frees the texture instanced actor
*/ */

View File

@ -20,6 +20,7 @@ import java.util.List;
import org.joml.Matrix4d; import org.joml.Matrix4d;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import org.joml.Sphered; import org.joml.Sphered;
import org.joml.Vector3d;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.joml.Vector3i; import org.joml.Vector3i;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
@ -322,6 +323,9 @@ public class Mesh {
// GL40.glUniformMatrix4dv(glGetUniformLocation(openGLState.getActiveShader().getId(), key), false, currentUniform.get(new double[16])); // GL40.glUniformMatrix4dv(glGetUniformLocation(openGLState.getActiveShader().getId(), key), false, currentUniform.get(new double[16]));
Globals.renderingEngine.checkError(); Globals.renderingEngine.checkError();
} }
if(currentUniformRaw instanceof Vector3d){
throw new Error("Unsupported data type!");
}
if(currentUniformRaw instanceof Vector3f){ if(currentUniformRaw instanceof Vector3f){
Vector3f currentUniform = (Vector3f)currentUniformRaw; Vector3f currentUniform = (Vector3f)currentUniformRaw;
openGLState.getActiveShader().setUniform(openGLState, key, currentUniform); openGLState.getActiveShader().setUniform(openGLState, key, currentUniform);