NVlabs / nvdiffrec

Official code for the CVPR 2022 (oral) paper "Extracting Triangular 3D Models, Materials, and Lighting From Images".
Other
2.09k stars 222 forks source link

What's the purpose of custom mipmap build function. #142

Closed saedrna closed 10 months ago

saedrna commented 10 months ago

I have noticed that the code use a custom mipmap build function texture2d_mip for the texture sampling. I am wondering what's the difference with the built-in function in diffract, e.g., texture_construct_mip.

https://github.com/NVlabs/nvdiffrec/blob/e7f2181b8a60eb8fedcdb4ad4d05bff3c0cf9bc1/render/texture.py#L21-L32

I have tried to replace the lines below with texture_construct_mip, but it seems that there is no difference.

https://github.com/NVlabs/nvdiffrec/blob/e7f2181b8a60eb8fedcdb4ad4d05bff3c0cf9bc1/render/texture.py#L65C5-L76

JHnvidia commented 10 months ago

Hi @saedrna,

It's mostly equivalent, and the main reason is legacy. In previous work (https://github.com/NVlabs/nvdiffmodeling) we did experiments on shader filtering by computing custom mip-pyramids. For example, it's usually a good idea to artificially reduce material roughness to supress highlight-flickering at coarse miplevels.It makes more sense for level-of-detail, though, so we're not using it in the nvdiffrec codebases.

The texture_construct_mip function creates an opaque object with the mipmap information, so it doesn't support passing the individual miplevels to a torch optimizer.

saedrna commented 10 months ago

For example, it's usually a good idea to artificially reduce material roughness to supress highlight-flickering at coarse miplevels.

The texture_construct_mip function creates an opaque object with the mipmap information, so it doesn't support passing the individual miplevels to a torch optimizer.

Thanks, I get the idea. Probably similar to the purpose of prefiltered specular envmap, i.e., more rough object will be sampled from coarse miplevels as below.

            # Roughness adjusted specular env lookup
            miplevel = self.get_mip(roughness)
            spec = dr.texture(self.specular[0][None, ...], reflvec.contiguous(), mip=list(m[None, ...] for m in self.specular[1:]), mip_level_bias=miplevel[..., 0], filter_mode='linear-mipmap-linear', boundary_mode='cube')