Expand a range of float numbers ? (keeping a uniform distribution) - range

Expand a random range from 0-6 to 0-7. Given a function rand6() that
returns a random float in the range [0,6] with a uniform distribution,
write a function that returns a random float in the range [0,7] using
only rand6() and keeping an uniform distribution.
Since we're working with float numbers, can i just do the following ?
x = rand6() / 6 * 7

Yes, absolutely. Your distribution will be scaled as well

Related

Do two floats in a compute shader being added or subtracted not give the same value 100% of the time?

I have a function I call to generate some randomness in my hlsl compute shader code
float rand3dTo1d(float3 value, float3 dotDir = float3(12.9898, 78.233, 37.719)){
//make value smaller to avoid artefacts
float3 smallValue = sin(value);
//get scalar value from 3d vector
float random = dot(smallValue, dotDir);
//make value more random by making it bigger and then taking the factional part
random = frac(sin(random) * 43758.5453);
return random;
}
If I pass in an incoming vectors location, all is fine, but if I try to pass in the center point of three vectors using this function into the randomness:
float3 GetTriangleCenter3d(float3 a, float3 b, float3 c) {
return (a + b + c) / 3.0;
}
Then ocassionally SOME of my points are not the same from frame to frame (shown by the color I paint the triangles with using this code). I get flickering of color.
float3 color = lerp(_ColorFrom, _ColorTo, rand1d);
I am at a total loss. I was able to at least get consitant results by using the thread id as the seed for the randomness, but not being able to use the centerpoint of the triangle is really weird to me and I have no idea what I am doing wrong or what I am missing. Any help would be great.

Rendering lighting from Spherical Harmonics in ARKit

I am trying to build a custom shader on the face in metal. As a result, I need to manually apply scene lighting from the spherical harmonics provided by ARKit.
I have implemented a function based on 3.2 (equation 13) from https://cseweb.ucsd.edu/~ravir/papers/envmap/envmap.pdf. I have the following metal function.
inline float estimateLightWithSHCoefficients(const float3 surfaceNormal,
const float L00,
const float L1n1, const float L10, const float L11,
const float L2n2, const float L2n1, const float L20, const float L21, const float L22) {
return (c1*L22*(pow(surfaceNormal.x, 2) - pow(surfaceNormal.y, 2)) + c3*L20*pow(surfaceNormal.z, 2) + c4*L00 - c5*L20
+ 2*c1*(L2n2*surfaceNormal.x*surfaceNormal.y + L21*surfaceNormal.x*surfaceNormal.z + L2n1*surfaceNormal.y*surfaceNormal.z)
+ 2*c2*(L11*surfaceNormal.x + L1n1*surfaceNormal.y + L10*surfaceNormal.z));
}
The constants are said as described in the paper. The coefficients (note that L2n1 corresponds to L2-2 in 3.2 - using n to indicate negative in the naming convention). The coefficients are set from the spherical harmonics output converted to floats (and then first 9 values are used as coefficients for red, next 9 for green, and last 9 for blue - I am not sure if this is the current order, and the inputs are given to the function in the same order as specified in the definition - would really appreciate any clarification if this is correct).
The vertex normal is obtained from ARSCNFaceGeometry's normal source but normalized. I am not sure if this is the correct way to do this.
I have been running some tests and I get negative light values in some positions (which should be clearly a bug). I would appreciate any advice as to why. I believe for this method to work both normal and spherical harmonics needs to be on the same coordinate system with the spherical harmonics centred at origin. I suspect that there might be an issue in where/how I am getting the normals/coefficients but that's just a guess. What's wrong with this approach?
If you have any pointers of existing implementations for calculating light using second-order spherical harmonics, I would highly appreciate it!
Thanks!

How to linearly interpolate animation curve in unity 3D?

