void Vizzer::renderCamera(ApplicationData &app, const Cameraf &c, const vec3f &color) { const float axisLength = 0.15f; const float radius = 0.003f; const vec3f eye = c.getEye(); const vec3f look = c.getLook() * axisLength; const vec3f right = c.getRight() * axisLength; const vec3f up = c.getUp() * axisLength; assets.renderSphere(camera.getCameraPerspective(), eye, radius * 1.5f, math::lerp(color, vec3f(1.0f, 1.0f, 1.0f), 0.25f)); assets.renderCylinder(camera.getCameraPerspective(), eye, eye + look, radius, math::lerp(color, vec3f(0.0f, 0.0f, 1.0f), 0.25f)); assets.renderCylinder(camera.getCameraPerspective(), eye, eye + right, radius, math::lerp(color, vec3f(0.0f, 1.0f, 0.0f), 0.25f)); assets.renderCylinder(camera.getCameraPerspective(), eye, eye + up, radius, math::lerp(color, vec3f(1.0f, 0.0f, 0.0f), 0.25f)); }
void PBRTPreamble(const Cameraf &camera, UINT resolution, bool externalCamera, const string &externalLookAt) { ofstream file(PBRTFilename()); // //http://www-users.cselabs.umn.edu/classes/Spring-2012/csci5108/fileformat.pdf // file << "Film \"image\"" << endl; file << " \"integer xresolution\" [" << resolution << "] \"integer yresolution\" [" << resolution << "]" << endl; file << " \"string filename\" [\"./scene.exr\"]" << endl; file << "Scale -1 1 1" << endl; if (externalCamera) file << "Include \"./camera.pbrt\"" << endl; else if (externalLookAt.size() > 0) file << externalLookAt << endl; else file << "LookAt " << camera.getEye() << ' ' << (camera.getEye() + camera.getLook()) << ' ' << camera.getUp() << endl; file << "Camera \"perspective\" \"float fov\" [60]" << endl; file << "SurfaceIntegrator \"whitted\"" << endl; file << " Sampler \"lowdiscrepancy\" \"integer pixelsamples\" [" << synthParams().PBRTSamples << "]" << endl; file << "WorldBegin" << endl; // // nsamples for an infinite light source does nothing. Light sampling is deterministic given the u-v sample values provided by the Sampler. // //file << "LightSource \"infinite\" \"string mapname\" [\"lightMaps/pisa_latlong.exr\"]" << endl; //file << " \"integer nsamples\" [1]" << endl; file << "AttributeBegin" << endl; file << "Rotate 110 0 0 1" << endl; file << "LightSource \"infinite\" \"string mapname\" [\"lightMaps/skylight-surreal.exr\"]" << endl; file << " \"integer nsamples\" [1]" << endl; file << "AttributeEnd" << endl; file << "AttributeBegin" << endl; file << "Rotate 110 0 0 1" << endl; file << "LightSource \"infinite\" \"string mapname\" [\"lightMaps/skylight-surreal.exr\"]" << endl; file << " \"integer nsamples\" [1]" << endl; file << "AttributeEnd" << endl; file << "AttributeBegin" << endl; file << "Rotate 180 1 0 0" << endl; file << "LightSource \"infinite\" \"string mapname\" [\"lightMaps/skylight-blue.exr\"]" << endl; file << " \"integer nsamples\" [1]" << endl; file << "AttributeEnd" << endl; file << "AttributeBegin" << endl; file << "Rotate 190 0 0 1" << endl; file << "LightSource \"infinite\" \"string mapname\" [\"lightMaps/skylight-pollution.exr\"]" << endl; file << " \"integer nsamples\" [1]" << endl; file << "AttributeEnd" << endl; }
SynthRenderResult SynthRenderer::render(AppState &state, const Scene &s, const Cameraf &c, bool qualityEstimateOnly) { D3D11RenderTarget &renderTarget = qualityEstimateOnly ? renderTargetSmall : renderTargetBig; Bitmap occludedObjectColor, unoccludedObjectColor; // // unoccluded rendering // renderTarget.bind(); renderTarget.clear(vec4f(1.0f, 0.0f, 1.0f, 1.0f)); s.objects[s.mainObjectIndex].render(state, c); renderTarget.captureColorBuffer(unoccludedObjectColor); // // occluded rendering // renderTarget.bind(); renderTarget.clear(vec4f(1.0f, 0.0f, 1.0f, 1.0f)); for (UINT objectIndex = 0; objectIndex < s.objects.size(); objectIndex++) { if (objectIndex != s.mainObjectIndex) s.objects[objectIndex].render(state, c); } renderTarget.clearColor(vec4f(1.0f, 0.0f, 1.0f, 1.0f)); s.objects[s.mainObjectIndex].render(state, c); renderTarget.captureColorBuffer(occludedObjectColor); state.graphics->bindRenderTarget(); SynthRenderResult result; if (!qualityEstimateOnly) { result.occludedObjectColor = occludedObjectColor; } ml::vec4uc magenta(255, 0, 255, 255); auto countPixels = [&](const Bitmap &image) { size_t count = 0; for (const auto &p : image) if (p.value != magenta) count++; return count; }; auto borderClear = [&](const Bitmap &image) { for (int y = 0; y < (int)image.getHeight(); y++) if (image(y, 0) != magenta || image(y, (int)image.getWidth() - 1) != magenta) return false; for (int x = 0; x < (int)image.getWidth(); x++) if (image(0, x) != magenta || image((int)image.getHeight() - 1, x) != magenta) return false; return true; }; double occlusionPercentage = 0.0; double totalScreenCoverage = 0.0; const size_t occludedObjectPixels = countPixels(occludedObjectColor); const size_t totalObjectPixels = countPixels(unoccludedObjectColor); double borderQuality = 0.0; if (borderClear(unoccludedObjectColor)) { borderQuality = 1.0; } result.quality = 0.0; if (totalObjectPixels > 0) { occlusionPercentage = 1.0 - (double)occludedObjectPixels / (double)totalObjectPixels; totalScreenCoverage = (double)occludedObjectPixels / double(occludedObjectColor.getNumPixels()); const int minTotalPixelCount = 1000; const float maxOcclusionPercentage = 0.4; const float minScreenCoverage = 0.15; const float maxScreenCoverage = 0.7; if (occludedObjectPixels >= minTotalPixelCount && occlusionPercentage <= maxOcclusionPercentage && totalScreenCoverage >= minScreenCoverage && totalScreenCoverage <= maxScreenCoverage && borderQuality > 0.0) { // TODO: this is not a good metric because it favors unoccluded too much... //result.quality = ml::math::max(totalScreenCoverage, 0.1); result.quality = 1.0; } } const ModelInstance &object = s.objects[s.mainObjectIndex]; //const vec3f objectCenter = object.modelToWorld * object.object.model->bbox.getCenter(); //const vec3f objectFrameX = (object.modelToWorld * (object.object.model->bbox.getCenter() + vec3f::eX) - objectCenter).getNormalized(); //const vec3f objectFrameY = (object.modelToWorld * (object.object.model->bbox.getCenter() + vec3f::eY) - objectCenter).getNormalized(); //const vec3f objectFrameZ = (object.modelToWorld * (object.object.model->bbox.getCenter() + vec3f::eZ) - objectCenter).getNormalized(); result.camera = c; result.annotations.push_back("modelName=" + object.model->modelName); result.annotations.push_back("modelCategory=" + object.model->categoryName); result.annotations.push_back("cameraEye=" + c.getEye().toString()); result.annotations.push_back("cameraRight=" + c.getRight().toString()); result.annotations.push_back("cameraLook=" + c.getLook().toString()); result.annotations.push_back("occludedObjectPixels=" + std::to_string(occludedObjectPixels)); result.annotations.push_back("totalObjectPixels=" + std::to_string(totalObjectPixels)); result.annotations.push_back("occlusionPercentage=" + std::to_string(occlusionPercentage)); result.annotations.push_back("totalScreenCoverage=" + std::to_string(totalScreenCoverage)); result.annotations.push_back("borderQuality=" + std::to_string(borderQuality)); result.annotations.push_back("quality=" + std::to_string(result.quality)); return result; }