104 lines
2.9 KiB
Plaintext
104 lines
2.9 KiB
Plaintext
// Stochastic shared code
|
|
|
|
// Compute local triangle barycentric coordinates and vertex IDs
|
|
void TriangleGrid(float2 uv, float scale,
|
|
out float w1, out float w2, out float w3,
|
|
out int2 vertex1, out int2 vertex2, out int2 vertex3)
|
|
{
|
|
// Scaling of the input
|
|
uv *= 3.464 * scale; // 2 * sqrt(3)
|
|
|
|
// Skew input space into simplex triangle grid
|
|
const float2x2 gridToSkewedGrid = float2x2(1.0, 0.0, -0.57735027, 1.15470054);
|
|
float2 skewedCoord = mul(gridToSkewedGrid, uv);
|
|
|
|
// Compute local triangle vertex IDs and local barycentric coordinates
|
|
int2 baseId = int2(floor(skewedCoord));
|
|
float3 temp = float3(frac(skewedCoord), 0);
|
|
temp.z = 1.0 - temp.x - temp.y;
|
|
if (temp.z > 0.0)
|
|
{
|
|
w1 = temp.z;
|
|
w2 = temp.y;
|
|
w3 = temp.x;
|
|
vertex1 = baseId;
|
|
vertex2 = baseId + int2(0, 1);
|
|
vertex3 = baseId + int2(1, 0);
|
|
}
|
|
else
|
|
{
|
|
w1 = -temp.z;
|
|
w2 = 1.0 - temp.y;
|
|
w3 = 1.0 - temp.x;
|
|
vertex1 = baseId + int2(1, 1);
|
|
vertex2 = baseId + int2(1, 0);
|
|
vertex3 = baseId + int2(0, 1);
|
|
}
|
|
}
|
|
|
|
// Fast random hash function
|
|
float2 SimpleHash2(float2 p)
|
|
{
|
|
return frac(sin(mul(float2x2(127.1, 311.7, 269.5, 183.3), p)) * 4375.85453);
|
|
}
|
|
|
|
|
|
half3 BaryWeightBlend(half3 iWeights, half tex0, half tex1, half tex2, half contrast)
|
|
{
|
|
// compute weight with height map
|
|
const half epsilon = 1.0f / 1024.0f;
|
|
half3 weights = half3(iWeights.x * (tex0 + epsilon),
|
|
iWeights.y * (tex1 + epsilon),
|
|
iWeights.z * (tex2 + epsilon));
|
|
|
|
// Contrast weights
|
|
half maxWeight = max(weights.x, max(weights.y, weights.z));
|
|
half transition = contrast * maxWeight;
|
|
half threshold = maxWeight - transition;
|
|
half scale = 1.0f / transition;
|
|
weights = saturate((weights - threshold) * scale);
|
|
// Normalize weights.
|
|
half weightScale = 1.0f / (weights.x + weights.y + weights.z);
|
|
weights *= weightScale;
|
|
return weights;
|
|
}
|
|
|
|
void PrepareStochasticUVs(float scale, float3 uv, out float3 uv1, out float3 uv2, out float3 uv3, out half3 weights)
|
|
{
|
|
// Get triangle info
|
|
float w1, w2, w3;
|
|
int2 vertex1, vertex2, vertex3;
|
|
TriangleGrid(uv.xy, scale, w1, w2, w3, vertex1, vertex2, vertex3);
|
|
|
|
// Assign random offset to each triangle vertex
|
|
uv1 = uv;
|
|
uv2 = uv;
|
|
uv3 = uv;
|
|
|
|
uv1.xy += SimpleHash2(vertex1);
|
|
uv2.xy += SimpleHash2(vertex2);
|
|
uv3.xy += SimpleHash2(vertex3);
|
|
weights = half3(w1, w2, w3);
|
|
|
|
}
|
|
|
|
void PrepareStochasticUVs(float scale, float2 uv, out float2 uv1, out float2 uv2, out float2 uv3, out half3 weights)
|
|
{
|
|
// Get triangle info
|
|
float w1, w2, w3;
|
|
int2 vertex1, vertex2, vertex3;
|
|
TriangleGrid(uv, scale, w1, w2, w3, vertex1, vertex2, vertex3);
|
|
|
|
// Assign random offset to each triangle vertex
|
|
uv1 = uv;
|
|
uv2 = uv;
|
|
uv3 = uv;
|
|
|
|
uv1.xy += SimpleHash2(vertex1);
|
|
uv2.xy += SimpleHash2(vertex2);
|
|
uv3.xy += SimpleHash2(vertex3);
|
|
weights = half3(w1, w2, w3);
|
|
|
|
}
|
|
|