Terrain Chunk triplanar mapping
This commit is contained in:
parent
72d1f8ac91
commit
bb089a7d36
208
assets/Shaders/terrain2/terrain2.fs
Normal file
208
assets/Shaders/terrain2/terrain2.fs
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
#define NR_POINT_LIGHTS 10
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
sampler2D specular;
|
||||||
|
float shininess;
|
||||||
|
};
|
||||||
|
|
||||||
|
in vec3 FragPos;
|
||||||
|
in vec3 Normal;
|
||||||
|
in vec2 texPlane1;
|
||||||
|
in vec2 texPlane2;
|
||||||
|
in vec2 texPlane3;
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
// 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(){
|
||||||
|
vec3 norm = normalize(Normal);
|
||||||
|
vec3 viewDir = normalize(viewPos - FragPos);
|
||||||
|
|
||||||
|
//grab light intensity
|
||||||
|
float lightIntensity = calcLightIntensityTotal(norm);
|
||||||
|
|
||||||
|
//get color of base texture
|
||||||
|
vec3 textureColor = getColor(texPlane1, texPlane2, texPlane3, norm, material);
|
||||||
|
|
||||||
|
//shadow
|
||||||
|
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-dLDirection), 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, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vec3 getColor(vec2 texPlane1, vec2 texPlane2, vec2 texPlane3, vec3 normal, Material material){
|
||||||
|
|
||||||
|
vec3 weights = abs(normal);
|
||||||
|
|
||||||
|
vec3 albedoX = texture(material.diffuse, texPlane1).rgb;
|
||||||
|
vec3 albedoY = texture(material.diffuse, texPlane2).rgb;
|
||||||
|
vec3 albedoZ = texture(material.diffuse, texPlane3).rgb;
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
62
assets/Shaders/terrain2/terrain2.vs
Normal file
62
assets/Shaders/terrain2/terrain2.vs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
//Vertex Shader
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
//defines
|
||||||
|
#define TEXTURE_MAP_SCALE 3.0
|
||||||
|
|
||||||
|
|
||||||
|
//input buffers
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
layout (location = 1) in vec3 aNormal;
|
||||||
|
layout (location = 4) in vec2 aTex;
|
||||||
|
|
||||||
|
|
||||||
|
//coordinate space transformation matrices
|
||||||
|
uniform mat4 transform;
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform mat4 lightSpaceMatrix;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//output buffers
|
||||||
|
out vec3 Normal;
|
||||||
|
out vec3 FragPos;
|
||||||
|
out vec2 texPlane1;
|
||||||
|
out vec2 texPlane2;
|
||||||
|
out vec2 texPlane3;
|
||||||
|
out vec4 FragPosLightSpace;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
//normalize posiiton and normal
|
||||||
|
vec4 FinalVertex = vec4(aPos, 1.0);
|
||||||
|
vec4 FinalNormal = vec4(aNormal, 1.0);
|
||||||
|
|
||||||
|
|
||||||
|
//push frag, normal, and texture positions to fragment shader
|
||||||
|
FragPos = vec3(model * FinalVertex);
|
||||||
|
Normal = mat3(transpose(inverse(model))) * aNormal;
|
||||||
|
|
||||||
|
//reference https://catlikecoding.com/unity/tutorials/advanced-rendering/triplanar-mapping/
|
||||||
|
texPlane1 = aPos.zy * TEXTURE_MAP_SCALE;
|
||||||
|
texPlane2 = aPos.xz * TEXTURE_MAP_SCALE;
|
||||||
|
texPlane3 = aPos.xy * TEXTURE_MAP_SCALE;
|
||||||
|
|
||||||
|
//flip first coordinate if the normal is negative
|
||||||
|
//this minimizes texture flipping
|
||||||
|
texPlane1.x = texPlane1.x * sign(Normal.x);
|
||||||
|
texPlane2.x = texPlane2.x * sign(Normal.y);
|
||||||
|
texPlane3.x = texPlane3.x * sign(Normal.z);
|
||||||
|
|
||||||
|
|
||||||
|
//shadow map stuff
|
||||||
|
FragPosLightSpace = lightSpaceMatrix * vec4(FragPos, 1.0);
|
||||||
|
|
||||||
|
|
||||||
|
//set final position with opengl space
|
||||||
|
gl_Position = projection * view * model * FinalVertex;
|
||||||
|
}
|
||||||
BIN
assets/Textures/leavesStylized1.png
Normal file
BIN
assets/Textures/leavesStylized1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
@ -45,6 +45,8 @@ import electrosphere.renderer.ShaderProgram;
|
|||||||
import electrosphere.renderer.light.PointLight;
|
import electrosphere.renderer.light.PointLight;
|
||||||
import electrosphere.renderer.light.SpotLight;
|
import electrosphere.renderer.light.SpotLight;
|
||||||
import electrosphere.renderer.loading.ModelPretransforms;
|
import electrosphere.renderer.loading.ModelPretransforms;
|
||||||
|
import electrosphere.renderer.meshgen.TerrainChunkModelGeneration;
|
||||||
|
import electrosphere.renderer.meshgen.TreeModelGeneration;
|
||||||
import electrosphere.renderer.shader.ShaderOptionMap;
|
import electrosphere.renderer.shader.ShaderOptionMap;
|
||||||
import electrosphere.renderer.texture.TextureMap;
|
import electrosphere.renderer.texture.TextureMap;
|
||||||
import electrosphere.renderer.ui.ElementManager;
|
import electrosphere.renderer.ui.ElementManager;
|
||||||
@ -408,8 +410,11 @@ public class Globals {
|
|||||||
defaultMeshShader = ShaderProgram.smart_assemble_shader(false,true);
|
defaultMeshShader = ShaderProgram.smart_assemble_shader(false,true);
|
||||||
//init terrain shader program
|
//init terrain shader program
|
||||||
terrainShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/terrain/terrain.vs", "/Shaders/terrain/terrain.fs");
|
terrainShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/terrain/terrain.vs", "/Shaders/terrain/terrain.fs");
|
||||||
|
TerrainChunkModelGeneration.terrainChunkShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/terrain2/terrain2.vs", "/Shaders/terrain2/terrain2.fs");
|
||||||
//init skybox
|
//init skybox
|
||||||
assetManager.registerModelToSpecificString(RenderUtils.createSkyboxModel(null), AssetDataStrings.ASSET_STRING_SKYBOX_BASIC);
|
assetManager.registerModelToSpecificString(RenderUtils.createSkyboxModel(null), AssetDataStrings.ASSET_STRING_SKYBOX_BASIC);
|
||||||
|
//init leaves
|
||||||
|
assetManager.registerModelToSpecificString(TreeModelGeneration.generateLeavesModel(), AssetDataStrings.LEAVES_MODEL);
|
||||||
//init models
|
//init models
|
||||||
assetManager.addModelPathToQueue("Models/unitsphere.fbx");
|
assetManager.addModelPathToQueue("Models/unitsphere.fbx");
|
||||||
assetManager.addModelPathToQueue("Models/unitsphere_1.fbx");
|
assetManager.addModelPathToQueue("Models/unitsphere_1.fbx");
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import org.joml.Vector3f;
|
|||||||
|
|
||||||
import electrosphere.auth.AuthenticationManager;
|
import electrosphere.auth.AuthenticationManager;
|
||||||
import electrosphere.controls.ControlHandler;
|
import electrosphere.controls.ControlHandler;
|
||||||
|
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.Scene;
|
import electrosphere.entity.Scene;
|
||||||
@ -44,6 +45,8 @@ import electrosphere.net.NetUtils;
|
|||||||
import electrosphere.net.client.ClientNetworking;
|
import electrosphere.net.client.ClientNetworking;
|
||||||
import electrosphere.net.server.Server;
|
import electrosphere.net.server.Server;
|
||||||
import electrosphere.net.server.player.Player;
|
import electrosphere.net.server.player.Player;
|
||||||
|
import electrosphere.renderer.Model;
|
||||||
|
import electrosphere.renderer.meshgen.TreeModelGeneration;
|
||||||
import electrosphere.renderer.ui.Window;
|
import electrosphere.renderer.ui.Window;
|
||||||
import electrosphere.server.ai.creature.adventurer.SeekTown;
|
import electrosphere.server.ai.creature.adventurer.SeekTown;
|
||||||
import electrosphere.server.datacell.DataCellManager;
|
import electrosphere.server.datacell.DataCellManager;
|
||||||
@ -775,12 +778,17 @@ public class LoadingThread extends Thread {
|
|||||||
// myCube.putData(EntityDataStrings.DRAW_TRANSPARENT_PASS, true);
|
// myCube.putData(EntityDataStrings.DRAW_TRANSPARENT_PASS, true);
|
||||||
// EntityUtils.getPosition(myCube).set(3,1,3);
|
// EntityUtils.getPosition(myCube).set(3,1,3);
|
||||||
|
|
||||||
SceneLoader loader = new SceneLoader();
|
// SceneLoader loader = new SceneLoader();
|
||||||
loader.serverInstantiateSceneFile("Scenes/testscene1/testscene1.json");
|
// loader.serverInstantiateSceneFile("Scenes/testscene1/testscene1.json");
|
||||||
|
|
||||||
|
|
||||||
Entity chunk = TerrainChunk.createTerrainChunkEntity();
|
Entity chunk = TerrainChunk.createTerrainChunkEntity();
|
||||||
|
|
||||||
|
Entity leaves = EntityUtils.spawnDrawableEntity(AssetDataStrings.LEAVES_MODEL);
|
||||||
|
EntityUtils.repositionEntity(leaves, new Vector3d(1,0,1));
|
||||||
|
leaves.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
|
||||||
|
leaves.putData(EntityDataStrings.DRAW_TRANSPARENT_PASS, true);
|
||||||
|
|
||||||
// Globals.entityManager.registerBehaviorTree(new BehaviorTree() {
|
// Globals.entityManager.registerBehaviorTree(new BehaviorTree() {
|
||||||
// int i = 0;
|
// int i = 0;
|
||||||
// public void simulate(){
|
// public void simulate(){
|
||||||
|
|||||||
@ -8,4 +8,5 @@ public class AssetDataStrings {
|
|||||||
public static final String ASSET_STRING_BITMAP_FONT_MESH_NAME = "quad";
|
public static final String ASSET_STRING_BITMAP_FONT_MESH_NAME = "quad";
|
||||||
public static final String ASSET_STRING_SKYBOX_BASIC = "skyboxBasic";
|
public static final String ASSET_STRING_SKYBOX_BASIC = "skyboxBasic";
|
||||||
public static final String BITMAP_CHARACTER_MODEL = "bitmapCharacterModel";
|
public static final String BITMAP_CHARACTER_MODEL = "bitmapCharacterModel";
|
||||||
|
public static final String LEAVES_MODEL = "leaves";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import org.joml.Vector3f;
|
|||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.game.client.terrain.manager.ClientTerrainManager;
|
import electrosphere.game.client.terrain.manager.ClientTerrainManager;
|
||||||
import electrosphere.game.collision.PhysicsUtils;
|
import electrosphere.game.collision.PhysicsUtils;
|
||||||
@ -20,9 +21,9 @@ public class TerrainChunk {
|
|||||||
//plane 1
|
//plane 1
|
||||||
{
|
{
|
||||||
//row 1
|
//row 1
|
||||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
{1.0f,1.0f,-1.0f,-1.0f,-1.0f,},
|
||||||
//row 2
|
//row 2
|
||||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
{-1.0f,1.0f,-1.0f,-1.0f,-1.0f,},
|
||||||
//row 3
|
//row 3
|
||||||
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
{-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,},
|
||||||
//row 4
|
//row 4
|
||||||
@ -158,6 +159,8 @@ public class TerrainChunk {
|
|||||||
Entity rVal = EntityUtils.spawnDrawableEntityWithPreexistingModel(modelPath);
|
Entity rVal = EntityUtils.spawnDrawableEntityWithPreexistingModel(modelPath);
|
||||||
PhysicsUtils.attachTerrainChunkRigidBody(rVal, data);
|
PhysicsUtils.attachTerrainChunkRigidBody(rVal, data);
|
||||||
|
|
||||||
|
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
|
||||||
|
|
||||||
EntityUtils.repositionEntity(rVal, new Vector3d(1,-1,1));
|
EntityUtils.repositionEntity(rVal, new Vector3d(1,-1,1));
|
||||||
|
|
||||||
return rVal;
|
return rVal;
|
||||||
|
|||||||
@ -1356,7 +1356,7 @@ public class RenderingEngine {
|
|||||||
|
|
||||||
public static void incrementOutputFramebuffer(){
|
public static void incrementOutputFramebuffer(){
|
||||||
outputFramebuffer++;
|
outputFramebuffer++;
|
||||||
if(outputFramebuffer > 7){
|
if(outputFramebuffer > 8){
|
||||||
outputFramebuffer = 0;
|
outputFramebuffer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,9 +8,9 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.vecmath.Vector2f;
|
|
||||||
|
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector2f;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
|
|
||||||
@ -24,6 +24,7 @@ import electrosphere.entity.types.terrain.TerrainChunkData;
|
|||||||
import electrosphere.renderer.Material;
|
import electrosphere.renderer.Material;
|
||||||
import electrosphere.renderer.Mesh;
|
import electrosphere.renderer.Mesh;
|
||||||
import electrosphere.renderer.Model;
|
import electrosphere.renderer.Model;
|
||||||
|
import electrosphere.renderer.ShaderProgram;
|
||||||
|
|
||||||
public class TerrainChunkModelGeneration {
|
public class TerrainChunkModelGeneration {
|
||||||
|
|
||||||
@ -365,6 +366,26 @@ public class TerrainChunkModelGeneration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static ShaderProgram terrainChunkShaderProgram = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected static int polygonize(
|
protected static int polygonize(
|
||||||
GridCell grid,
|
GridCell grid,
|
||||||
double isolevel,
|
double isolevel,
|
||||||
@ -618,20 +639,33 @@ public class TerrainChunkModelGeneration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
float[] temp = new float[3];
|
float[] temp = new float[3];
|
||||||
|
int i = 0;
|
||||||
for(Vector3f normal : normals){
|
for(Vector3f normal : normals){
|
||||||
|
Vector3f vert = verts.get(i);
|
||||||
|
|
||||||
float absX = Math.abs(normal.x);
|
float absX = Math.abs(normal.x);
|
||||||
float absY = Math.abs(normal.y);
|
float absY = Math.abs(normal.y);
|
||||||
float absZ = Math.abs(normal.z);
|
float absZ = Math.abs(normal.z);
|
||||||
if(absX >= absZ && absX >= absY){
|
|
||||||
temp[0] = normal.z / 2.0f + 0.5f;
|
float uvX = vert.z * absX + vert.x * absY + vert.x * absZ;
|
||||||
temp[1] = normal.y / 2.0f + 0.5f;
|
float uvY = vert.y * absX + vert.z * absY + vert.y * absZ;
|
||||||
} else if(absZ >= absX && absZ >= absY){
|
temp[0] = uvX;
|
||||||
temp[0] = normal.x / 2.0f + 0.5f;
|
temp[1] = uvY;
|
||||||
temp[1] = normal.y / 2.0f + 0.5f;
|
|
||||||
} else if(absY >= absX && absY >= absZ){
|
// if(absX >= absZ && absX >= absY){
|
||||||
temp[0] = normal.x / 2.0f + 0.5f;
|
// temp[0] = normal.z / 2.0f + 0.5f + vert.z * (absX / (absX + absZ)) + vert.x * (absZ / (absX + absZ));
|
||||||
temp[1] = normal.z / 2.0f + 0.5f;
|
// temp[1] = normal.y / 2.0f + 0.5f + vert.x * (absY / (absX + absY)) + vert.y * (absX / (absX + absY));
|
||||||
}
|
// } else if(absZ >= absX && absZ >= absY){
|
||||||
|
// temp[0] = normal.x / 2.0f + 0.5f + vert.z * (absX / (absX + absZ)) + vert.x * (absZ / (absX + absZ));
|
||||||
|
// temp[1] = normal.y / 2.0f + 0.5f + vert.z * (absY / (absZ + absY)) + vert.y * (absZ / (absZ + absY));
|
||||||
|
// } else if(absY >= absX && absY >= absZ){
|
||||||
|
// temp[0] = normal.x / 2.0f + 0.5f + vert.y * (absX / (absX + absY)) + vert.x * (absY / (absX + absY));
|
||||||
|
// temp[1] = normal.z / 2.0f + 0.5f + vert.y * (absZ / (absZ + absY)) + vert.z * (absY / (absZ + absY));
|
||||||
|
// } else {
|
||||||
|
// temp[0] = vert.x / 1.5f + vert.z / 1.5f;
|
||||||
|
// temp[1] = vert.y / 1.5f + vert.z / 1.5f;
|
||||||
|
// }
|
||||||
|
i++;
|
||||||
UVs.add(temp[0]);
|
UVs.add(temp[0]);
|
||||||
UVs.add(temp[1]);
|
UVs.add(temp[1]);
|
||||||
}
|
}
|
||||||
@ -758,7 +792,7 @@ public class TerrainChunkModelGeneration {
|
|||||||
groundMat.set_specular("/Textures/Ground/Dirt1.png");
|
groundMat.set_specular("/Textures/Ground/Dirt1.png");
|
||||||
m.setMaterial(groundMat);
|
m.setMaterial(groundMat);
|
||||||
|
|
||||||
m.setShader(Globals.defaultMeshShader);
|
m.setShader(TerrainChunkModelGeneration.terrainChunkShaderProgram);
|
||||||
m.parent = rVal;
|
m.parent = rVal;
|
||||||
|
|
||||||
rVal.meshes.add(m);
|
rVal.meshes.add(m);
|
||||||
|
|||||||
@ -0,0 +1,194 @@
|
|||||||
|
package electrosphere.renderer.meshgen;
|
||||||
|
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.renderer.Material;
|
||||||
|
import electrosphere.renderer.Mesh;
|
||||||
|
import electrosphere.renderer.Model;
|
||||||
|
|
||||||
|
import static org.lwjgl.opengl.GL30.glBindVertexArray;
|
||||||
|
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
|
||||||
|
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import org.lwjgl.BufferUtils;
|
||||||
|
|
||||||
|
public class TreeModelGeneration {
|
||||||
|
|
||||||
|
protected static Mesh generateLeafMesh(){
|
||||||
|
|
||||||
|
Mesh mesh = new Mesh();
|
||||||
|
|
||||||
|
|
||||||
|
mesh.mesh = null;
|
||||||
|
|
||||||
|
//
|
||||||
|
// VAO
|
||||||
|
//
|
||||||
|
mesh.vertexArrayObject = glGenVertexArrays();
|
||||||
|
glBindVertexArray(mesh.vertexArrayObject);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float[] vertices = new float[]{
|
||||||
|
0.5f, 0.5f, 0,
|
||||||
|
0.5f, -0.5f, 0,
|
||||||
|
-0.5f, -0.5f, 0,
|
||||||
|
-0.5f, 0.5f, 0,
|
||||||
|
|
||||||
|
|
||||||
|
0, 0.5f, 0.5f,
|
||||||
|
0, -0.5f, 0.5f,
|
||||||
|
0, -0.5f, -0.5f,
|
||||||
|
0, 0.5f, -0.5f,
|
||||||
|
|
||||||
|
|
||||||
|
0.5f, 0, 0.5f,
|
||||||
|
0.5f, 0, -0.5f,
|
||||||
|
-0.5f, 0, -0.5f,
|
||||||
|
-0.5f, 0, 0.5f
|
||||||
|
};
|
||||||
|
|
||||||
|
float[] normals = new float[]{
|
||||||
|
0.707f, 0.707f, 0,
|
||||||
|
0.707f, -0.707f, 0,
|
||||||
|
-0.707f, -0.707f, 0,
|
||||||
|
-0.707f, 0.707f, 0,
|
||||||
|
|
||||||
|
0, 0.707f, 0.707f,
|
||||||
|
0, -0.707f, 0.707f,
|
||||||
|
0, -0.707f, -0.707f,
|
||||||
|
0, 0.707f, -0.707f,
|
||||||
|
|
||||||
|
0.707f, 0, 0.707f,
|
||||||
|
0.707f, 0, -0.707f,
|
||||||
|
-0.707f, 0, -0.707f,
|
||||||
|
-0.707f, 0, 0.707f,
|
||||||
|
};
|
||||||
|
|
||||||
|
int[] elements = new int[]{
|
||||||
|
0, 1, 2,
|
||||||
|
0, 2, 3,
|
||||||
|
4, 5, 6,
|
||||||
|
4, 6, 7,
|
||||||
|
8, 9, 10,
|
||||||
|
8, 10, 11
|
||||||
|
};
|
||||||
|
|
||||||
|
float[] uvs = new float[]{
|
||||||
|
1, 1,
|
||||||
|
1, 0,
|
||||||
|
0, 0,
|
||||||
|
0, 1,
|
||||||
|
|
||||||
|
1, 1,
|
||||||
|
0, 1,
|
||||||
|
0, 0,
|
||||||
|
1, 0,
|
||||||
|
|
||||||
|
1, 1,
|
||||||
|
1, 0,
|
||||||
|
0, 0,
|
||||||
|
0, 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//Buffer data to GPU
|
||||||
|
//
|
||||||
|
|
||||||
|
try {
|
||||||
|
mesh.vertexCount = vertices.length / 3;
|
||||||
|
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(mesh.vertexCount * 3);
|
||||||
|
VertexArrayBufferData.put(vertices);
|
||||||
|
VertexArrayBufferData.flip();
|
||||||
|
mesh.buffer_vertices(VertexArrayBufferData, 3);
|
||||||
|
} catch (NullPointerException ex){
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// FACES
|
||||||
|
//
|
||||||
|
mesh.faceCount = elements.length / 3;
|
||||||
|
mesh.elementCount = elements.length;
|
||||||
|
try {
|
||||||
|
IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(mesh.elementCount);
|
||||||
|
elementArrayBufferData.put(elements);
|
||||||
|
elementArrayBufferData.flip();
|
||||||
|
mesh.buffer_faces(elementArrayBufferData);
|
||||||
|
} catch (NullPointerException ex){
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// NORMALS
|
||||||
|
//
|
||||||
|
try {
|
||||||
|
mesh.normalCount = normals.length / 3;
|
||||||
|
FloatBuffer NormalArrayBufferData;
|
||||||
|
if(mesh.normalCount > 0){
|
||||||
|
NormalArrayBufferData = BufferUtils.createFloatBuffer(mesh.normalCount * 3);
|
||||||
|
NormalArrayBufferData.put(normals);
|
||||||
|
NormalArrayBufferData.flip();
|
||||||
|
mesh.buffer_normals(NormalArrayBufferData, 3);
|
||||||
|
}
|
||||||
|
} catch (NullPointerException ex){
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// TEXTURE COORDINATES
|
||||||
|
//
|
||||||
|
try {
|
||||||
|
mesh.textureCoordCount = uvs.length / 2;
|
||||||
|
FloatBuffer TextureArrayBufferData;
|
||||||
|
if(mesh.textureCoordCount > 0){
|
||||||
|
TextureArrayBufferData = BufferUtils.createFloatBuffer(mesh.textureCoordCount * 2);
|
||||||
|
TextureArrayBufferData.put(uvs);
|
||||||
|
TextureArrayBufferData.flip();
|
||||||
|
mesh.buffer_texture_coords(TextureArrayBufferData, 2);
|
||||||
|
}
|
||||||
|
} catch (NullPointerException ex){
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
mesh.nodeID = "leaves";
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static Model generateLeavesModel(){
|
||||||
|
Model rVal = new Model();
|
||||||
|
rVal.meshes = new ArrayList<Mesh>();
|
||||||
|
Mesh m = generateLeafMesh();
|
||||||
|
|
||||||
|
|
||||||
|
Material groundMat = new Material();
|
||||||
|
groundMat.set_diffuse("/Textures/leavesStylized1.png");
|
||||||
|
groundMat.set_specular("/Textures/leavesStylized1.png");
|
||||||
|
Globals.assetManager.addTexturePathtoQueue("/Textures/leavesStylized1.png");
|
||||||
|
m.setMaterial(groundMat);
|
||||||
|
|
||||||
|
m.setShader(Globals.defaultMeshShader);
|
||||||
|
m.parent = rVal;
|
||||||
|
|
||||||
|
rVal.meshes.add(m);
|
||||||
|
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user