<p>So for anyone who was interested - after studying the source material by Walter, I became convinced the error had to be in the rotation of the slopes back into "normal shading space".  PBRT does this in a one-liner: "CosPhi(wiStretched) * slope_x - SinPhi(wiStretched) * slope_y;" etc etc.  I had split it out into separate sinTheta, sinPhi, sinPhiX steps.  One of those steps wasn't correct so the rotation wasn't unstreching correctly.  </p>

<p>So the correct visualization for a GGX normal distribution of half vectors is this: 
<a href="https://i.sstatic.net/rcyw8.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/rcyw8.jpg" alt="enter image description here"></a></p>

CC BY-SA 3.0
2017-05-04T19:55:23.870Z
Nice detective work. Have you fed this back to the author?
trichoplax is on Codidact now
CC BY-SA 3.0
2017-05-05T17:04:50.597Z
I'm actually the one who screwed up the code when I translated it to webgl - so yeah :-) I definitely let myself know. What I think I found most difficult about this problem is the lack of good information or graphics that actually visualize what the algorithms produce in graphics.
Steve
CC BY-SA 3.0
2017-05-03T18:05:42.833Z
2017-05-03T18:05:42.833Z
Steve
<p>I am attempting to visualize the raw output from PBRT's half-vector sampling function, based on the trowbridge-reitz distribution.  I'm isolating only the distribution and the associated functions necessary to sample it. </p>

<p>The function is based on the standard GGX half vector sampling formula: </p>

<p>$$\theta_s = arctan(\frac{\alpha_g\sqrt{\xi_1}}{\sqrt{1-\xi_1}})$$
$$\phi_s = 2\pi\xi_2$$</p>

<p>(from Walter GGX: <a href="http://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf" rel="nofollow noreferrer">http://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf</a>)</p>

<p>but the PBRT version has a lot more black magic related to importance sampling only directions that make significant contributions based on the incoming "wo" angle.  That one detail is making it hard for me to find published papers which specify how to add this directional importance sampling to the standard GGX sampling function.</p>

<p>Anyway, these angles come back from the sampling function as a vector 3 and spherical coordinates with $$Normalize([\theta_s,\phi_s, 1.0])$$ which should perturb the surface normal, creating the half vector to reflect around.</p>

<p>At this point I am only trying to make sense of the output from the "sample wh" function.  To visualize the results (raw "wh" output) I made a little graphics utility to output the results to a "normal map".  Here is the output:<a href="https://i.sstatic.net/0G3ei.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/0G3ei.jpg" alt="GGX half vector samples"></a></p>

<p>And a live webgl example here that continually runs new random numbers through the output (as if monte carlo sampling were running): <a href="http://rdtests.ml3ds-test.com/microfacettesting.html" rel="nofollow noreferrer">http://rdtests.ml3ds-test.com/microfacettesting.html</a></p>

<p>My expectation of the output would be a somewhat smooth gradient blend of the wh orientations as the x and y slopes cross into each other.  But what i'm seeing is an area between the 2 axes that doesn't want to blend well.  The random noise is good/expected, but you can see that inside the x/y blend areas, even the noise becomes fairly non-random.  </p>

<p>Can anyone give me some tips on what the half vector sampling <em>should</em> graph like, or some pointers to papers/published work that I can use to locate test data, graphs, or other educational material that could help me figure this out?  </p>

<raytracing><pathtracing><sampling><distribution>
Visualize the output of a Trowbridge-Reitz Half Vector Sampling Function
Steve
# Visualize the output of a Trowbridge-Reitz Half Vector Sampling Function

(Asked by: username_0 on 2017-05-03)

I am attempting to visualize the raw output from PBRT's half-vector sampling function, based on the trowbridge-reitz distribution. I'm isolating only the distribution and the associated functions necessary to sample it.

The function is based on the standard GGX half vector sampling formula:

$$\theta\_s = arctan(\frac{\alpha\_g\sqrt{\xi\_1}}{\sqrt{1-\xi\_1}})$$
$$\phi\_s = 2\pi\xi\_2$$

(from Walter GGX: <http://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf>)

but the PBRT version has a lot more black magic related to importance sampling only directions that make significant contributions based on the incoming "wo" angle. That one detail is making it hard for me to find published papers which specify how to add this directional importance sampling to the standard GGX sampling function.

Anyway, these angles come back from the sampling function as a vector 3 and spherical coordinates with $$Normalize([\theta\_s,\phi\_s, 1.0])$$ which should perturb the surface normal, creating the half vector to reflect around.

At this point I am only trying to make sense of the output from the "sample wh" function. To visualize the results (raw "wh" output) I made a little graphics utility to output the results to a "normal map". Here is the output:[![GGX half vector samples](https://i.sstatic.net/0G3ei.jpg)](https://i.sstatic.net/0G3ei.jpg)

And a live webgl example here that continually runs new random numbers through the output (as if monte carlo sampling were running): <http://rdtests.ml3ds-test.com/microfacettesting.html>

My expectation of the output would be a somewhat smooth gradient blend of the wh orientations as the x and y slopes cross into each other. But what i'm seeing is an area between the 2 axes that doesn't want to blend well. The random noise is good/expected, but you can see that inside the x/y blend areas, even the noise becomes fairly non-random.

Can anyone give me some tips on what the half vector sampling *should* graph like, or some pointers to papers/published work that I can use to locate test data, graphs, or other educational material that could help me figure this out?

**Tags:** raytracing, pathtracing, sampling, distribution


---

## 1 answers

### Answer by username_0 on 2017-05-03. Score: 2

So for anyone who was interested - after studying the source material by Walter, I became convinced the error had to be in the rotation of the slopes back into "normal shading space". PBRT does this in a one-liner: "CosPhi(wiStretched) \* slope\_x - SinPhi(wiStretched) \* slope\_y;" etc etc. I had split it out into separate sinTheta, sinPhi, sinPhiX steps. One of those steps wasn't correct so the rotation wasn't unstreching correctly.

So the correct visualization for a GGX normal distribution of half vectors is this:
[![enter image description here](https://i.sstatic.net/rcyw8.jpg)](https://i.sstatic.net/rcyw8.jpg)

> **Comments:**
> **username_1**: Nice detective work. Have you fed this back to the author?  
> **username_0**: I'm actually the one who screwed up the code when I translated it to webgl - so yeah :-) I definitely let myself know. What I think I found most difficult about this problem is the lack of good information or graphics that actually visualize what the algorithms produce in graphics.  

---

