Math::Vec3f PhotonMapper::rayMarch(Ray &r, double tmin, double tmax, PhotonMap &photonMap, PhotonMap &specularPhotonMap, const Scene &scene, const Shape *nearestShape, // const Math::Box<Math::Vec3d>& box, bool gather) const { // March light sources double dx = scene.rayMarchScatter*scene.rand_gen->nextd(); if (tmin+dx > tmax) { return nearestShape->surfaceShader->shade(this, r.hit, photonMap, specularPhotonMap, scene, gather); } Math::Vec3f col(0,0,0); Math::Vec3f p = r.o + r.d*tmin; HitInfo hit; hit.O = p; Ray lray; lray.o = p; lray.tMin = 1e-3; for (PhotonSource *source: scene.photonSources) { lray.d = source->position-p; if (scene.intersect(lray)) { continue; } col += source->computeIntensity(hit, scene)*dx*scene.sigma_s/(4.0*M_PI); } return col+exp(-scene.sigma_t*dx)*rayMarch(r, tmin+dx, tmax, photonMap, specularPhotonMap, scene, nearestShape, gather); }
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 ); } }
int main(int argc, char* argv[]){ if(argc != 5){ printf("%s",HELP_MESSAGE); return -1; } const int width = atoi(argv[2]); const int height = atoi(argv[3]); const int maxIterations = atoi(argv[4]); if(width <= 0 || height <= 0){ printf("%s",BAD_WIDTH_HEIGHT_OR_MAX_ITERATIONS); return -1; } FILE* file = fopen("test.ppm","wb"); if(file == NULL){ printf(FAILED_TO_CREATE_FILE); return -1; } createFileHeader(file,width,height); Vector3 direction; direction = (Vector3){.x=0.5,.y=0.5,.z=1}; Vector3 from; from = (Vector3){.x=-100,.y=-100,.z=-100}; int x = 0; int y = 0; int sampleRate = height/10; int loadCount = 0; for(y = 0; y<height; y++){ fprintf(file," "); for(x = 0; x<width; x++){ Vector3 offset; offset = (Vector3){.x = x, .y = y, .z = 0}; int value = (int)rayMarch(vec3Add(from,offset),direction,maxIterations); fprintf(file,"%d %d %d ",value,value,value); } fprintf(file,"\n"); if(y % sampleRate == 0){ printf("\r%i\%% done",loadCount*10); loadCount++; } } fclose(file); return 0; }
Math::Vec3f PhotonMapper::recursiveRender(Ray &r, PhotonMap &photonMap, PhotonMap &specularPhotonMap, const Scene &scene, bool gather) const { Shape *s_hit = scene.intersect(r); if (s_hit != NULL) { s_hit->fillHitInfo(r); for (const Math::Box<Math::Vec3d>& box:scene.fog) { double tMin, tMax; if (Math::intersects<Math::Vec3d>(r.o, r.d, box, r.tMin, std::min(r.tMax, r.hit.t-1e-3), &tMin, &tMax)) { if (r.hit.t <= tMin) { continue; } return rayMarch(r, tMin, tMax, photonMap, specularPhotonMap, scene, s_hit, gather); } } Math::Vec3f col = s_hit->surfaceShader->shade(this, r.hit, photonMap, specularPhotonMap, scene, gather); if (s_hit->areaLight()) { // TODO col = Math::Vec3f(1.0,1.0, 1.0); } return col; } return Math::Vec3f(0,0,0); }