wahn/rs_pbrt

Rethink SurfaceInteraction regarding C++ mutable members

wahn opened this issue · 6 comments

wahn commented

In C++ the class SurfaceInteraction looks like this:

class SurfaceInteraction : public Interaction {                                                         
  public:                                                                                               
...
    mutable Vector3f dpdx, dpdy;                                                                        
    mutable Float dudx = 0, dvdx = 0, dudy = 0, dvdy = 0;                                               
...                                                                                                        
};                                                                                                      

Most likely we should try to use Rust's interior mutability, e.g. RefCell. See C++ vs Rust and search for mutable keyword.

wahn commented

From the module cell documentation:

Consider using RwLock<T> or Mutex<T> if you need shared mutability in a multi-threaded situation.

wahn commented

I created a branch (issue_114) for this issue. Currently the Rust side looks like this:

pub struct SurfaceInteraction<'p, 's> {
    // Interaction Public Data
    pub p: Point3f,
    pub time: Float,
    pub p_error: Vector3f,
    pub wo: Vector3f,
    pub n: Normal3f,
    pub medium_interface: Option<Arc<MediumInterface>>,
    // SurfaceInteraction Public Data
    pub uv: Point2f,
    pub dpdu: Vector3f,
    pub dpdv: Vector3f,
    pub dndu: Normal3f,
    pub dndv: Normal3f,
    pub dpdx: RwLock<Vector3f>,
    pub dpdy: RwLock<Vector3f>,
    pub dudx: RwLock<Float>,
    pub dvdx: RwLock<Float>,
    pub dudy: RwLock<Float>,
    pub dvdy: RwLock<Float>,
    pub primitive: Option<&'p GeometricPrimitive>,
    pub shading: Shading,
    pub bsdf: Option<Arc<Bsdf>>,
    pub bssrdf: Option<Arc<TabulatedBssrdf>>,
    pub shape: Option<&'s dyn Shape>,
}

I made the remaining files compile, but the mlt and bdpt algorithms had to be removed. I think I have to find a better solution for the pointers involved. On the C++ side they are part of a struct and a class:

struct Interaction {                                                                                    
...
    MediumInterface mediumInterface;                                                                    
};                                                                                                      
...
class SurfaceInteraction : public Interaction {
...
    const Shape *shape = nullptr;                                                                       
...
    const Primitive *primitive = nullptr;                                                               
    BSDF *bsdf = nullptr;                                                                               
    BSSRDF *bssrdf = nullptr;                                                                           
};                                                                                                
wahn commented

After commit 031de34 we got rid of the lifetimes:

pub struct SurfaceInteraction {                                                                         
    // Interaction Public Data                                                                          
    pub p: Point3f,                                                                                     
    pub time: Float,                                                                                    
    pub p_error: Vector3f,                                                                              
    pub wo: Vector3f,                                                                                   
    pub n: Normal3f,                                                                                    
    pub medium_interface: Option<Arc<MediumInterface>>,                                                 
    // SurfaceInteraction Public Data                                                                   
    pub uv: Point2f,                                                                                    
    pub dpdu: Vector3f,                                                                                 
    pub dpdv: Vector3f,                                                                                 
    pub dndu: Normal3f,                                                                                 
    pub dndv: Normal3f,                                                                                 
    pub dpdx: RwLock<Vector3f>,                                                                         
    pub dpdy: RwLock<Vector3f>,                                                                         
    pub dudx: RwLock<Float>,                                                                            
    pub dvdx: RwLock<Float>,                                                                            
    pub dudy: RwLock<Float>,                                                                            
    pub dvdy: RwLock<Float>,                                                                            
    pub primitive: Option<Arc<dyn Primitive + Send + Sync>>,                                            
    pub shading: Shading,                                                                               
    pub bsdf: Option<Arc<Bsdf>>,                                                                        
    pub bssrdf: Option<Arc<TabulatedBssrdf>>,                                                           
    pub shape: Option<Arc<dyn Shape + Send + Sync>>,                                                    
}                                                                                                       
wahn commented

Let's see if we can make the mlt and bdpt algorithms work again ...

wahn commented

After commit e5ca87e bidirectional pathtracing works again:

> ./target/release/rs_pbrt -i assets/scenes/cafe_scene2.pbrt
...
Integrator "bdpt"
  "integer maxdepth" [3]
...
Rendering with 8 thread(s) ...
1024 / 1024 [=======================================================================] 100.00 % 12.19/s  
Writing image "pbrt.png" with bounds Bounds2 { p_min: Point2 { x: 0, y: 0 }, p_max: Point2 { x: 500, y: 500 } }

pbrt

Now we just need mlt to work again before we can merge the branch back to the master branch.

wahn commented

After commit 84ec364 mlt should work again. Everything is merged into the master branch. Let's close the issue then ...