1 /** 2 * Mandelbulber v2, a 3D fractal generator ,=#MKNmMMKmmßMNWy, 3 * ,B" ]L,,p%%%,,,§;, "K 4 * Copyright (C) 2014-21 Mandelbulber Team §R-==%w["'~5]m%=L.=~5N 5 * ,=mm=§M ]=4 yJKA"/-Nsaj "Bw,==,, 6 * This file is part of Mandelbulber. §R.r= jw",M Km .mM FW ",§=ß., ,TN 7 * ,4R =%["w[N=7]J '"5=],""]]M,w,-; T=]M 8 * Mandelbulber is free software: §R.ß~-Q/M=,=5"v"]=Qf,'§"M= =,M.§ Rz]M"Kw 9 * you can redistribute it and/or §w "xDY.J ' -"m=====WeC=\ ""%""y=%"]"" § 10 * modify it under the terms of the "§M=M =D=4"N #"%==A%p M§ M6 R' #"=~.4M 11 * GNU General Public License as §W =, ][T"]C § § '§ e===~ U !§[Z ]N 12 * published by the 4M",,Jm=,"=e~ § § j]]""N BmM"py=ßM 13 * Free Software Foundation, ]§ T,M=& 'YmMMpM9MMM%=w=,,=MT]M m§;'§, 14 * either version 3 of the License, TWw [.j"5=~N[=§%=%W,T ]R,"=="Y[LFT ]N 15 * or (at your option) TW=,-#"%=;[ =Q:["V"" ],,M.m == ]N 16 * any later version. J§"mr"] ,=,," =="""J]= M"M"]==ß" 17 * §= "=C=4 §"eM "=B:m|4"]#F,§~ 18 * Mandelbulber is distributed in "9w=,,]w em%wJ '"~" ,=,,ß" 19 * the hope that it will be useful, . "K= ,=RMMMßM""" 20 * but WITHOUT ANY WARRANTY; .''' 21 * without even the implied warranty 22 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 23 * 24 * See the GNU General Public License for more details. 25 * You should have received a copy of the GNU General Public License 26 * along with Mandelbulber. If not, see <http://www.gnu.org/licenses/>. 27 * 28 * ########################################################################### 29 * 30 * Authors: Krzysztof Marczak (buddhi1980@gmail.com) 31 * 32 * cRenderWorker class - worker for rendering image on single CPU core 33 */ 34 35 #ifndef MANDELBULBER2_SRC_RENDER_WORKER_HPP_ 36 #define MANDELBULBER2_SRC_RENDER_WORKER_HPP_ 37 38 #include <memory> 39 40 #include <QObject> 41 #include <QThread> 42 43 #include "algebra.hpp" 44 #include "color_structures.hpp" 45 #include "texture_enums.hpp" 46 47 // forward declarations 48 class cMaterial; 49 class cLight; 50 class cCameraTarget; 51 class cImage; 52 struct sRenderData; 53 struct sParamRender; 54 class cNineFractals; 55 class cScheduler; 56 class cPerlinNoiseOctaves; 57 58 #define MAX_RAYMARCHING 10000 59 60 // ambient occlusion data 61 struct sVectorsAround 62 { 63 double alpha; 64 double beta; 65 CVector3 v; 66 sRGBFloat color; 67 }; 68 69 class cRenderWorker : public QObject 70 { 71 Q_OBJECT 72 73 public: 74 struct sThreadData 75 { 76 int id; 77 int startLine; 78 std::shared_ptr<cScheduler> scheduler; 79 }; 80 81 cRenderWorker(std::shared_ptr<const sParamRender> _params, 82 std::shared_ptr<const cNineFractals> _fractal, std::shared_ptr<sThreadData> _threadData, 83 std::shared_ptr<sRenderData> _data, std::shared_ptr<cImage> _image); 84 ~cRenderWorker() override; 85 86 // PrepareAOVectors() is public because is needed also for OpenCL data 87 void PrepareAOVectors(); getAOVectorsAround() const88 const sVectorsAround *getAOVectorsAround() const { return AOVectorsAround.data(); } getAoVectorsCount() const89 int getAoVectorsCount() const { return AOVectorsCount; } 90 91 QThread workerThread; 92 93 private: 94 // ray-marching step data 95 struct sStep 96 { 97 double distance = 0.0; 98 double step = 0.0; 99 CVector3 point; 100 int iters = 0; 101 double distThresh = 0.0; 102 }; 103 104 struct sRayBuffer 105 { 106 std::vector<sStep> stepBuff; 107 int buffCount = 0; 108 }; 109 110 struct sRayMarchingIn 111 { 112 inline sRayMarchingIn &operator=(const sRayMarchingIn &assign) = default; 113 CVector3 start; 114 CVector3 direction; 115 double minScan = 0.0; 116 double maxScan = 0.0; 117 bool binaryEnable = false; 118 bool invertMode = false; 119 }; 120 121 struct sRayMarchingInOut 122 { 123 inline sRayMarchingInOut &operator=(const sRayMarchingInOut &assign) = default; 124 sStep *stepBuff; 125 int *buffCount; 126 }; 127 128 struct sRayMarchingOut 129 { 130 CVector3 point; 131 double lastDist = 0.0; 132 double depth = 0.0; 133 double distThresh = 0.0; 134 int objectId = 0; 135 bool found = false; 136 ; 137 }; 138 139 enum enumRayBranch 140 { 141 rayBranchReflection, 142 rayBranchRefraction, 143 rayBranchDone, 144 }; 145 146 struct sRayRecursionIn 147 { 148 sRayMarchingIn rayMarchingIn; 149 bool calcInside; 150 sRGBAfloat resultShader; 151 sRGBAfloat objectColour; 152 enumRayBranch rayBranch; 153 }; 154 155 struct sRayRecursionOut 156 { 157 sRayMarchingOut rayMarchingOut; 158 CVector3 point; 159 sRGBAfloat resultShader; 160 sRGBAfloat objectColour; 161 sRGBAfloat specular; 162 CVector3 normal; 163 float fogOpacity; 164 bool found; 165 }; 166 167 struct sRayRecursionInOut 168 { 169 sRayMarchingInOut rayMarchingInOut; 170 }; 171 172 struct sShaderInputData 173 { 174 CVector3 point; 175 CVector3 viewVector; 176 CVector3 normal; 177 double distThresh; // distance threshold depend on 'detailLevel' 178 double lastDist; 179 double delta; // initial step distance for shaders based on distance form camera 180 double depth; 181 sStep *stepBuff; 182 int stepCount; 183 int objectId; 184 bool invertMode; 185 cMaterial *material; 186 sRGBFloat texDiffuse; 187 sRGBFloat texColor; 188 sRGBFloat texLuminosity; 189 sRGBFloat texReflectance; 190 sRGBFloat texTransparency; 191 }; 192 193 struct sRayStack 194 { 195 sRayRecursionIn in; 196 sRayRecursionOut out; 197 sRGBAfloat reflectShader; 198 sRGBAfloat transparentShader; 199 enumRayBranch rayBranch; 200 bool goDeeper; 201 }; 202 203 struct sGradientsCollection 204 { 205 sRGBFloat surface; 206 sRGBFloat specular; 207 sRGBFloat diffuse; 208 sRGBFloat luminosity; 209 sRGBFloat roughness; 210 sRGBFloat reflectance; 211 sRGBFloat trasparency; 212 }; 213 214 // functions 215 void PrepareMainVectors(); 216 void PrepareReflectionBuffer(); 217 void RayMarching(sRayMarchingIn &in, sRayMarchingInOut *inOut, sRayMarchingOut *out) const; 218 double CalcDistThresh(CVector3 point) const; 219 double CalcDelta(CVector3 point) const; 220 static double IterOpacity( 221 double step, double iters, double maxN, double trim, double trimHigh, double opacitySp); 222 double CloudOpacity( 223 CVector3 point, double distance, double detailSize, double *distanceOut) const; 224 sRayRecursionOut RayRecursion(sRayRecursionIn in, sRayRecursionInOut &inOut); 225 void MonteCarloDOF(CVector3 *startRay, CVector3 *viewVector) const; 226 double MonteCarloDOFNoiseEstimation( 227 sRGBFloat pixel, int repeat, sRGBFloat pixelSum, sRGBFloat &StdDevSum); 228 229 // shaders 230 sRGBAfloat ObjectShader(const sShaderInputData &input, sRGBAfloat *surfaceColour, 231 sRGBAfloat *specularOut, sRGBFloat *iridescence, sGradientsCollection *gradients) const; 232 CVector3 CalculateNormals(const sShaderInputData &input) const; 233 sRGBAfloat SpecularHighlight(const sShaderInputData &input, CVector3 lightVector, 234 float specularWidth, float roughness, sRGBFloat diffuseGradient) const; 235 sRGBAfloat SpecularHighlightCombined(const sShaderInputData &input, CVector3 lightVector, 236 sRGBAfloat surfaceColor, sRGBFloat diffuseGradient) const; 237 sRGBAfloat SurfaceColour(const sShaderInputData &input, sGradientsCollection *gradients) const; 238 sRGBAfloat FastAmbientOcclusion(const sShaderInputData &input) const; 239 sRGBAfloat AmbientOcclusion(const sShaderInputData &input) const; 240 sRGBAfloat EnvMapping(const sShaderInputData &input) const; 241 sRGBAfloat AuxLightsShader(const sShaderInputData &input, sRGBAfloat surfaceColor, 242 sGradientsCollection *gradients, sRGBAfloat *specularOut) const; 243 sRGBAfloat AuxShadow(const sShaderInputData &input, const cLight *light, double distance, 244 CVector3 lightVector) const; 245 sRGBAfloat LightShading(const sShaderInputData &input, sRGBAfloat surfaceColor, 246 const cLight *light, sGradientsCollection *gradients, sRGBAfloat *outSpecular) const; 247 sRGBAfloat BackgroundShader(const sShaderInputData &input) const; 248 sRGBAfloat FakeLights( 249 const sShaderInputData &input, sRGBAfloat surfaceColor, sRGBAfloat *fakeSpec) const; 250 sRGBAfloat VolumetricShader( 251 const sShaderInputData &input, sRGBAfloat oldPixel, sRGBAfloat *opacityOut) const; 252 253 sRGBFloat TextureShader( 254 const sShaderInputData &input, texture::enumTextureSelection texSelect, cMaterial *mat) const; 255 CVector3 NormalMapShader(const sShaderInputData &input) const; 256 float RoughnessTexture(const sShaderInputData &input) const; 257 sRGBFloat IridescenceShader(const sShaderInputData &input) const; 258 sRGBFloat GlobalIlumination(const sShaderInputData &input, sRGBAfloat objectColor) const; 259 260 // data got from main thread 261 const sParamRender *params; 262 const cNineFractals *fractal; 263 sRenderData *data; 264 std::shared_ptr<sThreadData> threadData; 265 std::shared_ptr<cImage> image; 266 267 // internal variables 268 int maxRaymarchingSteps; 269 CRotationMatrix mRot; 270 CRotationMatrix mRotInv; 271 CVector3 baseX; 272 CVector3 baseY; 273 CVector3 baseZ; 274 CVector3 viewAngle; 275 // CVector3 shadowVector; 276 float actualHue; 277 int AOVectorsCount; 278 int reflectionsMax; 279 bool stopRequest; 280 281 // allocated objects 282 std::unique_ptr<cCameraTarget> cameraTarget; 283 std::vector<sRayBuffer> rayBuffer; 284 std::vector<sRayStack> rayStack; 285 std::vector<sVectorsAround> AOVectorsAround; 286 std::unique_ptr<cPerlinNoiseOctaves> perlinNoise; 287 288 public slots: 289 void doWork(); 290 291 signals: 292 void finished(); 293 void error(const QString &result); 294 }; 295 296 #endif /* MANDELBULBER2_SRC_RENDER_WORKER_HPP_ */ 297