Aetheria/Assets/Plugins/Celestial Body/Scripts/Shaders/Includes/Math.cginc
Reinier Vens 53a91351b7 Procedural Planets
Integrated Sebastian Lague's Planet Generator
Created Tour function in SectorRenderer which makes the camera follow each terrestrial planet in turn
2020-12-05 23:43:02 +00:00

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);
}