vec3 getNormal( vec3 hitpos, float val0 ){ return vec3( evalFunc( hitpos + vec3( dderiv, 0.0, 0.0 ) ) - val0, evalFunc( hitpos + vec3( 0.0, dderiv, 0.0 ) ) - val0, evalFunc( hitpos + vec3( 0.0, 0.0, dderiv ) ) - val0 ) / dderiv; }
void main( void ){ vec2 q = (gl_FragCoord.xy/resolution.xy) - vec2(0.5,0.5); vec3 ray0 = vec3( 0.0, 0.0, -50.0 ); vec3 hRay = vec3( q.x, q.y, 10.0 ); hRay = normalize( hRay ); float t = rayMarch( ray0, hRay ); vec3 hitpos = ray0 + t*hRay; float val0 = evalFunc ( hitpos ); vec3 normal = getNormal( hitpos, val0 ); normal = normalize( normal ); if( val0<0.0 ) normal*=-1.0; float c_diff = dot ( light_dir, normal ); //float c_spec = dot ( light_dir-hRay, normal ); c_spec*=c_spec; c_spec*=c_spec; c_spec*=c_spec; //float c = c_diff + c_spec; float c = 0.1 + max( 0.0, c_diff ); if( t < (tmax-dtmax) ){ if( val0 > 0.0 ){ gl_FragColor = vec4( 0.0, 0.5*c, c, 1.0 ); }else{ gl_FragColor = vec4( c, 0.5*c, 0.0, 1.0 ); }; }else{ gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 ); } }
// simple test function which draws the direction of the vector field void glwindow::drawVectorField(const vector &base, const vector dir[3], int gs, vector & (*evalFunc)(const vector &p, vector &v), float scale, int unit) { int i[3]; vector p, v; float igs = 1.0f / gs; glBegin(GL_LINES); for (i[0] = 0; i[0] <= gs; i[0]++) for (i[1] = 0; i[1] <= gs; i[1]++) for (i[2] = 0; i[2] <= gs; i[2]++) { // compute position in field p = _vector(base + dir[0] * (float)i[0] * igs + dir[1] * (float)i[1] * igs + dir[2] * (float)i[2] * igs); // evaluate evalFunc(p, v); // draw line glVertex3fv(p.getC(vector_e1_e2_e3)); if ( unit ) { glVertex3fv(_vector(p + scale * unit_e(v)).getC(vector_e1_e2_e3)); } else { glVertex3fv(_vector(p + scale * v).getC(vector_e1_e2_e3)); } } glEnd(); }
float bisec( vec3 ray0, vec3 hRay, float t, float dt ){ while( dt > dtmin ){ dt *=0.5; float thalf = t+dt; float val = evalFunc( ray0 + thalf*hRay ); if( abs(val) < iso ) t = thalf; } return t; }
void testTransFunction() { std::map<float, std::array<float, 2>> test; std::vector<std::array<float, 3>> funcs; funcs.push_back({{0.2, 0.2, 0.5}}); funcs.push_back({{0.5, 0.8, 0.5}}); funcs.push_back({{1.0, 1.0, 0.5}}); funcs.push_back({{0.6, 0.6, 0.5}}); for (auto & f : funcs) { std::array<float, 2> & t = test[f[0]]; t[0] = 1.f; if (f[1] > f[0]) { if (std::fabs(t[1]) < 0.0000001) { t[1] = 1.f; } std::array<float, 2> & t2 = test[f[1]]; t2[0] = 1.f; if (std::fabs(t2[1]) < 0.0000001) { t2[1] = 1.f; } } else { t[1] = -1.f; } } for (auto a : test) { std::cout << a.first << " " << a.second[0] << " " << a.second[1] << std::endl; } for (auto & f : funcs) { auto iter = test.find(f[0]); if (iter != test.end()) { std::array<float, 2> & ys = iter->second; if (std::fabs(f[1] - f[0]) < 0.0000001) { if (ys[1] >= 0.f) { ys[1] = ys[1] * f[2]; } else { ys[1] = ys[0] * f[2]; } } iter++; while (iter != test.end()) { float x = iter->first; float a = evalFunc(f, x); std::array<float, 2> & ys = iter->second; ys[0] = ys[0] * a; ys[1] = ys[1] * a; iter++; } } } for (auto a : test) { std::cout << a.first << " " << a.second[0] << " " << a.second[1] << std::endl; } }
float integrate( vec3 ray0, vec3 hRay ){ float dt = dtmax; float t = tmin; float sum = 0.0; while( t<tmax ){ sum += evalFunc( ray0 + t*hRay ); t += dt; } return sum; }
float rayMarch( vec3 ray0, vec3 hRay ){ float dt = dtmax; float t = tmin; while( t<tmax ){ float val = evalFunc( ray0 + t*hRay ); if( abs(val) > iso ) break; t += dt; } //return t; return bisec( ray0, hRay, t-dt, dt ); }
//_____________________________find it iterativly_________________________________________________ double getZMomIter(double tof_ns, double mass_au, int nbr_regions, double *EField, double *length) { //when a negative time was given return immediatly because there will be no good solution// if (tof_ns < 0) return 1e15; //calculate the acceleration from the E-field in the region, charge and mass of the particle// double a = EField[0] /mass_au * mmnsns; //the acceleration in Region 1 in mm/ns^2 //--iterativly find the right v_mmns to get the right tof_ns--// //--we have a function t(v), but we want the inverse of the function v(t)--// //--since this cannot be done we have to find the right v iterativly--// //--so we have a function f(x) (t(v)) with the function value fx0 (t) at point x0 (v)--// //--we don't know which x0 (v) will give us the fx0 (t) that we want--// //--that means we have to iterate x0 until fx0 is the same that we want--// //begin with a v when there would be only one Region// double x0 = length[0]/tof_ns - 0.5*a*tof_ns; double fx0 = evalFunc(x0, mass_au, nbr_regions, EField, length); //use Newtons Approximation// while(fabs(fx0 - tof_ns) > 0.01) { //we need to find the slope of the function at point x0 therefore we need// //a second point which is close to it// double x1 = 1.1 * x0; double fx1 = evalFunc(x1,mass_au, nbr_regions, EField, length); //calculate the slope// double m = (fx0-fx1)/(x0-x1); //the next starting point is the point where the slopeline crosses the wanted fx0 value// x0 = x0 + 0.7*(tof_ns-fx0)/m; fx0 = evalFunc(x0,mass_au, nbr_regions, EField, length); } //now calc momentum from the velocity that was found double v_au = x0 * mmns_au; double p_au = v_au * mass_au; return p_au; }
void func(NUMBER* x, NUMBER* y) { #ifdef REVERSE_TAPE codi::PreaccumulationHelper<NUMBER> ph; #else codi::ForwardPreaccumulationHelper<NUMBER> ph; #endif ph.start(x[0], x[1]); evalFunc(x, y); ph.finish(false, y[0], y[1]); }
std::vector<DeepDataType> DeepImage::renderPixelLinear(int y, int x) const { /* * Assumption: Image has at least the following channels: * DEPTH * DEPTH_BACK * ALPHA */ // TODO: Verify image has the correct channels (Z, ZBack, A) // Discontinuous transmittance function, 1=transparent, 0=opaque // key is the z-value // the array is three values: // 1. is the "top" or high transmittance value // 2. is the "botton" or low transmittance value // 3. is a counter for how many volumes that share this sample. std::map<DeepDataType, std::array<DeepDataType, 3>> transFunc; // Each flat surface or volume is stored as a simple 3 value // function is this vector // The first value is z, second is zBack and third is 1.0-alpha. std::vector<std::array<DeepDataType, 3>> sampleFuncs; // Initialize the transFunc by adding samples. const std::vector<int> indices = mIndexData[y*width() + x]; for (auto index : indices) { DeepDataType z = mChannelData.at(DEPTH)[index]; DeepDataType zBack = mChannelData.at(DEPTH_BACK)[index]; DeepDataType alpha = mChannelData.at(ALPHA)[index]; // Add this function to the sampleFuncs list. sampleFuncs.push_back({{z, zBack, (1.f-std::fabs(alpha))}}); // Add or fetch the current sample from the main transmittance func. std::array<DeepDataType, 3> & t = transFunc[z]; t[0] = 1.0; // Initialize first value (top) if (zBack > z) { if (std::fabs(t[1]) < EPSILON) { // If the bottom value is uninialized, set it to 1 // to indicate this is a continous point. t[1] = 1.0; } // Initialize the end point. std::array<DeepDataType, 3> & t2 = transFunc[zBack]; t2[0] = 1.0; if (std::fabs(t2[1]) < EPSILON) { t2[1] = 1.0; // Continous point. } } else { // Initialize the bottom value to -1.0 to indicate this is a discontinous point. t[1] = -1.0; } } // Initialize the final pixel std::vector<DeepDataType> finalColorValues(mChannelNamesNoZs.size(), 0.0); // Check if the pixel has any values at all. if (transFunc.begin() == transFunc.end()) { return finalColorValues; } // Compute the transmittance function by multiplying in every sample function. for (auto & func : sampleFuncs) { // Get the starting point. auto transIter = transFunc.find(func[0]); if (transIter != transFunc.end()) { // Just for safety. // Get the sample std::array<DeepDataType, 3> & transmittanceSample = transIter->second; if (std::fabs(func[1] - func[0]) < EPSILON) { // If the sample is a discontinous point, i.e. flat surface. if (transmittanceSample[1] >= 0.f) { // This points low is initialized, so just multiply the // current function with the value. transmittanceSample[1] = transmittanceSample[1] * func[2]; } else { // This point is uninitialized (set to < 0), so use the // high value multiplied by the current functions transmittance value. transmittanceSample[1] = transmittanceSample[0] * func[2]; } } else { // This is a volume point, so increase the volume counter by one. transmittanceSample[2] += 1.0; } transIter++; while (transIter != transFunc.end()) { // For the rest of the points, multiply with the function value DeepDataType transDepth = transIter->first; // Evaluate the current function value at the current depth. DeepDataType transparency = evalFunc(func, transDepth); // Multiply both the high and low value with the current value. std::array<DeepDataType, 3> & transmittanceSample = transIter->second; transmittanceSample[0] *= transparency; transmittanceSample[1] *= transparency; if (transDepth < func[1]) { // If this sample is within the volume, increase the counter. transmittanceSample[2] += 1.0; } transIter++; } } } // // Debug the transmittance func // for (auto & trans : transFunc) { // std::cout << "z:" << trans.first << " hi:" << trans.second[0] << // " lo:" << trans.second[1] << " num:" << trans.second[2] << std::endl; // } DeepDataType minTrans = 1.0; // Do the final compositing using the transmittance function. // TODO: Comment this part. for (auto index : indices) { DeepDataType z = mChannelData.at(DEPTH)[index]; DeepDataType zBack = mChannelData.at(DEPTH_BACK)[index]; DeepDataType alpha = mChannelData.at(ALPHA)[index]; if (alpha >= 0.0) { auto transIter = transFunc.find(z); if (zBack > z) { DeepDataType lastTrans = transIter->second[1]; DeepDataType transparency = 0.0; DeepDataType volumeCounter = transIter->second[2]; auto transBackIter = transFunc.find(zBack); do { transIter++; transparency += (lastTrans - transIter->second[0])/volumeCounter; volumeCounter = transIter->second[2]; lastTrans = transIter->second[1]; } while (transIter != transBackIter); minTrans = std::min(minTrans, transparency); int c = 0; for (auto & channelName : mChannelNamesNoZs) { if (channelName.compare(ALPHA) != 0) { finalColorValues[c] += transparency*mChannelData.at(channelName)[index]; } else { finalColorValues[c] += transparency; } c++; } } else { DeepDataType transDiff = transIter->second[0] - transIter->second[1]; minTrans = std::min(minTrans, transIter->second[1]); int c = 0; for (auto & channelName : mChannelNamesNoZs) { if (channelName.compare(ALPHA) != 0) { finalColorValues[c] += transDiff*mChannelData.at(channelName)[index]; } else { finalColorValues[c] += transDiff; } c++; } } } } // Unpremult auto alphaIter = std::find(mChannelNamesNoZs.begin(), mChannelNamesNoZs.end(), ALPHA); DeepDataType lastAlpha = finalColorValues[std::distance(mChannelNamesNoZs.begin(), alphaIter)]; int c = 0; for (auto & channelName : mChannelNamesNoZs) { if (channelName.compare(ALPHA) != 0) { if (lastAlpha > 0.0) { finalColorValues[c] /= lastAlpha; } else { finalColorValues[c] = 0.0; } } c++; } return finalColorValues; }