double cRenderWorker::AuxShadow(const sShaderInputData &input, double distance, CVector3 lightVector) { double step = input.delta; double dist = step; double light = 1.0; double opacity = 0.0; double shadowTemp = 1.0; double DE_factor = params->DEFactor; if (params->iterFogEnabled || params->volumetricLightAnyEnabled) DE_factor = 1.0; for (double i = input.delta; i < distance; i += dist * DE_factor) { CVector3 point2 = input.point + lightVector * i; sDistanceOut distanceOut; sDistanceIn distanceIn(point2, input.distThresh, false); dist = CalculateDistance(*params, *fractal, distanceIn, &distanceOut); data->statistics.totalNumberOfIterations += distanceOut.totalIters; if (params->iterFogEnabled) { opacity = IterOpacity(dist * DE_factor, distanceOut.iters, params->N, params->iterFogOpacityTrim, params->iterFogOpacity); } else { opacity = 0.0; } shadowTemp -= opacity * (distance - i) / distance; float dist_thresh; if (params->iterFogEnabled || params->volumetricLightAnyEnabled) { dist_thresh = CalcDistThresh(point2); } else dist_thresh = input.distThresh; if (dist < dist_thresh || shadowTemp < 0.0) { if (params->penetratingLights) { shadowTemp -= (distance - i) / distance; if (shadowTemp < 0.0) shadowTemp = 0.0; } else { shadowTemp = 0.0; } break; } } light = shadowTemp; return light; }
sRGBAfloat cRenderWorker::AmbientOcclusion(const sShaderInputData &input) { sRGBAfloat AO(0, 0, 0, 1.0); double start_dist = input.delta; double end_dist = input.delta / params->resolution; double intense = 0; for (int i = 0; i < AOvectorsCount; i++) { sVectorsAround v = AOvectorsAround[i]; double dist = input.lastDist; double opacity = 0.0; double shadowTemp = 1.0; for (double r = start_dist; r < end_dist; r += dist * 2.0) { CVector3 point2 = input.point + v.v * r; sDistanceOut distanceOut; sDistanceIn distanceIn(point2, input.distThresh, false); dist = CalculateDistance(*params, *fractal, distanceIn, &distanceOut, data); data->statistics.totalNumberOfIterations += distanceOut.totalIters; if (params->iterFogEnabled) { opacity = IterOpacity(dist * 2.0, distanceOut.iters, params->N, params->iterFogOpacityTrim, params->iterFogOpacity); } else { opacity = 0.0; } shadowTemp -= opacity * (end_dist - r) / end_dist; float dist_thresh; if (params->iterFogEnabled || params->volumetricLightEnabled[0]) { dist_thresh = CalcDistThresh(point2); } else dist_thresh = input.distThresh; if (dist < dist_thresh || distanceOut.maxiter || shadowTemp < 0.0) { shadowTemp -= (end_dist - r) / end_dist; if (shadowTemp < 0.0) shadowTemp = 0.0; break; } } intense = shadowTemp; AO.R += intense * v.R; AO.G += intense * v.G; AO.B += intense * v.B; } AO.R /= (AOvectorsCount * 256.0); AO.G /= (AOvectorsCount * 256.0); AO.B /= (AOvectorsCount * 256.0); return AO; }
sRGBAfloat cRenderWorker::MainShadow(const sShaderInputData &input) { sRGBAfloat shadow(1.0, 1.0, 1.0, 1.0); // starting point CVector3 point2; double factor = input.delta / params->resolution; if (!params->penetratingLights) factor = params->viewDistanceMax; double dist = input.distThresh; double DEFactor = params->DEFactor; if (params->iterFogEnabled || params->volumetricLightEnabled[0]) DEFactor = 1.0; // double start = input.delta; double start = input.distThresh; if (params->interiorMode) start = input.distThresh * DEFactor; double opacity = 0.0; double shadowTemp = 1.0; double softRange = tan(params->shadowConeAngle / 180.0 * M_PI); double maxSoft = 0.0; const bool bSoft = (!params->iterFogEnabled && !params->limitsEnabled && !params->iterThreshMode) && softRange > 0.0; for (double i = start; i < factor; i += dist * DEFactor) { point2 = input.point + input.lightVect * i; float dist_thresh; if (params->iterFogEnabled || params->volumetricLightEnabled[0]) { dist_thresh = CalcDistThresh(point2); } else dist_thresh = input.distThresh; sDistanceOut distanceOut; sDistanceIn distanceIn(point2, dist_thresh, false); dist = CalculateDistance(*params, *fractal, distanceIn, &distanceOut, data); data->statistics.totalNumberOfIterations += distanceOut.totalIters; if (bSoft) { double angle = (dist - dist_thresh) / i; if (angle < 0) angle = 0; if (dist < dist_thresh) angle = 0; double softShadow = (1.0 - angle / softRange); if (params->penetratingLights) softShadow *= (factor - i) / factor; if (softShadow < 0) softShadow = 0; if (softShadow > maxSoft) maxSoft = softShadow; } if (params->iterFogEnabled) { opacity = IterOpacity(dist * DEFactor, distanceOut.iters, params->N, params->iterFogOpacityTrim, params->iterFogOpacity); } else { opacity = 0.0; } shadowTemp -= opacity * (factor - i) / factor; if (dist < dist_thresh || shadowTemp < 0.0) { shadowTemp -= (factor - i) / factor; if (!params->penetratingLights) shadowTemp = 0.0; if (shadowTemp < 0.0) shadowTemp = 0.0; break; } } if (!bSoft) { shadow.R = shadowTemp; shadow.G = shadowTemp; shadow.B = shadowTemp; } else { shadow.R = (1.0 - maxSoft); shadow.G = (1.0 - maxSoft); shadow.B = (1.0 - maxSoft); } return shadow; }
//Ray-Marching CVector3 cRenderWorker::RayMarching(sRayMarchingIn &in, sRayMarchingInOut *inOut, sRayMarchingOut *out) { CVector3 point; bool found = false; double scan = in.minScan; double dist = 0; double search_accuracy = 0.01 * params->detailLevel; double search_limit = 1.0 - search_accuracy; int counter = 0; double step = 0.0; (*inOut->buffCount) = 0; double distThresh; out->objectId = 0; //qDebug() << "Start ************************"; CVector3 lastPoint, lastGoodPoint; bool deadComputationFound = false; for (int i = 0; i < 10000; i++) { lastGoodPoint = lastPoint; lastPoint = point; counter++; point = in.start + in.direction * scan; if (point == lastPoint || point == point/0.0) //detection of dead calculation { //qWarning() << "Dead computation\n" // << "Point:" << point.Debug() // << "\nPrevious point:" << lastPoint.Debug(); point = lastPoint; found = true; deadComputationFound = true; break; } distThresh = CalcDistThresh(point); sDistanceIn distanceIn(point, distThresh, false); sDistanceOut distanceOut; dist = CalculateDistance(*params, *fractal, distanceIn, &distanceOut, data); //qDebug() <<"thresh" << distThresh << "dist" << dist << "scan" << scan; if (in.invertMode) { dist = distThresh * 1.99 - dist; if (dist < 0.0) dist = 0.0; } out->objectId = distanceOut.objectId; //-------------------- 4.18us for Calculate distance -------------- //printf("Distance = %g\n", dist/distThresh); inOut->stepBuff[i].distance = dist; inOut->stepBuff[i].iters = distanceOut.iters; inOut->stepBuff[i].distThresh = distThresh; data->statistics.histogramIterations.Add(distanceOut.iters); data->statistics.totalNumberOfIterations += distanceOut.totalIters; if (dist > 3.0) dist = 3.0; if (dist < distThresh) { if (dist < 0.1 * distThresh) data->statistics.missedDE++; found = true; break; } inOut->stepBuff[i].step = step; if (params->interiorMode) { step = (dist - 0.8 * distThresh) * params->DEFactor * (1.0 - Random(1000) / 10000.0); ; } else { step = (dist - 0.5 * distThresh) * params->DEFactor * (1.0 - Random(1000) / 10000.0); ; } inOut->stepBuff[i].point = point; //qDebug() << "i" << i << "dist" << inOut->stepBuff[i].distance << "iters" << inOut->stepBuff[i].iters << "distThresh" << inOut->stepBuff[i].distThresh << "step" << inOut->stepBuff[i].step << "point" << inOut->stepBuff[i].point.Debug(); (*inOut->buffCount) = i + 1; scan += step / in.direction.Length(); //divided by length of view Vector to eliminate overstepping when fov is big if (scan > in.maxScan) { break; } } //------------- 83.2473 us for RayMarching loop ------------------------- //qDebug() << "------------ binary search"; if (found && in.binaryEnable && !deadComputationFound) { step *= 0.5; for (int i = 0; i < 30; i++) { counter++; if (dist < distThresh && dist > distThresh * search_limit) { break; } else { if (dist > distThresh) { scan += step; point = in.start + in.direction * scan; } else if (dist < distThresh * search_limit) { scan -= step; point = in.start + in.direction * scan; } } distThresh = CalcDistThresh(point); sDistanceIn distanceIn(point, distThresh, false); sDistanceOut distanceOut; dist = CalculateDistance(*params, *fractal, distanceIn, &distanceOut, data); //qDebug() << "i" << i <<"thresh" << distThresh << "dist" << dist << "scan" << scan << "step" << step; if (in.invertMode) { dist = distThresh * 1.99 - dist; if (dist < 0.0) dist = 0.0; } out->objectId = distanceOut.objectId; data->statistics.histogramIterations.Add(distanceOut.iters); data->statistics.totalNumberOfIterations += distanceOut.totalIters; step *= 0.5; } } if (params->iterThreshMode) { //this fixes problem with noise when there is used "stop at maxIter" mode scan -= distThresh; point = in.start + in.direction * scan; } //---------- 7.19605us for binary searching --------------- data->statistics.histogramStepCount.Add(counter); out->found = found; out->lastDist = dist; out->depth = scan; out->distThresh = distThresh; data->statistics.numberOfRaymarchings++; return point; }