b486678290
Library -Artifacts
128 lines
4.2 KiB
Plaintext
128 lines
4.2 KiB
Plaintext
//
|
|
// conventions
|
|
// left = coord.x - 1
|
|
// right = coord.x + 1
|
|
// top = coord.y + 1
|
|
// bottom = coord.y - 1
|
|
//
|
|
|
|
//#include "../../../Shaders/NoiseLib/Noise.hlsl"
|
|
|
|
//Texture2D<float4> PrecipMask; //defines where rainfall will occur
|
|
Texture2D<float4> ReposeMask;
|
|
Texture2D<float> Collision;
|
|
Texture2D<float> TerrainHeightPrev; //previous frame
|
|
Texture2D<float> SedimentPrev;
|
|
Texture2D<float> Hardness;
|
|
|
|
//outputs
|
|
RWTexture2D<float> TerrainHeight; //terrain heightmap
|
|
RWTexture2D<float> Sediment; //suspended sediment concentration (being transported by the water)
|
|
|
|
float dt; //the time step for the simulation
|
|
float EffectScalar;
|
|
|
|
float4 texDim; //the dimensions of all of our textures (they must all be the same dimensions)
|
|
float3 terrainDim; //the dimensions of the terrain in world units
|
|
|
|
#define LEFT(C) C.y
|
|
#define RIGHT(C) C.x
|
|
#define TOP(C) C.z
|
|
#define BOTTOM(C) C.w
|
|
|
|
uint4 getSafeNeighbors(uint2 coord) {
|
|
return uint4(
|
|
(coord.x < (uint)texDim[0] - 1) ? coord.x + 1 : coord.x, //right index
|
|
(coord.x > 0) ? coord.x - 1 : coord.x, //left index
|
|
(coord.y < (uint)texDim[1] - 1) ? coord.y + 1 : coord.y, //top index
|
|
(coord.y > 0) ? coord.y - 1 : coord.y //bottom index
|
|
);
|
|
}
|
|
|
|
|
|
//
|
|
// Thermal Erosion
|
|
//
|
|
float4 angleOfRepose; //actually tan(theta), which is slope (m)
|
|
float4 dxdy; //<dx, dy, 1.0f / dx, 1.0f / dy>
|
|
float InvDiagMag;
|
|
|
|
|
|
void simulateThermalErosion(uint2 coord) {
|
|
uint4 neigh = getSafeNeighbors(coord);
|
|
|
|
float4 hCardinal = float4(TerrainHeightPrev[uint2(LEFT(neigh), coord.y)], //left
|
|
TerrainHeightPrev[uint2(RIGHT(neigh), coord.y)], //right
|
|
TerrainHeightPrev[uint2(coord.x, TOP(neigh))], //up
|
|
TerrainHeightPrev[uint2(coord.x, BOTTOM(neigh))]); //down
|
|
|
|
float4 hDiagonal = float4(TerrainHeightPrev[uint2(LEFT(neigh), TOP(neigh))], //top left
|
|
TerrainHeightPrev[uint2(RIGHT(neigh), TOP(neigh))], //top right
|
|
TerrainHeightPrev[uint2(LEFT(neigh), BOTTOM(neigh))], //bottom left
|
|
TerrainHeightPrev[uint2(RIGHT(neigh), BOTTOM(neigh))]); //bottom right
|
|
|
|
/*
|
|
float4 hardnessCardinal = saturate(float4(Hardness[uint2(neigh.y, coord.y)],
|
|
Hardness[uint2(neigh.x, coord.y)],
|
|
Hardness[uint2(coord.x, neigh.z)],
|
|
Hardness[uint2(coord.x, neigh.w)]));
|
|
|
|
float4 hardnessDiagonal = saturate(float4(Hardness[uint2(neigh.y, neigh.z)],
|
|
Hardness[uint2(neigh.x, neigh.z)],
|
|
Hardness[uint2(neigh.y, neigh.w)],
|
|
Hardness[uint2(neigh.x, neigh.w)]));
|
|
*/
|
|
|
|
float4 h = float4(TerrainHeightPrev[coord], TerrainHeightPrev[coord], TerrainHeightPrev[coord], TerrainHeightPrev[coord]);
|
|
|
|
float4 dhCardinal = terrainDim[1] * (h - hCardinal);
|
|
float4 dhDiagonal = terrainDim[1] * (h - hDiagonal);
|
|
|
|
float4 sCardinal = -1.0f * min(sign(dhCardinal), 0.0f);
|
|
float4 sDiagonal = -1.0f * min(sign(dhDiagonal), 0.0f);
|
|
|
|
/*
|
|
float4 cHardness = saturate(Hardness[coord]);
|
|
float4 hardness = lerp(cHardness, hardnessCardinal, sCardinal);
|
|
|
|
dhCardinal *= 1.0f - hardness;
|
|
|
|
hardness = lerp(cHardness, hardnessDiagonal, sDiagonal);
|
|
dhDiagonal *= 1.0f - hardness;
|
|
*/
|
|
|
|
//compute slopes
|
|
float4 mCardinal = abs(dhCardinal * float4(dxdy.z, dxdy.z, dxdy.w, dxdy.w));
|
|
float4 mDiagonal = abs(dhDiagonal * float4(InvDiagMag, InvDiagMag, InvDiagMag, InvDiagMag));
|
|
|
|
float tau = angleOfRepose.x;
|
|
|
|
float dv = 0.0f; //volume of sediment moved
|
|
|
|
//could probably vectorize this and eliminate the ifs...
|
|
if (mCardinal.x > tau) { dv += dhCardinal.x; }
|
|
if (mCardinal.y > tau) { dv += dhCardinal.y; }
|
|
if (mCardinal.z > tau) { dv += dhCardinal.z; }
|
|
if (mCardinal.w > tau) { dv += dhCardinal.w; }
|
|
|
|
if (mDiagonal.x > tau) { dv += 0.707f * dhDiagonal.x; }
|
|
if (mDiagonal.y > tau) { dv += 0.707f * dhDiagonal.y; }
|
|
if (mDiagonal.z > tau) { dv += 0.707f * dhDiagonal.z; }
|
|
if (mDiagonal.w > tau) { dv += 0.707f * dhDiagonal.w; }
|
|
|
|
float halfHeight = 0.5f * TerrainHeightPrev[coord];
|
|
dv = clamp(0.0625f * dt * dv, -halfHeight, halfHeight);
|
|
|
|
TerrainHeight[coord] = TerrainHeightPrev[coord] - dv;
|
|
Sediment[coord] += dv;
|
|
}
|
|
|
|
|
|
#pragma kernel ThermalErosion
|
|
|
|
[numthreads(8, 8, 1)]
|
|
void ThermalErosion(uint3 id : SV_DispatchThreadID)
|
|
{
|
|
simulateThermalErosion(id.xy);
|
|
}
|