| 111 | } |
| 112 | |
| 113 | uint8_t getPaletteIndex(uint32_t millis32, int i, int j, uint32_t y_speed) { |
| 114 | // This function calculates which color to use from our palette for each LED |
| 115 | |
| 116 | // Get the scale factor from the UI slider (controls the "size" of the fire) |
| 117 | uint16_t scale = scaleXY.as<uint16_t>(); |
| 118 | |
| 119 | // Calculate 3D coordinates for the Perlin noise function: |
| 120 | uint16_t x = i * scale; // X position (horizontal in matrix) |
| 121 | uint32_t y = j * scale + y_speed; // Y position (vertical) + movement offset |
| 122 | uint16_t z = millis32 / invSpeedZ.as<uint16_t>(); // Z position (time dimension) |
| 123 | |
| 124 | // Generate 16-bit Perlin noise value using these coordinates |
| 125 | // The << 8 shifts values left by 8 bits (multiplies by 256) to use the full 16-bit range |
| 126 | uint16_t noise16 = inoise16(x << 8, y << 8, z << 8); |
| 127 | |
| 128 | // Convert 16-bit noise to 8-bit by taking the high byte (>> 8 shifts right by 8 bits) |
| 129 | uint8_t noise_val = noise16 >> 8; |
| 130 | |
| 131 | // Calculate how much to subtract based on vertical position (j) |
| 132 | // This creates the fade-out effect from bottom to top |
| 133 | // abs8() ensures we get a positive value |
| 134 | // The formula maps j from 0 to HEIGHT-1 to a value from 255 to 0 |
| 135 | int8_t subtraction_factor = abs8(j - (HEIGHT - 1)) * 255 / (HEIGHT - 1); |
| 136 | |
| 137 | // Subtract the factor from the noise value (with underflow protection) |
| 138 | // qsub8 is a "saturating subtraction" - it won't go below 0 |
| 139 | return qsub8(noise_val, subtraction_factor); |
| 140 | } |
| 141 | |
| 142 | fl::CRGBPalette16 getPalette() { |
| 143 | // This function returns the appropriate color palette based on the UI selection |