public PSSpectrum Clamp(float low = 0f, float high = float.MaxValue) { PSSpectrum ret = new PSSpectrum(0f); fixed (float* spd = spectra) for (int i = 0; i < nSamples; i++) ret[i] = Clamp(spd[i], low, high); return ret; }
public PSSpectrum Pow(RgbSpectrum e) { PSSpectrum ret = new PSSpectrum(0f); for (int i = 0; i < nSamples; i++) ret[i] = this[i] > 0 ? (float)Math.Pow(this[i], (float)e[i]) : 0f; return ret; }
public static PSSpectrum Exp(RgbSpectrum s) { PSSpectrum ret = new PSSpectrum(0f); for (int i = 0; i < nSamples; i++) ret[i] = (float)Math.Exp((float)s[i]); return ret; }
public static PSSpectrum FromSampled(float[] lambda, float[] values, SpectrumType type = SpectrumType.Reflectance) { var n = lambda.Length; if (!SpectrumSamplesSorted(lambda, values, lambda.Length)) { SortSpectrumSamples(ref lambda, ref values); return FromSampled(lambda, values, type); } var r = new PSSpectrum(0f); for (int i = 0; i < nSpectralSamples; ++i) { // Compute average value of given SPD over $i$th sample's range float lambda0 = MathLab.Lerp((float)(i) / (float)(nSpectralSamples), sampledLambdaStart, sampledLambdaEnd); float lambda1 = MathLab.Lerp((float)(i + 1f) / (float)(nSpectralSamples), sampledLambdaStart, sampledLambdaEnd); r.spectra[i] = AverageSpectrumSamples(lambda, values, n, lambda0, lambda1); } return r; }
public static PSSpectrum Lerp(float t, ref PSSpectrum s1, ref PSSpectrum s2) { return (1f - t) * s1 + t * s2; }
//public static PSSpectrum FromRgb(ref RgbSpectrum rgbSp, SpectrumType type = SpectrumType.Reflectance) //{ // var rgb = rgbSp.ToArray(); // return FromRGB(rgb, type); //} public static PSSpectrum FromRGB_old(float[] rgb, SpectrumType type = SpectrumType.Reflectance) { var r = new PSSpectrum(0f); if (type == SpectrumType.Reflectance) { // Convert reflectance spectrum to RGB if ((rgb[0] <= rgb[1]) && (rgb[0] <= rgb[2])) { // Compute reflectance _PSSpectrum_ with _rgb[0]_ as minimum r += rgb[0] * rgbRefl2SpectWhite; if (rgb[1] <= rgb[2]) { r += (rgb[1] - rgb[0]) * rgbRefl2SpectCyan; r += (rgb[2] - rgb[1]) * rgbRefl2SpectBlue; } else { r += (rgb[2] - rgb[0]) * rgbRefl2SpectCyan; r += (rgb[1] - rgb[2]) * rgbRefl2SpectGreen; } } else if (rgb[1] <= rgb[0] && rgb[1] <= rgb[2]) { // Compute reflectance _PSSpectrum_ with _rgb[1]_ as minimum r += rgb[1] * rgbRefl2SpectWhite; if (rgb[0] <= rgb[2]) { r += (rgb[0] - rgb[1]) * rgbRefl2SpectMagenta; r += (rgb[2] - rgb[0]) * rgbRefl2SpectBlue; } else { r += (rgb[2] - rgb[1]) * rgbRefl2SpectMagenta; r += (rgb[0] - rgb[2]) * rgbRefl2SpectRed; } } else { // Compute reflectance _PSSpectrum_ with _rgb[2]_ as minimum r += rgb[2] * rgbRefl2SpectWhite; if (rgb[0] <= rgb[1]) { r += (rgb[0] - rgb[2]) * rgbRefl2SpectYellow; r += (rgb[1] - rgb[0]) * rgbRefl2SpectGreen; } else { r += (rgb[1] - rgb[2]) * rgbRefl2SpectYellow; r += (rgb[0] - rgb[1]) * rgbRefl2SpectRed; } } r *= .94f; } else { // Convert illuminant spectrum to RGB if (rgb[0] <= rgb[1] && rgb[0] <= rgb[2]) { // Compute illuminant _PSSpectrum_ with _rgb[0]_ as minimum r += rgb[0] * rgbIllum2SpectWhite; if (rgb[1] <= rgb[2]) { r += (rgb[1] - rgb[0]) * rgbIllum2SpectCyan; r += (rgb[2] - rgb[1]) * rgbIllum2SpectBlue; } else { r += (rgb[2] - rgb[0]) * rgbIllum2SpectCyan; r += (rgb[1] - rgb[2]) * rgbIllum2SpectGreen; } } else if (rgb[1] <= rgb[0] && rgb[1] <= rgb[2]) { // Compute illuminant _PSSpectrum_ with _rgb[1]_ as minimum r += rgb[1] * rgbIllum2SpectWhite; if (rgb[0] <= rgb[2]) { r += (rgb[0] - rgb[1]) * rgbIllum2SpectMagenta; r += (rgb[2] - rgb[0]) * rgbIllum2SpectBlue; } else { r += (rgb[2] - rgb[1]) * rgbIllum2SpectMagenta; r += (rgb[0] - rgb[2]) * rgbIllum2SpectRed; } } else { // Compute illuminant _PSSpectrum_ with _rgb[2]_ as minimum r += rgb[2] * rgbIllum2SpectWhite; if (rgb[0] <= rgb[1]) { r += (rgb[0] - rgb[2]) * rgbIllum2SpectYellow; r += (rgb[1] - rgb[0]) * rgbIllum2SpectGreen; } else { r += (rgb[1] - rgb[2]) * rgbIllum2SpectYellow; r += (rgb[0] - rgb[1]) * rgbIllum2SpectRed; } } r *= .86445f; } return r.Clamp(); }
public static PSSpectrum FromRGB(float[] rgb, SpectrumType type = SpectrumType.Reflectance) { var r = new PSSpectrum(0f); if (type == SpectrumType.Reflectance) { // Convert reflectance spectrum to RGB if (rgb[0] <= rgb[1] && rgb[0] <= rgb[2]) { // Compute reflectance _PSSpectrum_ with _rgb[0]_ as minimum //r += rgb[0] * rgbRefl2SpectWhite; r.MAdd(ref rgbRefl2SpectWhite, rgb[0]); if (rgb[1] <= rgb[2]) { r.MAdd(ref rgbRefl2SpectCyan, (rgb[1] - rgb[0])); r.MAdd(ref rgbRefl2SpectBlue, (rgb[2] - rgb[1])); //r += (rgb[1] - rgb[0]) * rgbRefl2SpectCyan; //r += (rgb[2] - rgb[1]) * rgbRefl2SpectBlue; } else { //r += (rgb[2] - rgb[0]) * rgbRefl2SpectCyan; //r += (rgb[1] - rgb[2]) * rgbRefl2SpectGreen; r.MAdd(ref rgbRefl2SpectCyan, (rgb[2] - rgb[0])); r.MAdd(ref rgbRefl2SpectGreen, (rgb[1] - rgb[2])); } } else if (rgb[1] <= rgb[0] && rgb[1] <= rgb[2]) { // Compute reflectance _PSSpectrum_ with _rgb[1]_ as minimum //r += rgb[1] * rgbRefl2SpectWhite; r.MAdd(ref rgbRefl2SpectWhite, rgb[1]); if (rgb[0] <= rgb[2]) { //r += (rgb[0] - rgb[1]) * rgbRefl2SpectMagenta; //r += (rgb[2] - rgb[0]) * rgbRefl2SpectBlue; r.MAdd(ref rgbRefl2SpectMagenta, (rgb[0] - rgb[1])); r.MAdd(ref rgbRefl2SpectBlue, (rgb[2] - rgb[0])); } else { //r += (rgb[2] - rgb[1]) * rgbRefl2SpectMagenta; //r += (rgb[0] - rgb[2]) * rgbRefl2SpectRed; r.MAdd(ref rgbRefl2SpectMagenta, (rgb[2] - rgb[1])); r.MAdd(ref rgbRefl2SpectRed, (rgb[0] - rgb[2])); } } else { // Compute reflectance _PSSpectrum_ with _rgb[2]_ as minimum //r += rgb[2] * rgbRefl2SpectWhite; r.MAdd(ref rgbRefl2SpectWhite, rgb[2]); if (rgb[0] <= rgb[1]) { //r += (rgb[0] - rgb[2]) * rgbRefl2SpectYellow; //r += (rgb[1] - rgb[0]) * rgbRefl2SpectGreen; r.MAdd(ref rgbRefl2SpectYellow, (rgb[0] - rgb[2])); r.MAdd(ref rgbRefl2SpectGreen, (rgb[1] - rgb[0])); } else { //r += (rgb[1] - rgb[2]) * rgbRefl2SpectYellow; //r += (rgb[0] - rgb[1]) * rgbRefl2SpectRed; r.MAdd(ref rgbRefl2SpectYellow, (rgb[1] - rgb[2])); r.MAdd(ref rgbRefl2SpectRed, (rgb[0] - rgb[1])); } } r *= .94f; } else { // Convert illuminant spectrum to RGB if (rgb[0] <= rgb[1] && rgb[0] <= rgb[2]) { // Compute illuminant _PSSpectrum_ with _rgb[0]_ as minimum //r += rgb[0] * rgbIllum2SpectWhite; r.MAdd(ref rgbIllum2SpectWhite, rgb[0]); if (rgb[1] <= rgb[2]) { //r += (rgb[1] - rgb[0]) * rgbIllum2SpectCyan; //r += (rgb[2] - rgb[1]) * rgbIllum2SpectBlue; r.MAdd(ref rgbIllum2SpectCyan, (rgb[1] - rgb[0])); r.MAdd(ref rgbIllum2SpectBlue, (rgb[2] - rgb[1])); } else { // r += (rgb[2] - rgb[0]) * rgbIllum2SpectCyan; //r += (rgb[1] - rgb[2]) * rgbIllum2SpectGreen; r.MAdd(ref rgbIllum2SpectCyan, (rgb[2] - rgb[0])); r.MAdd(ref rgbIllum2SpectGreen, (rgb[1] - rgb[2])); } } else if (rgb[1] <= rgb[0] && rgb[1] <= rgb[2]) { // Compute illuminant _PSSpectrum_ with _rgb[1]_ as minimum //r += rgb[1] * rgbIllum2SpectWhite; r.MAdd(ref rgbIllum2SpectWhite, rgb[1]); if (rgb[0] <= rgb[2]) { //r += (rgb[0] - rgb[1]) * rgbIllum2SpectMagenta; //r += (rgb[2] - rgb[0]) * rgbIllum2SpectBlue; r.MAdd(ref rgbIllum2SpectMagenta, (rgb[0] - rgb[1])); r.MAdd(ref rgbIllum2SpectBlue, (rgb[2] - rgb[0])); } else { //r += (rgb[2] - rgb[1]) * rgbIllum2SpectMagenta; //r += (rgb[0] - rgb[2]) * rgbIllum2SpectRed; r.MAdd(ref rgbIllum2SpectMagenta, (rgb[2] - rgb[1])); r.MAdd(ref rgbIllum2SpectRed, (rgb[0] - rgb[2])); } } else { // Compute illuminant _PSSpectrum_ with _rgb[2]_ as minimum //r += rgb[2] * rgbIllum2SpectWhite; r.MAdd(ref rgbIllum2SpectWhite, rgb[2]); if (rgb[0] <= rgb[1]) { //r += (rgb[0] - rgb[2]) * rgbIllum2SpectYellow; //r += (rgb[1] - rgb[0]) * rgbIllum2SpectGreen; r.MAdd(ref rgbIllum2SpectYellow, (rgb[0] - rgb[2])); r.MAdd(ref rgbIllum2SpectGreen, (rgb[1] - rgb[0])); } else { //r += (rgb[1] - rgb[2]) * rgbIllum2SpectYellow; //r += (rgb[0] - rgb[1]) * rgbIllum2SpectRed; r.MAdd(ref rgbIllum2SpectYellow, (rgb[1] - rgb[2])); r.MAdd(ref rgbIllum2SpectRed, (rgb[0] - rgb[1])); } } r *= .86445f; } r.ClampSelf(); return r; }
static PSSpectrum() { X = new PSSpectrum(0f); Y = new PSSpectrum(0f); Z = new PSSpectrum(0f); // Compute XYZ matching functions for _PSSpectrum_ for (int i = 0; i < nSpectralSamples; i++) { float wl0 = MathLab.Lerp(i / (float)nSpectralSamples, sampledLambdaStart, sampledLambdaEnd); float wl1 = MathLab.Lerp((i + 1f) / nSpectralSamples, sampledLambdaStart, sampledLambdaEnd); X[i] = AverageSpectrumSamples(CIE_lambda, CIE_X, nCIESamples, wl0, wl1); Y[i] = AverageSpectrumSamples(CIE_lambda, CIE_Y, nCIESamples, wl0, wl1); Z[i] = AverageSpectrumSamples(CIE_lambda, CIE_Z, nCIESamples, wl0, wl1); yint += Y[i]; } Init(); }
public void MAdd(ref PSSpectrum sp, ref PSSpectrum f) { for (int i = 0; i < nSamples; i++) { this[i] += sp[i] * f[i]; } }
public static PSSpectrum operator /(PSSpectrum a, float b) { var result = new PSSpectrum(0f); for (int i = 0; i < nSamples; i++) { result.spectra[i] = a.spectra[i] / b; } return result; }
public static PSSpectrum operator -(PSSpectrum a, PSSpectrum b) { var result = new PSSpectrum(0f); for (int i = 0; i < nSamples; i++) { result.spectra[i] = a.spectra[i] - b.spectra[i]; } return result; }
public PSSpectrum(PSSpectrum sp) { //spectra = new float[nSamples]; fixed (float* spd = spectra) for (int i = 0; i < nSamples; i++) spd[i] = sp.spectra[i]; }