Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[✨ feature] Implement eval_roughness() for most BSDFs #589

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

saeedhd96
Copy link

@saeedhd96 saeedhd96 commented Mar 14, 2023

Description

Introduce method eval_roughness() similar to eval_diffuse_reflectance() ...

Fixes #454

Testing

Tested on a two-sided BSDF, the test is named test04_eval_roughness in test_twosided.py

Checklist

  • My code follows the style guidelines of this project
  • My changes generate no new warnings
  • My code also compiles for cuda_* and llvm_* variants. If you can't test this, please leave below
  • I have commented my code
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • I cleaned the commit history and removed any "Merge" commits
  • I give permission that the Mitsuba 3 project may redistribute my contributions under the terms of its license

Copy link
Member

@njroussel njroussel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this PR @saeedhd96 , especially for going through all of these BSDFs.

A part from the few minor comments, could I ask you to please add a test for the aov changes? Preferably in a new file src/integrators/tests/test_aov.py -- you only need to test the roughness. You can just spawn a single ray that is supposed to hit a rectangle with known roughness and verify the aovs return value. (We don't have any existing tests for the aov integrator.)

include/mitsuba/python/docstr.h Show resolved Hide resolved
Comment on lines 66 to +67
}
Float eval_roughness(const SurfaceInteraction3f &si,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing new line here.

Comment on lines +525 to +530
* This method approximates the roughness for a given
* direction. For some materials, an exact value can be computed
* inexpensively.
* When this is not possible, the value is approximated by
* evaluating the BSDF for a normal outgoing direction and returning this
* value multiplied by pi. This is the default behaviour of this method.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update this 😄

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why shouldn't it be exactly the same? doesn't it under the hood call same methods as diffuse_reflectance_eval?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused.

Doesn't the default behaviour just return 1 currently? It doesn't use the BSDF evaluation at the normal direction.

src/render/bsdf.cpp Show resolved Hide resolved
* surface position.
*/
virtual Float eval_roughness(const SurfaceInteraction3f &si,
Mask active = true) const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean I should indent it one more tab or one less?
Isn't it currently in line with diffuse_reflectance?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Mask active = true argument should be aligned with the opening parenthesis of the previous line. Like in the other methods. Do you see what I mean?

Comment on lines +286 to +305
SurfaceInteraction3f si(si_);

if (m_brdf[0] == m_brdf[1]) {
si.wi.z() = dr::abs(si.wi.z());
return m_brdf[0]->eval_roughness(si, active);
} else {
Float result = 0.f;
Mask front_side = Frame3f::cos_theta(si.wi) > 0.f && active,
back_side = Frame3f::cos_theta(si.wi) < 0.f && active;

if (dr::any_or<true>(front_side))
result = m_brdf[0]->eval_roughness(si, front_side);

if (dr::any_or<true>(back_side)) {
si.wi.z() *= -1.f;
dr::masked(result, back_side) =
m_brdf[1]->eval_roughness(si, back_side);
}

return result;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we move this logic to a separate function?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this be a concern of this PR? since such a refactoring is a different task than this, and should happen for other methods of this class, I would suggest doing that in another tab. Also, I am not too good at C++, and I cannot do such a refactoring without bad consequences :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with this. I'll refactor it with a lambda once it's merged.

@Speierers
Copy link
Member

Thanks @saeedhd96 for this PR!

It would be beneficial if this feature could also take into account anisotropic roughness. Would it be best to have this method return two roughness values? Is there something I'm not considering?

@saeedhd96
Copy link
Author

saeedhd96 commented Apr 14, 2023

I can totally get the point of having it return two roughness values for anisotropic. I can do that, but I guess that would be the behavior across all imlementations ... is that OK?
I am planning to use mi.Vectorf2f() for that, is that ok?
@Speierers

@njroussel
Copy link
Member

I hadn't considered the anisotropic case.
It's not an issue, you can return two values for all implementations. Vector2f is good too :)

(Sorry for the delay...)

@wjakob wjakob force-pushed the master branch 3 times, most recently from 3f3b8d0 to 1bdea6e Compare October 12, 2023 19:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants