Release v0.9.6

This commit is contained in:
nimblefox-ci
2026-07-31 19:29:07 +03:00
parent 3602e87e0c
commit 8e6b90a10e
264 changed files with 12411 additions and 2 deletions
@@ -0,0 +1,15 @@
// Licensed under the Non-Profit Open Software License version 3.0
// Variables
float2 ClampRange;
// Kernel
[numthreads(32,1,1)]
void Clamp (uint3 id : SV_DispatchThreadID)
{
if(id.x < HeightMapLength){ // Keep in bounds
// Update texture
HeightBuffer[id.x] = clamp(HeightBuffer[id.x], ClampRange.x, ClampRange.y);
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 87cf122e8f207694aa255ce415696591
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,14 @@
// Licensed under the Non-Profit Open Software License version 3.0
// Variables
float2 ExpanderMinMax;
// Kernel
[numthreads(32,1,1)]
void Expand (uint3 id : SV_DispatchThreadID)
{
if(id.x < HeightMapLength){ // Keep in bounds
// Expand height
HeightBuffer[id.x] = clamp((HeightBuffer[id.x] - ExpanderMinMax.x) / ExpanderMinMax.y, 0, 1);
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 32af8ef11d4f6e24289de4765f4d6347
timeCreated: 1556402402
@@ -0,0 +1,12 @@
// Licensed under the Non-Profit Open Software License version 3.0
// Variables
float HeightContrastPow;
// Kernel
[numthreads(32,1,1)]
void HeightContrast (uint3 id : SV_DispatchThreadID)
{
// Expand height
HeightBuffer[id.x] = clamp(pow(abs(HeightBuffer[id.x] + 0.5), HeightContrastPow) - 0.5, 0, 1);
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2386040a4e4bbb04faa3dcc57c80e435
timeCreated: 1556405164
@@ -0,0 +1,21 @@
// Licensed under the Non-Profit Open Software License version 3.0
// Kernel
[numthreads(32,32,1)]
void HeightMapToTexture (uint3 id : SV_DispatchThreadID)
{
// Get width and height of texture
int w,h;
Texture.GetDimensions(w,h);
// Calculate position relative to heightmap
float2 relativeID = RelativizeVector(id.x, id.y, w, h);
float2 heightMapPos = float2(relativeID.x * HeightMapResolution, relativeID.y * HeightMapResolution);
// Calculate height
float3 gradient = CalculateGradientAndHeight(heightMapPos, HeightMapResolution, HeightBuffer);
// Set height
Texture[id.xy] = float4(gradient.z,gradient.z,gradient.z,1);
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0ae8d18f40ac1974db9ed6523037bda7
timeCreated: 1556291579
@@ -0,0 +1,103 @@
// Licensed under the Non-Profit Open Software License version 3.0
// Variables
uint ErosionParticleCount;
uint ErosionMaxLifeTime;
float ErosionInertia;
float ErosionParticleStartSpeed;
float ErosionParticleStartWater;
float ErosionSedimentCapacityFactor;
float ErosionMinSedimentCapacity;
float ErosionSpeed;
float ErosionEvaporateSpeed;
float ErosionGravity;
float ErosionDepositSpeed;
// Kernel
[numthreads(32,1,1)]
void HydraulicErosion (uint3 id : SV_DispatchThreadID)
{
if(id.x < ErosionParticleCount){ // Keep in bounds
float randomNormalizedX = Random(id.x);
float randomNormalizedY = Random(id.x + HeightMapResolution * randomNormalizedX);
float2 pos = float2(
randomNormalizedX * HeightMapResolution,
randomNormalizedY * HeightMapResolution
);
// Particle values
float2 dir = float2(0,0);
float speed = ErosionParticleStartSpeed;
float water = ErosionParticleStartWater;
float sediment = 0;
for(uint lifeTime = 0; lifeTime < ErosionMaxLifeTime; lifeTime++){
// Calculate texture coords
uint2 coord = uint2(
(uint) pos.x,
(uint) pos.y
);
int index = PosToIndex(coord, HeightMapResolution);
// Calculate cell offset
float2 cellOffset = float2(
pos.x - float(coord.x),
pos.y - float(coord.y)
);
// Calculate interpolated gradient and height
float3 heightAndGradient = CalculateGradientAndHeight(pos, HeightMapResolution, HeightBuffer);
// Update the droplet's direction and position (move position 1 unit regardless of speed)
dir.x = (dir.x * ErosionInertia - heightAndGradient.x * (1 - ErosionInertia));
dir.y = (dir.y * ErosionInertia - heightAndGradient.y * (1 - ErosionInertia));
// Normalize dir
dir = Normalize2D(dir);
// Add to position
pos += dir;
// Header guard to check wheter particle is still inside texture and moving
if((dir.x == 0 && dir.y == 0) || pos.x <= 0 || pos.y <= 0 || pos.x >= float(HeightMapResolution - 2) || pos.y >= float(HeightMapResolution - 2)){ break; }
// Calculate new height and deltaHeight
float height = CalculateGradientAndHeight(pos, HeightMapResolution, HeightBuffer).z;
float deltaHeight = height - heightAndGradient.z;
// Calculate the droplet's sediment capacity (higher when moving fast down a slope and contains lots of water)
float sedimentCapacity = max(-deltaHeight, ErosionMinSedimentCapacity) * speed * water * ErosionSedimentCapacityFactor;
// If carrying more sediment than capacity, or if flowing uphill:
if (sediment > sedimentCapacity || deltaHeight > 0) {
// If moving uphill (deltaHeight > 0) try fill up to the current height, otherwise deposit a fraction of the excess sediment
float amountToDeposit = (deltaHeight > 0) ?
min(deltaHeight, sediment) :
(sediment - sedimentCapacity) * ErosionDepositSpeed;
// Remove deposited sediment
sediment -= amountToDeposit;
// Add the sediment to the four nodes of the current cell using bilinear interpolation
AddToBuffer(index, HeightMapResolution, cellOffset, amountToDeposit, HeightBuffer);
}
else {
// Erode a fraction of the droplet's current carry capacity.
// Clamp the erosion to the change in height so that it doesn't dig a hole in the terrain behind the droplet
float amountToErode = min((sedimentCapacity - sediment) * ErosionSpeed, -deltaHeight);
// Remove erosion amount from heightmap
AddToBuffer(index, HeightMapResolution, cellOffset, -amountToErode, HeightBuffer);
// Add eroded amount to sediment currently carried
sediment += amountToErode;
}
// Update droplet's speed and water content
speed = sqrt (max(0,speed * speed + deltaHeight * ErosionGravity));
water *= (1 - ErosionEvaporateSpeed);
}
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: fa4ceb37d27b27746821c24bfb4c208b
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,62 @@
// Licensed under the Non-Profit Open Software License version 3.0
// Variables
uint PerlinType;
float PerlinAmplitude;
float PerlinFrequency;
float2 PerlinOffset;
uint PerlinOctaves;
float PerlinOctavesStrength;
// Methods
float StandardPerlinNoise(uint id, float amplitude, float2 offset){
// Calculate vector
float2 pos = IndexToFloatVector(id, HeightMapResolution);
// Calculate x and y position
float x = float(pos.x) / HeightMapResolution;
float y = float(pos.y) / HeightMapResolution;
// Generate noise
return cnoise(float2(x * amplitude + offset.x, y * amplitude + offset.y));
}
float BillowyPerlinNoise(uint id, float amplitude, float2 offset){
float noise = StandardPerlinNoise(id, amplitude, offset);
return abs(noise * 2 - 1);
}
float RigidPerlinNoise(uint id, float amplitude, float2 offset){
return 1 - BillowyPerlinNoise(id, amplitude, offset);;
}
// Kernel
[numthreads(32,1,1)]
void PerlinNoise (uint3 id : SV_DispatchThreadID)
{
if(id.x < HeightMapLength){ // Keep in bounds
float total = 0;
float frequency = PerlinFrequency;
float amplitude = 1;
float maxvalue = 0;
for(uint i = 0; i < PerlinOctaves; i++){
// Types
if(PerlinType == 0){ // Standard
total += StandardPerlinNoise(id.x, frequency, PerlinOffset) * amplitude;
} else if(PerlinType == 1){ // Billowy
total += BillowyPerlinNoise(id.x, frequency, PerlinOffset) * amplitude;
} else if(PerlinType == 2){ // Rigid
total += RigidPerlinNoise(id.x, frequency, PerlinOffset) * amplitude;
}
maxvalue += amplitude;
amplitude *= PerlinOctavesStrength;
frequency *= 2;
}
// Update buffer
HeightBuffer[id.x] = total/maxvalue;
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 0260ec8f278be834195f00cac6315f59
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
// Licensed under the Non-Profit Open Software License version 3.0
// Variables
uint PseudoRandomNoiseSeed;
// Kernel
[numthreads(32,1,1)]
void PseudoRandomNoise (uint3 id : SV_DispatchThreadID)
{
if(id.x < HeightMapLength){ // Keep in bounds
// Calculate vector
uint2 pos = IndexToVector(id.x, HeightMapResolution);
// Generate noise
float noise = Random((pos.x + (pos.y * HeightMapResolution)) * PseudoRandomNoiseSeed);
// Update buffer
HeightBuffer[id.x] = noise;
}
}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 73e7265746e81774ebca11f4b98413e4
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,30 @@
// Licensed under the Non-Profit Open Software License version 3.0
// Variables
uint TerraceCount;
float TerraceShape;
bool Smooth;
// Kernel
[numthreads(1024,1,1)]
void Terrace (uint3 id : SV_DispatchThreadID)
{
if(id.x < HeightMapLength){ // Keep in bounds
float height = HeightBuffer[id.x] * TerraceCount; // Calculate height inside the terrace range
uint heightFloor = uint(height); // Floor the height
float difference = height - heightFloor; // Difference between height and floor. Normalized terrace
if(Smooth){ // Should the terraces be smooth or sharp. Changes what part of the sigmoid is used
difference = (NormalisedSigmoid(difference * 2 - 1, TerraceShape) + 1) / 2;
} else {
difference = NormalisedSigmoid(difference, TerraceShape);
}
// Calculate floor and ceil of terrace
float floor = float(heightFloor) / TerraceCount;
float ceil = float(heightFloor + 1) / TerraceCount;
// Update buffer
HeightBuffer[id.x] = lerp(floor, ceil, difference);
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8f9c8c3b289cae746b013fe7e3d21d3c
timeCreated: 1557500706