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": {
"growthRate" : 0.001
},
"grassData": {
"baseColor": {"x": 0.05, "y": 0.2, "z": 0.01},
"tipColor": {"x": 0.25, "y": 0.45, "z": 0}
},
"graphicsTemplate": {
"model": {
"path" : "Models/foliage/grass2.fbx"

View File

@ -29,6 +29,8 @@ uniform Material material;
// uniform sampler2D ourTexture;
uniform int hasTransparency;
// uniform sampler2D specularTexture;
uniform vec3 baseColor;
uniform vec3 tipColor;
uniform mat4 view;
@ -49,8 +51,6 @@ void main(){
float heightPercent = TexCoord.y;
//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));
//mix normals

View File

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

View File

@ -219,12 +219,18 @@ public class FoliageModel {
QueuedTexture queuedAsset = new QueuedTexture(QueuedTextureType.DATA_BUFF,buffer,textureWidth,textureHeight);
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());
EntityUtils.getScale(rVal).set(1,1,1);
//add ambient foliage behavior tree
AmbientFoliage.attachAmbientFoliageTree(rVal, 1.0f, foliageType.getGrowthModel().getGrowthRate());
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){
ClientEntityUtils.destroyEntity(toDelete);

View File

@ -9,14 +9,26 @@ import electrosphere.game.data.common.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";
//Denotes an tree object
/**
* Denotes an tree object
*/
public static final String TOKEN_TREE = "TREE";
//the physics object(s) for the foliage
/**
* The physics object(s) for the foliage
*/
List<PhysicsObject> physicsObjects;
/**
* Data controlling the procedural grass
*/
GrassData grassData;
/**
* Gets the physics object(s)
* @return The physics object(s)
@ -24,5 +36,14 @@ public class FoliageType extends CommonEntityType {
public List<PhysicsObject> getPhysicsObjects() {
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;
import java.util.List;
import org.joml.Matrix4d;
import org.joml.Vector3d;
@ -9,6 +11,8 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.RenderPipelineState;
import electrosphere.renderer.actor.ActorUniformMap;
import electrosphere.renderer.actor.ActorUniformMap.UniformValue;
import electrosphere.renderer.model.Material;
import electrosphere.renderer.model.Model;
import electrosphere.renderer.shader.VisualShader;
@ -52,6 +56,11 @@ public class TextureInstancedActor {
String vertexShaderPath;
String fragmentShaderPath;
/**
* A map of mesh -> uniforms to apply to the mesh
*/
ActorUniformMap uniformMap = new ActorUniformMap();
/**
* Creates an instanced actor
* @param modelPath The path of the model this actor uses
@ -94,11 +103,17 @@ public class TextureInstancedActor {
* Attaches a TextureInstancedActor to an entity
* @param parent The entity
* @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 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);
parent.putData(EntityDataStrings.TEXTURE_INSTANCED_ACTOR, newActor);
return newActor;
}
/**
@ -144,6 +159,17 @@ public class TextureInstancedActor {
openGLState.setActiveShader(renderPipelineState, shader);
shader.setUniform(openGLState, uniformColSize, colSize);
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);
//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
*/

View File

@ -20,6 +20,7 @@ import java.util.List;
import org.joml.Matrix4d;
import org.joml.Matrix4f;
import org.joml.Sphered;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector3i;
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]));
Globals.renderingEngine.checkError();
}
if(currentUniformRaw instanceof Vector3d){
throw new Error("Unsupported data type!");
}
if(currentUniformRaw instanceof Vector3f){
Vector3f currentUniform = (Vector3f)currentUniformRaw;
openGLState.getActiveShader().setUniform(openGLState, key, currentUniform);