Parcourir la source

Add PBRT_MTL_HACK writeup, patch

Matt Pharr il y a 7 ans
Parent
commit
f7920f3826
2 fichiers modifiés avec 113 ajouts et 22 suppressions
  1. 35 22
      README.md.html
  2. 78 0
      html/mtl.patch.txt

+ 35 - 22
README.md.html

@@ -258,7 +258,7 @@ help with improvements in this area!)
 The `exporters/cinema4d` directory in the pbrt-v3 distribution provides an
 The `exporters/cinema4d` directory in the pbrt-v3 distribution provides an
 exporter from Cinema 4D. This exporter was developed to export the amazing
 exporter from Cinema 4D. This exporter was developed to export the amazing
 "landscape" scene that is on the book's front cover from Cinema 4D, so thus
 "landscape" scene that is on the book's front cover from Cinema 4D, so thus
-should be up to date with respect to pbrt's material models and rendering
+is up to date with respect to pbrt's material models and rendering
 settings. We have seen good results with using this exporter for other
 settings. We have seen good results with using this exporter for other
 Cinema 4D scenes.
 Cinema 4D scenes.
 
 
@@ -276,7 +276,8 @@ $ obj2pbrt scene.obj scene.pbrt
 If there is an accompanying material description file (e.g. `scene.mtl`),
 If there is an accompanying material description file (e.g. `scene.mtl`),
 the values in it will be roughly mapped to corresponding pbrt materials.
 the values in it will be roughly mapped to corresponding pbrt materials.
 You will likely need to manually edit and tune the materials in the
 You will likely need to manually edit and tune the materials in the
