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

Set up ray types for testrender #1648

Merged
merged 3 commits into from
Feb 27, 2023

Conversation

lgritz
Copy link
Collaborator

@lgritz lgritz commented Feb 21, 2023

Try to set ray types correctly for rays -- a little naive now, only using "camera", "shadow", and also "diffuse" for all indirect rays (leave distinguishing between reflection, refraction, diffuse, glossy for another day, and currently testrender doesn't support subsurface or displacement, but maybe someday).

Also, for testshade, improve efficency -- don't decode raytype on every point. For each individual shade, testshade was converting the name of the raytype from a string to a ustring, then decoding to a bitfield. Pull it all out of the loops by computing the bitfield once.

Copy link
Contributor

@fpsunflower fpsunflower left a comment

Choose a reason for hiding this comment

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

LGTM

It would be hard to split raytype much further for testrender without a fairly significant refactor to all the closures.

@lgritz
Copy link
Collaborator Author

lgritz commented Feb 21, 2023

Yeah, I figured. It would go deep into the closures, and that was much more than I was prepared to do at the moment, and also is unnecessary for what @jstone-lucasfilm needs to get unstuck, which I think is merely to distinguish camera rays from secondary rays.

Try to set ray types correctly for rays -- a little naive now, only
using "camera", "shadow", and "diffuse" for all rays (leave
distinguishing between reflection, refraction, diffuse, glossy for
another day, and currently testrender doesn't support subsurface or
displacement, but maybe someday).

Also, for testshade, improve efficency -- don't decode raytype on
every point.  For each individual shade, testshade was converting the
name of the raytype from a string to a ustring, then decoding to a
bitfield. Pull it all out of the loops by computing the bitfield once.

Signed-off-by: Larry Gritz <lg@larrygritz.com>
@lgritz
Copy link
Collaborator Author

lgritz commented Feb 22, 2023

Amended: I forgot to assign the raytype of the ray to the SG! Sorry, @jstone-lucasfilm, fixed now. Also, I added a testsuite entry to verify. (Note to self: how many decades will it take me to fully absorb the precept that "untested code is buggy code," always dammit.)

@lgritz
Copy link
Collaborator Author

lgritz commented Feb 23, 2023

@fpsunflower Would love your opinion on this:

Now that I "fixed" this PR, the render-bumptest test fails! And it's because of this glass shader in which we try to disable the contribution of caustic rays by testing (!raytype("glossy") && !raytype("diffuse")).

Well, a minute ago when we didn't set the ray type correctly at all in testrender, it was never these ray types. Now we do, but we set all non-camera rays to think they are diffuse -- because, as noted, correctly distinguishing reflection vs refraction vs glossy vs diffuse requires the BSDF closures themselves having more smarts than they currently do in testrender -- and so all secondary rays (even reflection rays) think they are diffuse, therefore they don't shade now!

The same glass shader is in src/shaders, obviously meant to be an example, though now we see that it's a poor example (at least when used with a fixed testrender. So that's very unsatisfying.

I'm sure that we did it this way because once upon a time, SPI's glass shader probably had a similar idiom. But maybe this isn't the way we would currently recommend that anybody do it.

I think the expedient thing is to just remove the "caustic-avoiding" behavior of this shader, which we clearly didn't depend on because it never worked properly. But still curious to hear your amused take on this, Chris.

@fpsunflower
Copy link
Contributor

Yeah I agree, the caustic avoidance should be done in the integrator, not the shader.

That being said - there is still a grey area where the renderer, through its own heuristics will not actually use something the shader could have worked really hard to compute. So there is still some need for a mechanism for the renderer to tell the shader "I am not going to use a,b, or c even if you give them to me". I don't think we ever came up with a satisfying design for this.

One candidate we had talked about adding (and maybe we did this via getattribute() is the maximum path roughness. This is a bit better than raytype because it less. you do a softer cutoff of some effects.

Another design we considered was giving some more explicit hints to the shader like:

  • skip bump
  • skip sss
  • skip specular
  • etc ...

The logic would even be mostly the same as raytype() -- it would just be querying a bitmask populated by the renderer with some agreed upon strings. If we design the hints to be "skip X" -- that allows the shader to ignore these hints if it wants -- they are only there for the sake of early exits.

As an example where raytypes definitely don't work - consider the connection rays in BDPT -- they only need to know transparency information, but are not technically "shadow" rays -- in fact if you allow lens connections they can be "camera" rays (!). This is where having a more explicit list of "skippable work" seems beneficial.

Another idea we discussed but never actually implemented was the idea of letting the renderer tell the compiler before runtime optimization (or during, via callbacks) which closures it is interested in. If the renderer decides a particular closure is not important (say something specular after deciding its not going to allow caustics), it would let the runtime optimization turn that into a no-op and most likely cascade into a bunch of other simplifications. We actually already do this for raytypes by giving the mask of "definitely on" and "definitely off" -- this would be another flavor of that. That being said -- the trend seems to be to move away from compiling additional specializations of shaders given the JIT compilation costs, so I think ultimately we'll want to stick to things that are cheap at to leave in for a runtime decision.

Its definitely a topic worth discussing at the next TSC, I am curious how other teams solved this. I suspect that if you have a "pattern only" integration of OSL, this problem presents itself much less, because you simply wouldn't pull on the shader outputs that generate something you don't need. So maybe this is only an issue for those folks relying on closures?

@fpsunflower
Copy link
Contributor

Also that glass shader should definitely be rewritten to use the shiny new Material X closures :)

The code path that was supposed to suppress noisy caustic rays never
worked properly before because we never set the ray type in
testrender. Now that testrender sets it -- but does not distinguish
between the different types of secondary rays -- the code path is
active, but incorrect, and causes tests to fail. Just remove the
offending clause for now and return to the old behavior of the shader
(no attempt to eliminate caustic rays). Later, we should revamp the
glass shader entirely by switching to the newer MaterialX-inspired
closures.

Signed-off-by: Larry Gritz <lg@larrygritz.com>
@lgritz
Copy link
Collaborator Author

lgritz commented Feb 23, 2023

I updated the PR by removing the special cases that attempted to suppress caustic rays.

Later, we should rewrite those glass shaders entirely based on the new closures, but I wanted to limit the scope creep of this PR which was really just aimed at fixing what Jonathan needed right away.

Signed-off-by: Larry Gritz <lg@larrygritz.com>
@lgritz
Copy link
Collaborator Author

lgritz commented Feb 27, 2023

On Slack, Jonathan reports that this works, so I'm going to merge.

As a note: the last batch of trouble Jonathan was having was because of this line:

<Background resolution="1024" /> 

currently, this will run the shader out of any ray context at all (therefore having no raytype) in order to populate an environment map that will be used as needed.

Remove the "resolution" part so it just says

<Background  />

and it will run the shader every time it's needed, with the correct(-ish) ray type. But... we also discovered that when you do that, no importance sampling is used at all, so it's much noisier. I think the right approach is to do both -- populate the map for importance sampling, but run the shader on the rays themselves to get higher quality visible results. Caveat emptor if you write a shader that has ray behavior that deviates significantly from the no-raytype behavior that will be used to understand the distribution of energy.

@lgritz lgritz merged commit a68a972 into AcademySoftwareFoundation:main Feb 27, 2023
lgritz added a commit to lgritz/OpenShadingLanguage that referenced this pull request Mar 1, 2023
Try to set ray types correctly for rays -- a little naive now, only
using "camera", "shadow", and "diffuse" for all rays (leave
distinguishing between reflection, refraction, diffuse, glossy for
another day, and currently testrender doesn't support subsurface or
displacement, but maybe someday).

Also, for testshade, improve efficency -- don't decode raytype on
every point.  For each individual shade, testshade was converting the
name of the raytype from a string to a ustring, then decoding to a
bitfield. Pull it all out of the loops by computing the bitfield once.

Adjust glass shaders to not change behavior based on raytype:
The code path that was supposed to suppress noisy caustic rays never
worked properly before because we never set the ray type in
testrender. Now that testrender sets it -- but does not distinguish
between the different types of secondary rays -- the code path is
active, but incorrect, and causes tests to fail. Just remove the
offending clause for now and return to the old behavior of the shader
(no attempt to eliminate caustic rays). Later, we should revamp the
glass shader entirely by switching to the newer MaterialX-inspired
closures.

Note: when you specify a resolution in the Background command in our 
scene xml, it will  run the shader out of any ray context at all (therefore
having no raytype) in order to populate an environment map that will be
used as needed. If you omit the resolution, no importance sampling is
used at all, so it's much noisier. I think the right approach is to do both --
populate the map for importance sampling, but run the shader on the rays
themselves to get higher quality visible results.

Signed-off-by: Larry Gritz <lg@larrygritz.com>
@lgritz lgritz deleted the lg-testrender-raytype branch March 16, 2023 06:01
chellmuth pushed a commit to chellmuth/OpenShadingLanguage that referenced this pull request Sep 6, 2024
  * Don't insert redundant run layer calls inside a basic block (AcademySoftwareFoundation#1665)
  * Apply recent run layer call optimization to batched execution (AcademySoftwareFoundation#1669)
  * Do-over: Make recent run-layer optimizations optional, and fix
    init ops-related false positive (AcademySoftwareFoundation#1672)
  * fix for ReParameterization corner case (AcademySoftwareFoundation#1670)
  * RendererServices API for letting get_texture_handle consider colorspace (AcademySoftwareFoundation#1641)
  * Set up ray types for testrender (AcademySoftwareFoundation#1648)
  * testrender: Don't use the cached background map on the first bounce (AcademySoftwareFoundation#1649)
  * Switch lockgeom to interpolated and interactive (AcademySoftwareFoundation#1662)
  * Add type information for needed attributes. (AcademySoftwareFoundation#1650)

Note that this bump to 1.13.3.x is only for Arnold at this point, and
not yet for the platforms, so to make CI go faster I have rigged
.spdev.yaml to only build the sparnold versions at this time.

Also updated ABI dump files.

See merge request spi/dev/3rd-party/osl-feedstock!47
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.

2 participants