rocky plains biome
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
This commit is contained in:
parent
c3f372d600
commit
21c73c6672
@ -24,7 +24,15 @@
|
||||
],
|
||||
"surfaceGenerationParams": {
|
||||
"surfaceGenTag": "plains",
|
||||
"heightOffset": 10
|
||||
"heightOffset": 10,
|
||||
"floorVariants": [
|
||||
{
|
||||
"voxelId": 2,
|
||||
"frequency": 1.0,
|
||||
"dispersion": 1.0,
|
||||
"priority": 1.0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -53,6 +61,12 @@
|
||||
"surfaceGenTag": "hills",
|
||||
"heightOffset": 10,
|
||||
"floorVariants": [
|
||||
{
|
||||
"voxelId": 2,
|
||||
"frequency": 1.0,
|
||||
"dispersion": 1.0,
|
||||
"priority": 1.0
|
||||
}
|
||||
],
|
||||
"foliageDescriptions": [
|
||||
]
|
||||
@ -116,6 +130,53 @@
|
||||
"surfaceGenTag": "empty",
|
||||
"heightOffset": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "plains_rock",
|
||||
"displayName": "Plains (rock)",
|
||||
"isAerial": false,
|
||||
"isSurface": true,
|
||||
"isSubterranean": false,
|
||||
"regions": [
|
||||
{
|
||||
"frequency": 1.0,
|
||||
"baseFloorVoxel": 1,
|
||||
"floorVariants": [
|
||||
{
|
||||
"voxelId": 7,
|
||||
"frequency": 0.5,
|
||||
"dispersion": 0.5,
|
||||
"priority": 1.0
|
||||
},
|
||||
{
|
||||
"voxelId": 8,
|
||||
"frequency": 0.5,
|
||||
"dispersion": 0.5,
|
||||
"priority": 1.0
|
||||
}
|
||||
],
|
||||
"foliageDescription": [
|
||||
]
|
||||
}
|
||||
],
|
||||
"surfaceGenerationParams": {
|
||||
"surfaceGenTag": "plains",
|
||||
"heightOffset": 10,
|
||||
"floorVariants": [
|
||||
{
|
||||
"voxelId": 7,
|
||||
"frequency": 0.5,
|
||||
"dispersion": 0.5,
|
||||
"priority": 1.0
|
||||
},
|
||||
{
|
||||
"voxelId": 8,
|
||||
"frequency": 0.5,
|
||||
"dispersion": 0.5,
|
||||
"priority": 1.0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
|
||||
@ -35,7 +35,7 @@ out vec3 samplerIndexVec; //the indices in the atlas of textures to sample
|
||||
out vec3 samplerRatioVec; //the vector of HOW MUCH to pull from each texture in the atlas
|
||||
|
||||
|
||||
|
||||
float map(float value, float min1, float max1, float min2, float max2);
|
||||
|
||||
void main() {
|
||||
//normalize posiiton and normal
|
||||
@ -48,6 +48,9 @@ void main() {
|
||||
ViewFragPos = vec3(view * model * FinalVertex);
|
||||
Normal = mat3(transpose(inverse(model))) * aNormal;
|
||||
|
||||
// //clamp the aPos vector to just shy of its surrounding values
|
||||
// //this prevents sampling across into the next texture
|
||||
// vec3 clampedPos = vec3(map(aPos.x,0,1,0.02,0.98), map(aPos.y,0,1,0.02,0.98), map(aPos.z,0,1,0.02,0.98));
|
||||
//reference https://catlikecoding.com/unity/tutorials/advanced-rendering/triplanar-mapping/
|
||||
texPlane1 = aPos.zy * TEXTURE_MAP_SCALE;
|
||||
texPlane2 = aPos.xz * TEXTURE_MAP_SCALE;
|
||||
@ -71,3 +74,9 @@ void main() {
|
||||
//set final position with opengl space
|
||||
gl_Position = projection * view * model * FinalVertex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float map(float value, float min1, float max1, float min2, float max2) {
|
||||
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 402 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 108 KiB |
@ -1,3 +1,3 @@
|
||||
#maven.buildNumber.plugin properties file
|
||||
#Tue Apr 01 15:25:00 EDT 2025
|
||||
buildNumber=616
|
||||
#Wed Apr 02 13:31:25 EDT 2025
|
||||
buildNumber=617
|
||||
|
||||
@ -1411,6 +1411,10 @@ World creation options work
|
||||
(04/02/2025)
|
||||
Homogenous worlds actually generate-able
|
||||
Two EXCELLENT rock textures
|
||||
Fix rock2 texture
|
||||
biome floor elements controlling noise generator's voxel selection
|
||||
Plains (rock) biome
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -107,5 +107,5 @@ public class BiomeData {
|
||||
public BiomeSurfaceGenerationParams getSurfaceGenerationParams(){
|
||||
return surfaceGenerationParams;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package electrosphere.game.data.biome;
|
||||
|
||||
import electrosphere.util.noise.NoiseMapperElement;
|
||||
|
||||
/**
|
||||
* Describes how a given voxel type may be used to populate the floor of the biome
|
||||
*/
|
||||
public class BiomeFloorElement {
|
||||
public class BiomeFloorElement implements NoiseMapperElement {
|
||||
|
||||
/**
|
||||
* The id of the voxel type for this element in particular
|
||||
@ -25,4 +27,17 @@ public class BiomeFloorElement {
|
||||
*/
|
||||
Double priority;
|
||||
|
||||
/**
|
||||
* Gets the voxel id of this floor element
|
||||
* @return The voxel id
|
||||
*/
|
||||
public int getVoxelId(){
|
||||
return voxelId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFrequency() {
|
||||
return (float)(double)this.frequency;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -4,6 +4,9 @@ import java.util.List;
|
||||
|
||||
import org.graalvm.polyglot.HostAccess.Export;
|
||||
|
||||
import electrosphere.util.annotation.Exclude;
|
||||
import electrosphere.util.noise.NoiseMapper;
|
||||
|
||||
/**
|
||||
* Params for the surface generation algorithm
|
||||
*/
|
||||
@ -32,6 +35,19 @@ public class BiomeSurfaceGenerationParams {
|
||||
@Export
|
||||
List<BiomeFoliageDescription> foliageDescriptions;
|
||||
|
||||
/**
|
||||
* Used to map gradients into floor variants (ie to distribute the floor variants spatially)
|
||||
*/
|
||||
@Exclude
|
||||
NoiseMapper<BiomeFloorElement> floorVariantMapper;
|
||||
|
||||
/**
|
||||
* Precomputes the surface voxel distribution
|
||||
*/
|
||||
protected void precomputeSurfaceDistribution(){
|
||||
this.floorVariantMapper = new NoiseMapper<BiomeFloorElement>(floorVariants);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tag for the generation algorithm for generating the surface
|
||||
* @return The tag for the generation algorithm for generating the surface
|
||||
@ -64,6 +80,13 @@ public class BiomeSurfaceGenerationParams {
|
||||
return foliageDescriptions;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a floor variant based on a gradient value
|
||||
* @param gradientValue The gradient value
|
||||
* @return The floor element
|
||||
*/
|
||||
public BiomeFloorElement getFloorVariant(float gradientValue){
|
||||
return this.floorVariantMapper.lookup(gradientValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -54,6 +54,7 @@ public class BiomeTypeMap {
|
||||
idBiomeMap.put(id,biome);
|
||||
if(biome.isSurface()){
|
||||
this.surfaceBiomes.add(biome);
|
||||
biome.getSurfaceGenerationParams().precomputeSurfaceDistribution();
|
||||
}
|
||||
if(biome.isAerial()){
|
||||
this.skyBiomes.add(biome);
|
||||
@ -61,8 +62,9 @@ public class BiomeTypeMap {
|
||||
if(biome.isSubterranean()){
|
||||
this.subterraneanBiomes.add(biome);
|
||||
}
|
||||
indexBiomeMap.put(indexBiomeMap.size(),biome);
|
||||
biomeIndexMap.put(biome,indexBiomeMap.size());
|
||||
int index = indexBiomeMap.size();
|
||||
indexBiomeMap.put(index,biome);
|
||||
biomeIndexMap.put(biome,index);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -183,6 +183,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
|
||||
double surfaceHeight = heightfield[x][z];
|
||||
double gradient = gradientField[x][z];
|
||||
BiomeData surfaceBiome = surfaceBiomeMap[x][z];
|
||||
BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams();
|
||||
|
||||
for(int y = 0; y < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; y++){
|
||||
int finalWorldY = worldY + ((y * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION);
|
||||
@ -196,7 +197,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
|
||||
realX, realY, realZ,
|
||||
stride,
|
||||
surfaceHeight, gradient,
|
||||
surfaceBiome,
|
||||
surfaceBiome, surfaceParams,
|
||||
generationContext
|
||||
);
|
||||
if(voxel != null){
|
||||
|
||||
@ -2,6 +2,7 @@ package electrosphere.server.terrain.generation.voxelphase;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.game.data.biome.BiomeData;
|
||||
import electrosphere.game.data.biome.BiomeSurfaceGenerationParams;
|
||||
import electrosphere.server.terrain.generation.interfaces.GeneratedVoxel;
|
||||
import electrosphere.server.terrain.generation.interfaces.GenerationContext;
|
||||
import io.github.studiorailgun.MathUtils;
|
||||
@ -79,7 +80,7 @@ public class AnimeMountainsGen implements VoxelGenerator {
|
||||
int chunkX, int chunkY, int chunkZ,
|
||||
double realX, double realY, double realZ,
|
||||
int stride, double surfaceHeight, double surfaceGradient,
|
||||
BiomeData surfaceBiome,
|
||||
BiomeData surfaceBiome, BiomeSurfaceGenerationParams surfaceParams,
|
||||
GenerationContext generationContext
|
||||
) {
|
||||
Globals.profiler.beginAggregateCpuSample("AnimeMountainsGen.getVoxel");
|
||||
|
||||
@ -2,6 +2,7 @@ package electrosphere.server.terrain.generation.voxelphase;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.game.data.biome.BiomeData;
|
||||
import electrosphere.game.data.biome.BiomeSurfaceGenerationParams;
|
||||
import electrosphere.server.terrain.generation.interfaces.GeneratedVoxel;
|
||||
import electrosphere.server.terrain.generation.interfaces.GenerationContext;
|
||||
|
||||
@ -39,7 +40,7 @@ public class HillsVoxelGen implements VoxelGenerator {
|
||||
double realX, double realY, double realZ,
|
||||
int stride,
|
||||
double surfaceHeight, double surfaceGradient,
|
||||
BiomeData surfaceBiome,
|
||||
BiomeData surfaceBiome, BiomeSurfaceGenerationParams surfaceParams,
|
||||
GenerationContext generationContext
|
||||
){
|
||||
Globals.profiler.beginAggregateCpuSample("HillsVoxelGen.getVoxel");
|
||||
|
||||
@ -2,6 +2,7 @@ package electrosphere.server.terrain.generation.voxelphase;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.game.data.biome.BiomeData;
|
||||
import electrosphere.game.data.biome.BiomeSurfaceGenerationParams;
|
||||
import electrosphere.server.terrain.generation.interfaces.GeneratedVoxel;
|
||||
import electrosphere.server.terrain.generation.interfaces.GenerationContext;
|
||||
|
||||
@ -45,7 +46,7 @@ public class MountainVoxelGen implements VoxelGenerator {
|
||||
double realX, double realY, double realZ,
|
||||
int stride,
|
||||
double surfaceHeight, double surfaceGradient,
|
||||
BiomeData surfaceBiome,
|
||||
BiomeData surfaceBiome, BiomeSurfaceGenerationParams surfaceParams,
|
||||
GenerationContext generationContext
|
||||
){
|
||||
Globals.profiler.beginAggregateCpuSample("HillsVoxelGen.getVoxel");
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package electrosphere.server.terrain.generation.voxelphase;
|
||||
|
||||
import electrosphere.game.data.biome.BiomeData;
|
||||
import electrosphere.game.data.biome.BiomeFloorElement;
|
||||
import electrosphere.game.data.biome.BiomeSurfaceGenerationParams;
|
||||
import electrosphere.game.data.voxel.sampler.SamplerFile;
|
||||
import electrosphere.server.terrain.generation.interfaces.GeneratedVoxel;
|
||||
import electrosphere.server.terrain.generation.interfaces.GenerationContext;
|
||||
@ -62,7 +64,8 @@ public class NoiseVoxelGen implements VoxelGenerator {
|
||||
int chunkX, int chunkY, int chunkZ,
|
||||
double realX, double realY, double realZ,
|
||||
int stride, double surfaceHeight, double surfaceGradient,
|
||||
BiomeData surfaceBiome, GenerationContext generationContext
|
||||
BiomeData surfaceBiome, BiomeSurfaceGenerationParams surfaceParams,
|
||||
GenerationContext generationContext
|
||||
) {
|
||||
|
||||
//floor handling
|
||||
@ -91,11 +94,13 @@ public class NoiseVoxelGen implements VoxelGenerator {
|
||||
voxel.weight = -1.0f;
|
||||
voxel.type = 0;
|
||||
} else if(heightDiff < -strideMultiplier){
|
||||
BiomeFloorElement floorEl = surfaceParams.getFloorVariant((float)surfaceGradient);
|
||||
//generate full-size surface-type voxel
|
||||
double finalHeight = sample;
|
||||
voxel.weight = (float)finalHeight;
|
||||
voxel.type = 2;
|
||||
voxel.type = floorEl.getVoxelId();
|
||||
} else {
|
||||
BiomeFloorElement floorEl = surfaceParams.getFloorVariant((float)surfaceGradient);
|
||||
//surface
|
||||
double surfacePercent = -heightDiff / strideMultiplier;
|
||||
if(surfacePercent > 1.0 || surfacePercent < 0){
|
||||
@ -103,7 +108,7 @@ public class NoiseVoxelGen implements VoxelGenerator {
|
||||
}
|
||||
double finalHeight = sample * surfacePercent * 2 - 1;
|
||||
voxel.weight = (float)(finalHeight * sample);
|
||||
voxel.type = 2;
|
||||
voxel.type = floorEl.getVoxelId();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.server.terrain.generation.voxelphase;
|
||||
|
||||
import electrosphere.game.data.biome.BiomeData;
|
||||
import electrosphere.game.data.biome.BiomeSurfaceGenerationParams;
|
||||
import electrosphere.server.terrain.generation.interfaces.GeneratedVoxel;
|
||||
import electrosphere.server.terrain.generation.interfaces.GenerationContext;
|
||||
|
||||
@ -37,6 +38,7 @@ public interface VoxelGenerator {
|
||||
* @param surfaceHeight The height of the surface at x,z
|
||||
* @param surfaceGradient The rate of change in the surface at this point
|
||||
* @param surfaceBiome The surface biome of the chunk
|
||||
* @param surfaceGenPArams Extra parameters for generating surface voxel values
|
||||
* @param generationContext The generation context
|
||||
*/
|
||||
public void getVoxel(
|
||||
@ -46,7 +48,7 @@ public interface VoxelGenerator {
|
||||
double realX, double realY, double realZ,
|
||||
int stride,
|
||||
double surfaceHeight, double surfaceGradient,
|
||||
BiomeData surfaceBiome,
|
||||
BiomeData surfaceBiome, BiomeSurfaceGenerationParams surfaceGenParams,
|
||||
GenerationContext generationContext
|
||||
);
|
||||
|
||||
|
||||
76
src/main/java/electrosphere/util/noise/NoiseMapper.java
Normal file
76
src/main/java/electrosphere/util/noise/NoiseMapper.java
Normal file
@ -0,0 +1,76 @@
|
||||
package electrosphere.util.noise;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Maps objects to a frequency, then allows normalized noise values to index into the frequency range
|
||||
*/
|
||||
public class NoiseMapper<T> {
|
||||
|
||||
/**
|
||||
* The objects in the buckets
|
||||
*/
|
||||
List<T> objects;
|
||||
|
||||
/**
|
||||
* The frequencies
|
||||
*/
|
||||
float[] frequencies;
|
||||
|
||||
public NoiseMapper(List<T> objects){
|
||||
Map<NoiseMapperElement,T> typeMap = new HashMap<NoiseMapperElement,T>();
|
||||
//convert types
|
||||
List<NoiseMapperElement> elements = objects.stream().map(object -> {
|
||||
if(object instanceof NoiseMapperElement){
|
||||
NoiseMapperElement casted = (NoiseMapperElement)object;
|
||||
typeMap.put(casted,object);
|
||||
return casted;
|
||||
} else {
|
||||
throw new Error("Supplied a class that does not extend NoiseMapper! " + object.getClass());
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
//set frequencies
|
||||
float frequencySum = 0;
|
||||
for(NoiseMapperElement el : elements){
|
||||
frequencySum = frequencySum + el.getFrequency();
|
||||
}
|
||||
this.frequencies = new float[elements.size()];
|
||||
this.objects = new ArrayList<T>();
|
||||
int i = 0;
|
||||
float accumulator = 0;
|
||||
for(NoiseMapperElement el : elements){
|
||||
this.frequencies[i] = el.getFrequency() / frequencySum + accumulator;
|
||||
this.objects.add(typeMap.get(el));
|
||||
accumulator = accumulator + this.frequencies[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up a value's corresponding object
|
||||
* @param value The value
|
||||
* @return The object
|
||||
*/
|
||||
public T lookup(float value){
|
||||
if(value < 0){
|
||||
throw new Error("Supplied value less than 0! " + value);
|
||||
} else if(value > 1){
|
||||
throw new Error("Supplied value greater than 1! " + value);
|
||||
}
|
||||
int searchIndex = 0;
|
||||
float prevFreq = 0;
|
||||
while(searchIndex < frequencies.length){
|
||||
if(value >= prevFreq && value <= frequencies[searchIndex]){
|
||||
return objects.get(searchIndex);
|
||||
}
|
||||
prevFreq = frequencies[searchIndex];
|
||||
searchIndex++;
|
||||
}
|
||||
throw new Error("Failed to mape value " + value + " into object! " + frequencies + " " + objects);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package electrosphere.util.noise;
|
||||
|
||||
/**
|
||||
* An element that can be supplied to a noise mapper
|
||||
*/
|
||||
public interface NoiseMapperElement {
|
||||
|
||||
/**
|
||||
* Gets the frequency of this element
|
||||
* @return The frequency
|
||||
*/
|
||||
public float getFrequency();
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user