void PhotonMapper::forwardPassRay(Ray ray, int x, int y, float weight, int depth){ Intersection is; if (weight > 0 && depth < maxForwardPassDepth && mScene->intersect(ray, is)){ Hitpoint* hp = new Hitpoint(); hp->pixelX = x; hp->pixelY = y; hp->is = is; hp->radius = startRadius; Color reflectedC, refractedC, emittedC; Material* m = is.mMaterial; float reflectivity = m->getReflectivity(is); float transparency = m->getTransparency(is); float diffuse = (1.0f - reflectivity - transparency)*weight; hp->pixelWeight = (1.0f - reflectivity - transparency) * weight; if (reflectivity > 0.0f) { Ray reflectedRay = is.getReflectedRay(); forwardPassRay(reflectedRay, x, y, reflectivity * weight, depth+1); } if (transparency > 0.0f) { Ray refractedRay = is.getRefractedRay(); forwardPassRay(refractedRay, x, y, transparency * weight, depth+1); } if (diffuse){ for (int i = 0; i < mScene->getNumberOfLights(); ++i){ PointLight* l = mScene->getLight(i); if (!mScene->intersect(is.getShadowRay(l))){ Vector3D lightVec = l->getWorldPosition() - is.mPosition; float d2 = lightVec.length2(); lightVec.normalize(); Color radiance = l->getRadiance(); Color brdf = is.mMaterial->evalBRDF(is, lightVec); float angle = max(lightVec * is.mNormal, 0.0f); hp->directIllumination += radiance * brdf * angle / d2; } } vec.push_back(hp); } } }
void PhotonMapper::photonTracingPass(){ for (int i = 0; i < mScene->getNumberOfLights(); ++i){ PointLight* l = mScene->getLight(i); for (int i = 0; i < numberPhotons; ++i){ Vector3D dir(uniform() * 2 - 1, uniform() * 2 - 1, uniform() * 2 - 1); while(dir.length2() > 1.0f){ dir = Vector3D(uniform() * 2 - 1, uniform() * 2 - 1, uniform() * 2 - 1); } dir.normalize(); Ray ray; ray.orig = l->getWorldPosition(); ray.dir = dir; Color startFlux = l->getRadiance() * 4.0f * M_PI; trace(ray, 0, startFlux); } } }
PVScene::PVScene(Scene *scene) { glGenVertexArrays(1, &vertexArray); glBindVertexArray(vertexArray); GLCHECK(); glGenBuffers(1, &vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); GLCHECK(); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); glVertexAttribPointer(0, 3, GL_FLOAT, false, 64, (void *)0); glVertexAttribPointer(1, 3, GL_FLOAT, false, 64, (void *)16); glVertexAttribPointer(2, 3, GL_FLOAT, false, 64, (void *)32); glVertexAttribPointer(3, 2, GL_FLOAT, false, 64, (void *)48); GLCHECK(); std::vector<Vertex> vertices; int vertexCount = 0; int vertexOffset = 0; int curr_material = scene->getTriangles()[0].material_id; for (Triangle & tri : scene->getTriangles()) { if (curr_material != tri.material_id) { addMesh(scene, curr_material, vertexOffset, vertexCount); vertexOffset += vertexCount; vertexCount = 0; curr_material = tri.material_id; } vertices.push_back(tri.v[0]); vertices.push_back(tri.v[1]); vertices.push_back(tri.v[2]); vertexCount += 3; } addMesh(scene, curr_material, vertexOffset, vertexCount); Camera *camera = scene->getCamera(); viewMatrix = lookAtLH(camera->getPosition(), camera->getTarget(), camera->getUp()); projectionMatrix = perspectiveLH(camera->getFOV(), camera->getAspectRatio(), 0.1f, 100.0f); GLCHECK(); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_DYNAMIC_DRAW); GLCHECK(); glBindVertexArray(0); GLCHECK(); for (int i = 0; i < scene->getNumLights(); i++) { PointLight *light = (PointLight *)scene->getLight(i); lights.push_back(new PVLight(light->getPosition(), light->getRadiance())); } shader = new PVShader(vs3d_source, fs3d_source); GLCHECK(); }