1/** 2 * Mandelbulber v2, a 3D fractal generator _%}}i*<. ____ _______ 3 * Copyright (C) 2021 Mandelbulber Team _>]|=||i=i<, / __ \___ ___ ___ / ___/ / 4 * \><||i|=>>%) / /_/ / _ \/ -_) _ \/ /__/ /__ 5 * This file is part of Mandelbulber. )<=i=]=|=i<> \____/ .__/\__/_//_/\___/____/ 6 * The project is licensed under GPLv3, -<>>=|><|||` /_/ 7 * see also COPYING file in this folder. ~+{i%+++ 8 * 9 * Mandelbox fractal known as AmazingBox or ABox, invented by Tom Lowe in 2010 10 * Variable parameters over iteration time 11 * Based on work by Tglad, Buddhi, DarkBeam 12 * @reference 13 * http://www.fractalforums.com/ifs-iterated-function-systems/amazing-fractal/msg12467/#msg12467 14 * This formula contains aux.color and aux.actualScaleA 15 16 * This file has been autogenerated by tools/populateUiInformation.php 17 * from the file "fractal_mandelbox_variable.cpp" in the folder formula/definition 18 * D O N O T E D I T T H I S F I L E ! 19 */ 20 21REAL4 MandelboxVariableIteration(REAL4 z, __constant sFractalCl *fractal, sExtendedAuxCl *aux) 22{ 23 REAL colorAdd = 0.0f; 24 REAL rrCol = 0.0f; 25 REAL4 zCol = z; 26 REAL4 oldZ = z; 27 REAL4 limit4 = fractal->transformCommon.additionConstant111; 28 REAL4 value4 = 2.0f * fractal->transformCommon.additionConstant111; 29 if (fractal->transformCommon.functionEnabledFalse) 30 value4 = fractal->transformCommon.additionConstant222; 31 32 if (fractal->mandelbox.rotationsEnabled) 33 { // TODO evaluate implementation of vec3 limit and value 34 /* REAL4 zRot; 35 // cast vector to array pointer for address taking of components in opencl 36 REAL *zRotP = (REAL *)&zRot; 37 __constant REAL *colP = (__constant REAL *)&fractal->mandelbox.color.factor; 38 for (int dim = 0; dim < 3; dim++) 39 { 40 // handle each dimension x, y and z sequentially in pointer var dim 41 REAL *rotDim = (dim == 0) ? &zRotP[0] : ((dim == 1) ? &zRotP[1] : &zRotP[2]); 42 __constant REAL *colorFactor = (dim == 0) ? &colP[0] : ((dim == 1) ? &colP[1] : &colP[2]); 43 44 zRot = Matrix33MulFloat4(fractal->mandelbox.rot[0][dim], z); 45 if (*rotDim > fractal->mandelbox.foldingLimit) 46 { 47 *rotDim = fractal->mandelbox.foldingValue - *rotDim; 48 z = Matrix33MulFloat4(fractal->mandelbox.rotinv[0][dim], zRot); 49 aux->color += *colorFactor; 50 } 51 else 52 { 53 zRot = Matrix33MulFloat4(fractal->mandelbox.rot[1][dim], z); 54 if (*rotDim < -fractal->mandelbox.foldingLimit) 55 { 56 *rotDim = -fractal->mandelbox.foldingValue - *rotDim; 57 z = Matrix33MulFloat4(fractal->mandelbox.rotinv[1][dim], zRot); 58 aux->color += *colorFactor; 59 } 60 } 61 }*/ 62 } 63 else 64 { 65 if (!fractal->transformCommon.functionEnabledCyFalse) 66 { 67 z = fabs(z + limit4) - fabs(z - limit4) - z; 68 zCol = z; 69 } 70 else // variable limit values 71 { 72 if (fractal->transformCommon.functionEnabledAx) 73 { 74 if (aux->i > fractal->transformCommon.startIterationsC) 75 { 76 limit4.x *= (1.0f 77 - 1.0f 78 / (1.0f 79 + (aux->i - fractal->transformCommon.startIterationsC) 80 / fractal->transformCommon.offsetA000.x)) 81 * fractal->transformCommon.scale3D111.x; 82 } 83 z.x = fabs(z.x + limit4.x) - fabs(z.x - limit4.x) - z.x; 84 } 85 if (fractal->transformCommon.functionEnabledAy) 86 { 87 if (aux->i > fractal->transformCommon.startIterationsY) 88 { 89 limit4.y *= (1.0f 90 - 1.0f 91 / (1.0f 92 + (aux->i - fractal->transformCommon.startIterationsY) 93 / fractal->transformCommon.offsetA000.y)) 94 * fractal->transformCommon.scale3D111.y; 95 } 96 z.y = fabs(z.y + limit4.y) - fabs(z.y - limit4.y) - z.y; 97 } 98 if (fractal->transformCommon.functionEnabledAz) 99 { 100 if (aux->i > fractal->transformCommon.startIterationsZ) 101 { 102 limit4.z *= (1.0f 103 - 1.0f 104 / (1.0f 105 + (aux->i - fractal->transformCommon.startIterationsZ) 106 / fractal->transformCommon.offsetA000.z)) 107 * fractal->transformCommon.scale3D111.z; 108 } 109 z.z = fabs(z.z + limit4.z) - fabs(z.z - limit4.z) - z.z; 110 } 111 zCol = z; 112 } 113 } 114 115 // spherical folding 116 REAL maxR2use = fractal->transformCommon.maxR2d1; 117 REAL minR2use = fractal->transformCommon.minR2p25; 118 // vary maxR2 119 if (fractal->transformCommon.functionEnabledEFalse) 120 { 121 if (aux->i > fractal->transformCommon.startIterationsB) 122 { 123 maxR2use *= (1.0f 124 - 1.0f 125 / (1.0f 126 + (aux->i - fractal->transformCommon.startIterationsB) 127 / fractal->transformCommon.offsetA0)) 128 * fractal->transformCommon.scaleA1; 129 } 130 } 131 // vary minR2 132 if (fractal->transformCommon.functionEnabledDFalse) 133 { 134 if (aux->i > fractal->transformCommon.startIterationsA) 135 { 136 minR2use *= (1.0f 137 - 1.0f 138 / (1.0f 139 + (aux->i - fractal->transformCommon.startIterationsA) 140 / fractal->transformCommon.offset0)) 141 * fractal->transformCommon.scale1; 142 } 143 } 144 145 REAL rr = dot(z, z); 146 rrCol = rr; 147 // Mandelbox Spherical fold 148 149 z += fractal->mandelbox.offset; 150 151 // if (r2 < 1e-21f) r2 = 1e-21f; 152 if (rr < minR2use) 153 { 154 REAL tglad_factor1 = maxR2use / minR2use; 155 z *= tglad_factor1; 156 aux->DE *= tglad_factor1; 157 } 158 else if (rr < maxR2use) 159 { 160 REAL tglad_factor2 = maxR2use / rr; 161 z *= tglad_factor2; 162 aux->DE *= tglad_factor2; 163 } 164 z -= fractal->mandelbox.offset; 165 166 // 3D Rotation 167 if (fractal->mandelbox 168 .mainRotationEnabled) // z = Matrix33MulFloat4(fractal->mandelbox.mainRot, z); 169 { 170 REAL4 tempVC = (REAL4){fractal->mandelbox.rotationMain.x, fractal->mandelbox.rotationMain.y, 171 fractal->mandelbox.rotationMain.z, 0.0f}; // constant to be varied 172 if (fractal->transformCommon.functionEnabledPFalse) 173 { 174 if (aux->i >= fractal->transformCommon.startIterations 175 && aux->i < fractal->transformCommon.stopIterations 176 && (fractal->transformCommon.stopIterations - fractal->transformCommon.startIterations 177 != 0)) 178 { 179 REAL iterationRange = 180 fractal->transformCommon.stopIterations - fractal->transformCommon.startIterations; 181 REAL currentIteration = (aux->i - fractal->transformCommon.startIterations); 182 tempVC += fractal->transformCommon.offset000 * currentIteration / iterationRange; 183 } 184 185 if (aux->i >= fractal->transformCommon.stopIterations) 186 { 187 tempVC += tempVC + fractal->transformCommon.offset000; 188 } 189 } 190 191 tempVC *= M_PI_180_F; 192 193 z = RotateAroundVectorByAngle4(z, (REAL3){1.0f, 0.0f, 0.0f}, tempVC.x); 194 z = RotateAroundVectorByAngle4(z, (REAL3){0.0f, 1.0f, 0.0f}, tempVC.y); 195 z = RotateAroundVectorByAngle4(z, (REAL3){0.0f, 0.0f, 1.0f}, tempVC.z); 196 } 197 198 // scale 199 REAL useScale = 1.0f; 200 { 201 useScale = aux->actualScaleA + fractal->mandelbox.scale; 202 203 z *= useScale; 204 aux->DE = aux->DE * fabs(useScale) + 1.0f; 205 if (fractal->transformCommon.functionEnabledFFalse 206 && aux->i >= fractal->transformCommon.startIterationsX 207 && aux->i < fractal->transformCommon.stopIterationsX) 208 { 209 // update actualScaleA for next iteration 210 REAL vary = fractal->transformCommon.scaleVary0 211 * (fabs(aux->actualScaleA) - fractal->transformCommon.scaleB1); 212 if (fractal->transformCommon.functionEnabledNFalse) 213 aux->actualScaleA = -vary; 214 else 215 aux->actualScaleA = aux->actualScaleA - vary; 216 } 217 } 218 // add cpixel 219 REAL4 c = aux->const_c; 220 221 if (fractal->transformCommon.addCpixelEnabledFalse 222 && aux->i >= fractal->transformCommon.startIterationsH 223 && aux->i < fractal->transformCommon.stopIterationsH) 224 { 225 REAL4 tempC = aux->const_c; 226 if (fractal->transformCommon.alternateEnabledFalse) // alternate 227 { 228 tempC = aux->c; 229 switch (fractal->mandelbulbMulti.orderOfXYZ) 230 { 231 case multi_OrderOfXYZCl_xyz: 232 default: tempC = (REAL4){tempC.x, tempC.y, tempC.z, tempC.w}; break; 233 case multi_OrderOfXYZCl_xzy: tempC = (REAL4){tempC.x, tempC.z, tempC.y, tempC.w}; break; 234 case multi_OrderOfXYZCl_yxz: tempC = (REAL4){tempC.y, tempC.x, tempC.z, tempC.w}; break; 235 case multi_OrderOfXYZCl_yzx: tempC = (REAL4){tempC.y, tempC.z, tempC.x, tempC.w}; break; 236 case multi_OrderOfXYZCl_zxy: tempC = (REAL4){tempC.z, tempC.x, tempC.y, tempC.w}; break; 237 case multi_OrderOfXYZCl_zyx: tempC = (REAL4){tempC.z, tempC.y, tempC.x, tempC.w}; break; 238 } 239 aux->c = tempC; 240 } 241 else 242 { 243 switch (fractal->mandelbulbMulti.orderOfXYZ) 244 { 245 case multi_OrderOfXYZCl_xyz: 246 default: tempC = (REAL4){c.x, c.y, c.z, c.w}; break; 247 case multi_OrderOfXYZCl_xzy: tempC = (REAL4){c.x, c.z, c.y, c.w}; break; 248 case multi_OrderOfXYZCl_yxz: tempC = (REAL4){c.y, c.x, c.z, c.w}; break; 249 case multi_OrderOfXYZCl_yzx: tempC = (REAL4){c.y, c.z, c.x, c.w}; break; 250 case multi_OrderOfXYZCl_zxy: tempC = (REAL4){c.z, c.x, c.y, c.w}; break; 251 case multi_OrderOfXYZCl_zyx: tempC = (REAL4){c.z, c.y, c.x, c.w}; break; 252 } 253 } 254 // rotate c 255 if (fractal->transformCommon.rotationEnabled 256 && aux->i >= fractal->transformCommon.startIterationsG 257 && aux->i < fractal->transformCommon.stopIterationsG) 258 { 259 tempC = Matrix33MulFloat4(fractal->transformCommon.rotationMatrix, tempC); 260 } 261 // vary c 262 if (fractal->transformCommon.functionEnabledMFalse) 263 { 264 if (fractal->transformCommon.functionEnabledx) 265 { 266 if (aux->i > fractal->transformCommon.startIterationsM) 267 { 268 tempC.x *= (1.0f 269 - 1.0f 270 / (1.0f 271 + (aux->i - fractal->transformCommon.startIterationsM) 272 / fractal->transformCommon.offsetF000.x)) 273 * fractal->transformCommon.constantMultiplierB111.x; 274 } 275 } 276 if (fractal->transformCommon.functionEnabledy) 277 { 278 if (aux->i > fractal->transformCommon.startIterationsO) 279 { 280 tempC.y *= (1.0f 281 - 1.0f 282 / (1.0f 283 + (aux->i - fractal->transformCommon.startIterationsO) 284 / fractal->transformCommon.offsetF000.y)) 285 * fractal->transformCommon.constantMultiplierB111.y; 286 } 287 } 288 if (fractal->transformCommon.functionEnabledz) 289 { 290 if (aux->i > fractal->transformCommon.startIterationsP) 291 { 292 tempC.z *= (1.0f 293 - 1.0f 294 / (1.0f 295 + (aux->i - fractal->transformCommon.startIterationsP) 296 / fractal->transformCommon.offsetF000.z)) 297 * fractal->transformCommon.constantMultiplierB111.z; 298 } 299 } 300 } 301 z += tempC * fractal->transformCommon.constantMultiplier111; 302 } 303 304 // DE tweak 305 if (fractal->analyticDE.enabledFalse) 306 aux->DE = aux->DE * fractal->analyticDE.scale1 + fractal->analyticDE.offset0; 307 308 // color updated v2.13 & mode2 v2.14 309 if (fractal->foldColor.auxColorEnabledFalse) 310 { 311 if (fractal->transformCommon.functionEnabledCxFalse) 312 { 313 if (zCol.x != oldZ.x) 314 colorAdd += fractal->mandelbox.color.factor.x 315 * (fabs(zCol.x) - fractal->transformCommon.additionConstant111.x); 316 if (zCol.y != oldZ.y) 317 colorAdd += fractal->mandelbox.color.factor.y 318 * (fabs(zCol.y) - fractal->transformCommon.additionConstant111.y); 319 if (zCol.z != oldZ.z) 320 colorAdd += fractal->mandelbox.color.factor.z 321 * (fabs(zCol.z) - fractal->transformCommon.additionConstant111.z); 322 323 if (rrCol < fractal->transformCommon.maxR2d1) 324 { 325 if (rrCol < fractal->transformCommon.minR2p25) 326 colorAdd += 327 fractal->mandelbox.color.factorSp1 * (fractal->transformCommon.minR2p25 - rrCol) 328 + fractal->mandelbox.color.factorSp2 329 * (fractal->transformCommon.maxR2d1 - fractal->transformCommon.minR2p25); 330 else 331 colorAdd += 332 fractal->mandelbox.color.factorSp2 * (fractal->transformCommon.maxR2d1 - rrCol); 333 } 334 } 335 else 336 { 337 if (zCol.x != oldZ.x) colorAdd += fractal->mandelbox.color.factor.x; 338 if (zCol.y != oldZ.y) colorAdd += fractal->mandelbox.color.factor.y; 339 if (zCol.z != oldZ.z) colorAdd += fractal->mandelbox.color.factor.z; 340 341 if (rrCol < fractal->transformCommon.minR2p25) 342 colorAdd += fractal->mandelbox.color.factorSp1; 343 else if (rrCol < fractal->transformCommon.maxR2d1) 344 colorAdd += fractal->mandelbox.color.factorSp2; 345 } 346 aux->color += colorAdd; 347 } 348 return z; 349}