Integrated Sebastian Lague's Planet Generator Created Tour function in SectorRenderer which makes the camera follow each terrestrial planet in turn
73 lines
2.7 KiB
HLSL
73 lines
2.7 KiB
HLSL
static const float PI = 3.14159265359;
|
|
static const float TAU = PI * 2;
|
|
static const float maxFloat = 3.402823466e+38;
|
|
|
|
// Remap a value from one range to another
|
|
float remap(float v, float minOld, float maxOld, float minNew, float maxNew) {
|
|
return saturate(minNew + (v-minOld) * (maxNew - minNew) / (maxOld-minOld));
|
|
}
|
|
|
|
// Remap the components of a vector from one range to another
|
|
float4 remap(float4 v, float minOld, float maxOld, float minNew, float maxNew) {
|
|
return saturate(minNew + (v-minOld) * (maxNew - minNew) / (maxOld-minOld));//
|
|
}
|
|
|
|
// Remap a float value (with a known mininum and maximum) to a value between 0 and 1
|
|
float remap01(float v, float minOld, float maxOld) {
|
|
return saturate((v-minOld) / (maxOld-minOld));
|
|
}
|
|
|
|
// Remap a float2 value (with a known mininum and maximum) to a value between 0 and 1
|
|
float2 remap01(float2 v, float2 minOld, float2 maxOld) {
|
|
return saturate((v-minOld) / (maxOld-minOld));
|
|
}
|
|
|
|
// Smooth minimum of two values, controlled by smoothing factor k
|
|
// When k = 0, this behaves identically to min(a, b)
|
|
float smoothMin(float a, float b, float k) {
|
|
k = max(0, k);
|
|
// https://www.iquilezles.org/www/articles/smin/smin.htm
|
|
float h = max(0, min(1, (b - a + k) / (2 * k)));
|
|
return a * h + b * (1 - h) - k * h * (1 - h);
|
|
}
|
|
|
|
// Smooth maximum of two values, controlled by smoothing factor k
|
|
// When k = 0, this behaves identically to max(a, b)
|
|
float smoothMax(float a, float b, float k) {
|
|
k = min(0, -k);
|
|
float h = max(0, min(1, (b - a + k) / (2 * k)));
|
|
return a * h + b * (1 - h) - k * h * (1 - h);
|
|
}
|
|
|
|
float Blend(float startHeight, float blendDst, float height) {
|
|
return smoothstep(startHeight - blendDst / 2, startHeight + blendDst / 2, height);
|
|
}
|
|
|
|
|
|
// Returns vector (dstToSphere, dstThroughSphere)
|
|
// If ray origin is inside sphere, dstToSphere = 0
|
|
// If ray misses sphere, dstToSphere = maxValue; dstThroughSphere = 0
|
|
float2 raySphere(float3 sphereCentre, float sphereRadius, float3 rayOrigin, float3 rayDir) {
|
|
float3 offset = rayOrigin - sphereCentre;
|
|
float a = 1; // Set to dot(rayDir, rayDir) if rayDir might not be normalized
|
|
float b = 2 * dot(offset, rayDir);
|
|
float c = dot (offset, offset) - sphereRadius * sphereRadius;
|
|
float d = b * b - 4 * a * c; // Discriminant from quadratic formula
|
|
|
|
// Number of intersections: 0 when d < 0; 1 when d = 0; 2 when d > 0
|
|
if (d > 0) {
|
|
float s = sqrt(d);
|
|
float dstToSphereNear = max(0, (-b - s) / (2 * a));
|
|
float dstToSphereFar = (-b + s) / (2 * a);
|
|
|
|
// Ignore intersections that occur behind the ray
|
|
if (dstToSphereFar >= 0) {
|
|
return float2(dstToSphereNear, dstToSphereFar - dstToSphereNear);
|
|
}
|
|
}
|
|
// Ray did not intersect sphere
|
|
return float2(maxFloat, 0);
|
|
}
|
|
|
|
|
|
|