-generated pbrt file in order to achieve reasonably good-looking results.
+generated pbrt file in order to achieve reasonably good-looking
+results.
 
 
 Note that OBJ files only describe scene geometry; they don't include camera
 Note that OBJ files only describe scene geometry; they don't include camera
 specifications or descriptions of light sources. (Thus, the generated pbrt
 specifications or descriptions of light sources. (Thus, the generated pbrt
@@ -349,9 +350,11 @@ origin you've chosen as the basis for specifying a `LookAt` transformation
 for a more conventional camera model.
 for a more conventional camera model.
 
 
 While placing the camera, it can be helpful to have a point light source at
 While placing the camera, it can be helpful to have a point light source at
-the camera's position. Adding the following light source to your scene file
-does this in a way that ensures that the light moves appropriately to
-wherever the camera has been placed.
+the camera's position. Adding a light source like the following to your
+scene file does this in a way that ensures that the light moves
+appropriately to wherever the camera has been placed. (You may need to
+scale the intensity up or down for good results--remember the
+radius-squared falloff!
 
 
 ```
 ```
 AttributeBegin
 AttributeBegin
@@ -362,23 +365,33 @@ AttributeEnd
 
 
 Once the camera is placed, we have found that it's next useful to set up
 Once the camera is placed, we have found that it's next useful to set up
 approximate light sources. For outdoor scenes, a good HDR environment map
 approximate light sources. For outdoor scenes, a good HDR environment map
-is often all that is needed for lighting. For indoor scenes, you may want a
-combination of an environment map for the outside and point and/or area
-light sources for interior lights. You may find it useful to examine the
-scene in the modeling system that it came from to determine which geometry
-corresponds to area light sources and to try adding `AreaLightSource`
-properties to those. (Note that in pbrt, area light sources only emit
-lights on the side that the surface normal points; you may need a
-`ReverseOrientation` directive to make the light come out in the right
-direction.
-
-Given good lighting, the next step is to tune the materials. It can be
-helpful to pick a material and set it to an extreme value (such as a
-"matte" material that is pure red) and render the scene; this quickly shows
-which geometric models have that material associated with it. As you do
-this, watch for objects that are missing texture maps and re-add
-them. (The good news is that such objects generally do have correct texture
-coordinates with them. 
+is often all that is needed for lighting. (You may want to consider using
+`imgtool makesky` to make a realistic HDR sky environment map.)
+
+For indoor scenes, you may want a combination of an environment map for the
+outside and point and/or area light sources for interior lights. You may
+find it useful to examine the scene in the modeling system that it came
+from to determine which geometry corresponds to area light sources and to
+try adding `AreaLightSource` properties to those. (Note that in pbrt, area
+light sources only emit lights on the side that the surface normal points;
+you may need a `ReverseOrientation` directive to make the light come out in
+the right direction.)
+
+Given good lighting, the next step is to tune the materials (or set them
+from scratch). It can be helpful to pick a material and set it to an
+extreme value (such as a "matte" material that is pure red) and render the
+scene; this quickly shows which geometric models have that material
+associated with it. Alternatively, consdier applying this
+[patch](html/mtl.patch.txt) to your pbrt source tree; after rebuilding
+pbrt, if you set the `PBRT_MTL_HACK` environment variable, rendering the
+scene will cause a separate image to be generated for each `NamedMaterial`
+in the scene, with a filename corresponding to the material name. Each
+image will only include the objects with that material.
+
+As you figure out which material names correspond to what geometry, watch
+for objects that are missing texture maps and re-add them. (The good news
+is that such objects generally do have correct texture coordinates with
+them.
 
 
 # Submitting Updates
 # Submitting Updates
 
 

+ 78 - 0
html/mtl.patch.txt

@@ -0,0 +1,78 @@
+diff --git a/src/core/api.cpp b/src/core/api.cpp
+index e0c4b4a..b275b85 100644
+--- a/src/core/api.cpp
++++ b/src/core/api.cpp
+@@ -234,6 +234,9 @@ static std::vector<uint32_t> pushedActiveTransformBits;
+ static TransformCache transformCache;
+ int catIndentCount = 0;
+ 
++static bool renderEachMaterial = getenv("PBRT_MTL_HACK");
++static std::map<std::string, std::shared_ptr<Material>>::iterator namedMaterialsIter;
++
+ // API Forward Declarations
+ std::vector<std::shared_ptr<Shape>> MakeShapes(const std::string &name,
+                                                const Transform *ObjectToWorld,
+@@ -1346,6 +1349,14 @@ void pbrtWorldEnd() {
+     // Create scene and render
+     if (PbrtOptions.cat || PbrtOptions.toPly) {
+         printf("%*sWorldEnd\n", catIndentCount, "");
++    } else if (renderEachMaterial) {
++      for (namedMaterialsIter = graphicsState.namedMaterials.begin();
++           namedMaterialsIter != graphicsState.namedMaterials.end(); ++namedMaterialsIter) {
++        std::unique_ptr<Integrator> integrator(renderOptions->MakeIntegrator());
++        std::unique_ptr<Scene> scene(renderOptions->MakeScene());
++        if (scene && integrator) integrator->Render(*scene);
++      }
++      // TODO? render stuff with no material bound?
+     } else {
+         std::unique_ptr<Integrator> integrator(renderOptions->MakeIntegrator());
+         std::unique_ptr<Scene> scene(renderOptions->MakeScene());
+@@ -1371,13 +1382,24 @@ void pbrtWorldEnd() {
+ }
+ 
+ Scene *RenderOptions::MakeScene() {
+-    std::shared_ptr<Primitive> accelerator =
+-        MakeAccelerator(AcceleratorName, primitives, AcceleratorParams);
++    std::shared_ptr<Primitive> accelerator;
++    if (renderEachMaterial) {
++        std::vector<std::shared_ptr<Primitive>> filteredPrims;
++        std::copy_if(primitives.begin(), primitives.end(), std::back_inserter(filteredPrims),
++                     [](const std::shared_ptr<Primitive> &p) -> bool {
++                       return p->GetMaterial() == namedMaterialsIter->second.get();
++                     });
++        accelerator = MakeAccelerator(AcceleratorName, filteredPrims, AcceleratorParams);
++    } else {
++        accelerator = MakeAccelerator(AcceleratorName, primitives, AcceleratorParams);
++    }
+     if (!accelerator) accelerator = std::make_shared<BVHAccel>(primitives);
+     Scene *scene = new Scene(accelerator, lights);
+-    // Erase primitives and lights from _RenderOptions_
+-    primitives.erase(primitives.begin(), primitives.end());
+-    lights.erase(lights.begin(), lights.end());
++    if (!renderEachMaterial) {
++      // Erase primitives and lights from _RenderOptions_
++      primitives.erase(primitives.begin(), primitives.end());
++      lights.erase(lights.begin(), lights.end());
++    }
+     return scene;
+ }
+ 
+@@ -1427,7 +1449,17 @@ Integrator *RenderOptions::MakeIntegrator() const {
+ 
+ Camera *RenderOptions::MakeCamera() const {
+     std::unique_ptr<Filter> filter = MakeFilter(FilterName, FilterParams);
+-    Film *film = MakeFilm(FilmName, FilmParams, std::move(filter));
++    Film *film = nullptr;
++    if (renderEachMaterial) {
++      ParamSet fp = FilmParams;
++      std::unique_ptr<std::string[]> fns(new std::string[1]);
++      fns[0] = namedMaterialsIter->first + ".exr";
++      fp.AddString("filename", std::move(fns), 1);
++      std::unique_ptr<Filter> box(new BoxFilter({0.5f, 0.5f}));
++      film = MakeFilm(FilmName, fp, std::move(box));
++    } else
++      film = MakeFilm(FilmName, FilmParams, std::move(filter));
++
+     if (!film) {
+         Error("Unable to create film.");
+         return nullptr;