void OBJXArchive::createMapOfMaterials() { m_mapOfMaterials.clear(); if (m_mtlFile.str().length() > 0) { m_mtlFile.seekg(ios::beg); string line = ""; Material m; while (getline(m_mtlFile, line)) { if ( (line.find("newmtl ") != string::npos) && (line.length() > 8) ) { // Store old material description. if (m.getName() != "Undefined") { m_mapOfMaterials[m.getName()] = m; } // Start next material description. m = Material(line.substr(7)); } if ( (line.find("Ns ") != string::npos) && (line.length() > 4) ) { stringstream shininess(line.substr(3)); double s; shininess >> s; m.setShininess(s); } if ( (line.find("Ka ") != string::npos) && (line.length() > 4) ) { stringstream ambient(line.substr(3)); double x; double y; double z; ambient >> x; ambient >> y; ambient >> z; m.setAmbient(Point3(x, y, z)); }
QVector3D WhittedRenderer::trace(const Ray& primaryRay, int depth, const QList<Shape*>& shapes, const QList<Light*>& lights) { double minDist = std::numeric_limits<double>::max(); Shape* closestShape = nullptr; QVector3D shaded; if (m_grid->intersect(primaryRay, closestShape, minDist)) { auto material = closestShape->material(); shaded = material->ambientReflectivity() * m_ambientLightColor * material->colorVector(); QColor color = material ? material->color() : QColor(40, 40, 40); QVector3D diffuseColor(color.redF(), color.greenF(), color.blueF()); QVector4D hitPoint = primaryRay.along(minDist); QVector4D normalVector = closestShape->surfaceNormal(hitPoint, primaryRay); QVector4D viewVector = -primaryRay.direction(); foreach(Light* light, lights) { QVector3D emittance; QVector4D lightVector; light->sample(lightVector, emittance); lightVector = lightVector - hitPoint; float lightVectorLengthSquared = lightVector.lengthSquared(); float lightVectorLength = sqrt(lightVectorLengthSquared); lightVector.normalize(); Ray shadowRay(hitPoint, lightVector); double t; Shape* blockingShape; bool shadowRayHit = m_grid->intersect(shadowRay, blockingShape, t); if (!shadowRayHit || (shadowRayHit && (lightVectorLengthSquared < t * t))) { // Diffuse float dot = fmax(0.0f, QVector4D::dotProduct(lightVector, normalVector)) * material->diffuseReflectivity(); emittance *= 1 / (1 + 0.2 * lightVectorLength + 0.08 * lightVectorLengthSquared); shaded += dot * QVector3D(emittance.x() * diffuseColor.x(), emittance.y() * diffuseColor.y(), emittance.z() * diffuseColor.z()); // Specular if (material->specularReflectivity() > 0.0) { QVector4D reflectedLightVector = MathUtils::reflect(-lightVector, normalVector); // lightVector and normalVector are already normalized float dot = QVector4D::dotProduct(reflectedLightVector, viewVector); if (dot > 0.0) shaded += material->specularReflectivity() * pow(dot, material->shininess()) * emittance; } } }
// Apply the phong model to this point on the surface of the object, returning // the color of that point. Vec3d Material::shade( Scene *scene, const ray& r, const isect& i ) const { // YOUR CODE HERE // For now, this method just returns the diffuse color of the object. // This gives a single matte color for every distinct surface in the // scene, and that's it. Simple, but enough to get you started. // (It's also inconsistent with the phong model...) // Your mission is to fill in this method with the rest of the phong // shading model, including the contributions of all the light sources. // You will need to call both distanceAttenuation() and shadowAttenuation() // somewhere in your code in order to compute shadows and light falloff. if( debugMode ) std::cout << "Debugging Phong code..." << std::endl; //Intersection Point Vec3d P = r.at(i.t); Vec3d L = Vec3d(0,0,0); Vec3d V = -r.getDirection(); //======[ Emission ]====== L += ke(i); if(debugMode) std::cout << "ke(i): " << ke(i) <<"\n"; //======[ Ambient ]====== //missing Ka L += prod(ka(i),scene->ambient()); if(debugMode){ std::cout << "ambient: " << scene->ambient() <<"\n"; std::cout << "ka(i): " << ka(i) <<"\n"; } //iterate through lights for ( std::vector<Light*>::const_iterator litr = scene->beginLights(); litr != scene->endLights(); ++litr ) { Vec3d Lc; //light contribution Light* pLight = *litr; Vec3d sa = pLight->shadowAttenuation(P); double da = pLight->distanceAttenuation(P); //======[ Diffuse ]====== Vec3d direction = pLight->getDirection(P); Vec3d normal = i.N; if(debugMode) { std::cout << "D: "; clamp((normal*direction)*kd(i)).print(); } Lc = clamp((normal*direction)*kd(i)); //======[ Specular ]====== Vec3d H = (V+direction)/2.0; if(debugMode) { std::cout << "S: "; clamp(ks(i)*pow((normal*H),shininess(i))).print(); std::cout <<"sa: "; sa.print(); } Lc += clamp(ks(i)*pow((normal*H),shininess(i))); Lc = da * prod(Lc,sa); L+=Lc; } if(debugMode){ std::cout <<"L: "; L.print(); } return L; }
bool CalSaver::saveXmlCoreMaterial(const std::string& strFilename, CalCoreMaterial *pCoreMaterial) { std::stringstream str; vsxTiXmlDocument doc(strFilename); vsxTiXmlElement material("MATERIAL"); //material.SetAttribute("MAGIC",Cal::MATERIAL_XMLFILE_MAGIC); material.SetAttribute("VERSION",Cal::LIBRARY_VERSION); material.SetAttribute("NUMMAPS",pCoreMaterial->getVectorMap().size()); vsxTiXmlElement ambient("AMBIENT"); CalCoreMaterial::Color ambientColor; ambientColor = pCoreMaterial->getAmbientColor(); str.str(""); str << (int)ambientColor.red << " " << (int)ambientColor.green << " " << (int)ambientColor.blue << " " << (int)ambientColor.alpha; vsxTiXmlText ambientdata(str.str()); ambient.InsertEndChild(ambientdata); material.InsertEndChild(ambient); vsxTiXmlElement diffuse("DIFFUSE"); CalCoreMaterial::Color diffuseColor; diffuseColor = pCoreMaterial->getDiffuseColor(); str.str(""); str << (int)diffuseColor.red << " " << (int)diffuseColor.green << " " << (int)diffuseColor.blue << " " << (int)diffuseColor.alpha; vsxTiXmlText diffusedata(str.str()); diffuse.InsertEndChild(diffusedata); material.InsertEndChild(diffuse); vsxTiXmlElement specular("SPECULAR"); CalCoreMaterial::Color specularColor; specularColor = pCoreMaterial->getSpecularColor(); str.str(""); str << (int)specularColor.red << " " << (int)specularColor.green << " " << (int)specularColor.blue << " " << (int)specularColor.alpha; vsxTiXmlText speculardata(str.str()); specular.InsertEndChild(speculardata); material.InsertEndChild(specular); vsxTiXmlElement shininess("SHININESS"); str.str(""); str << pCoreMaterial->getShininess(); vsxTiXmlText shininessdata(str.str()); shininess.InsertEndChild(shininessdata); material.InsertEndChild(shininess); std::vector<CalCoreMaterial::Map>& vectorMap = pCoreMaterial->getVectorMap(); int mapId; for(mapId = 0; mapId < (int)vectorMap.size(); ++mapId) { vsxTiXmlElement map("MAP"); vsxTiXmlText mapdata(vectorMap[mapId].strFilename); map.InsertEndChild(mapdata); material.InsertEndChild(map); } doc.InsertEndChild(material); if(!doc.SaveFile()) { CalError::setLastError(CalError::FILE_WRITING_FAILED, __FILE__, __LINE__, strFilename); return false; } return true; }