After researching for hours and hours I am just not able to linearly interpolate two animation curve,I need something like Mathf.lerp for animation curve,I had try with inTangent and OutTangent with keyframes of the animation curve but it does not store the values,am I missing something ?
Need guidance,this would help me a lot in my project,thanks.
Seems to me you are looking to "morph" one animation curve into another. This imho depends on your use case.
Assuming both curves are defined between [0.0, 1.0], I'd calculate the curve value for t in both, and interpolate linearly both results over the same time.
/*
* Evaluates two AnimationCurve objects, and interpolates linearly
* between the results, effectively "morphing" from curve A to curve
* B in a linear fashion.
* Both curves must be defined between 0.0 and 1.0, and t must be
* within the same 0.0-1.0 range too.
*/
public float EvaluateLerpTwoCurves(AnimationCurve a, AnimationCurve b, float t) {
float valueA = a.Evaluate (t);
float valueB = b.Evaluate (t);
float result = Mathf.Lerp(valueA, valueB, t);
return result;
}
You may wish to interpolate between both AnimationCurve using a different approach (not linearly like Mathf.Lerp does), you could even use a third AnimationCurve to define how to morph between both curves.
Note that the suggested code above requires both curves to be defined between 0.0 and 1.0, and t must be within the same 0.0-1.0 range too.

Pack two floats within range into one float

In HLSL, how would I go about packing two floats within the range of 0-1 into one float with an optimal precision. This would be incredibly useful to compress my GBuffer further.
//Packing
float a = 0.45;
float b = 0.55;
uint aScaled = a * 0xFFFF;
uint bScaled = b * 0xFFFF;
uint abPacked = (aScaled << 16) | (bScaled & 0xFFFF);
float finalFloat = asfloat(abPacked);
//Unpacking
float inputFloat = finalFloat;
uint uintInput = asuint(inputFloat);
float aUnpacked = (uintInput >> 16) / 65535.0f;
float bUnpacked = (uintInput & 0xFFFF) / 65535.0f;
Converting floating point numbers to fixed point integers is an error prone idea, due to floats covering much larger magnitudes. Say unpacking sRGB will give you pow(255,2.2) values, which are larger than 0xffff, and you will need several times than amount for robust HDR. Generally fixed point code is very fragile, obfuscated and a nightmare to debug. People invented floats for a good reason.
There are several 16-bit float formats. IEEE 16-bit float one is optimized for numbers between -1.0 to 1.0, but also support numbers up to 0x10000, just in case you need HDR, still so you will need to normalize your larger floats for it, Then there is bfloat16, which behaves like normal 32-bit float, just with less precision. IEEE 16-bit floats are widely supported by modern CPUs and GPUs, and can also be converted quickly even in software. bfloat16 is just gaining popularity, so you will have to research if it is suitable for your needs. Finally you can introduce your own 16-bit float format, using integer log function, which is provided by most CPUs as a single instruction.

iPhone - AVAudioPlayer - convert decibel level into percent

I like to update an existing iPhone application which is using AudioQueue for playing audio files. The levels (peakPowerForChannel, averagePowerForChannel) were linear form 0.0f to 1.0f.
Now I like to use the simpler class AVAudioPlayer which works fine, the only issue is that the levels which are now in decibel, not linear from -120.0f to 0.0f.
Has anyone a formula to convert it back to the linear values between 0.0f and 1.0f?
Thanks
Tom
Several Apple examples use the following formula to convert the decibels into a linear range (from 0.0 to 1.0):
double percentage = pow (10, (0.05 * power));
where power is the value you get from one of the various level meter methods or functions, such as AVAudioPlayer's averagePowerForChannel:
Math behind the Linear and Logarithmic value conversion:
1. Linear to Decibel (logarithmic):
decibelValue = 20.0f * log10(linearValue)
Note: log is base 10
Suppose the linear value in the form of percentage range from [ 0 (min vol) to 100 (max vol)] then the decibelValue for half of the volume (50%) is
decibelValue = 20.0f * log10(50.0f/100.0f) = -6 dB
Full volume:
decibelValue = 20.0f * log10(100.0f/100.0f) = 0 dB
Complete mute:
decibelValue = 20.0f * log10(0/100.0f) = -infinity
2. Decibel(logarithmic) to Linear:
LinearValue = pow(10.0f, decibelValue/20.0f)
Apple uses a lookup table in their SpeakHere sample that converts from dB to a linear value displayed on a level meter.
I moulded their calculation in a small routine; see here.