<p>Assume that rays with a distance larger than <span class="math-container">$D$</span> won't contribute to the occlusion. Since I don't know exactly of V-ray implements their interpolation, we can create a weight function <span class="math-container">$w(\frac{d}{D})$</span> where <span class="math-container">$w(x) = \left\{\begin{matrix}
f(x), \quad 0 \geq x \geq 1 \\ 
0, \quad otherwise
\end{matrix}\right.$</span></p>
<p>and compute <span class="math-container">$AO = 1 - \frac{1}{N} \sum_{i=0}^N w(\frac{d_i}{D})$</span>.</p>
<p>A simple example would be to let <span class="math-container">$f(x) = 1-x$</span> but this gives <span class="math-container">$w$</span> a non-continuous first derivative. Adding some additional constraints besides <span class="math-container">$f(0)=1, f(1)=0$</span>, like <span class="math-container">$f'(1) = 0, f''(1)=0$</span> would give a polynomial like <span class="math-container">$f(x) = 1-3x+3x^2-x^3$</span> which decreases in value a bit faster than linear and would give smoother results.</p>

CC BY-SA 4.0
2023-02-11T05:56:52.397Z
yep, you're right, thank you!! I didn't implement everything you showed but I got similar results with the code at my edited question.
mrmanet
CC BY-SA 4.0
2023-02-11T07:06:12.513Z
It would be too much to ask for at least a pseudocode of your non-linear interpolation? This math is a bit over my head now lol
mrmanet
CC BY-SA 4.0
2023-02-11T11:02:33.370Z
Maybe like this: https://www.shadertoy.com/view/dljSDW
Mathis
CC BY-SA 4.0
2023-02-10T22:04:35.007Z
2023-02-10T22:04:35.007Z
Mathis
<p>My AO algorithm is as follows, whith the random vectors just all over the hemisphere:</p>
<pre class="lang-cpp prettyprint-override"><code>    vec3 ao_ray_position= random_in_hemisphere(gi_rec.normal);
    
    ao_ray = ray(gi_rec.p + gi_rec.normal * 0.001f, ao_ray_position);
    ao_hit = !world.hit(ao_ray, 0, infinity, gi_rec);
            
    ao_result = Color(ao_hit / gi_samples, ao_hit/ gi_samples, ao_hit/ gi_samples);
</code></pre>
<p>which renders this image:</p>
<p><a href="https://i.sstatic.net/01Nan.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/01Nan.jpg" alt="enter image description here" /></a></p>
<p>Now this one is from V-Ray with falloff at 8,7, which is the setting I want to implement, but can't figure out how. I've seen many examples of limiting the hemisphere by cone angle but the image just renders black</p>
<p><a href="https://i.sstatic.net/N8ECX.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/N8ECX.jpg" alt="enter image description here" /></a></p>
<p>EDIT:
Thanks to Mathis I got it working, the code and the result meanwhile:</p>
<pre class="lang-cpp prettyprint-override"><code>    float ao = 1.0f;
    float dist = distance(gi_rec.p, rec.p);
    if (dist &lt; d) {
        ao = !gi_hit / dist;
    }
</code></pre>
<p><a href="https://i.sstatic.net/cv3jb.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/cv3jb.jpg" alt="enter image description here" /></a></p>

<ray><render><occlusion>
How to implement falloff control in brute force ambient occlusion?
mrmanet
# How to implement falloff control in brute force ambient occlusion?

(Asked by: username_0 on 2023-02-06)

My AO algorithm is as follows, whith the random vectors just all over the hemisphere:

```cpp
    vec3 ao_ray_position= random_in_hemisphere(gi_rec.normal);
    
    ao_ray = ray(gi_rec.p + gi_rec.normal * 0.001f, ao_ray_position);
    ao_hit = !world.hit(ao_ray, 0, infinity, gi_rec);
            
    ao_result = Color(ao_hit / gi_samples, ao_hit/ gi_samples, ao_hit/ gi_samples);

```

which renders this image:

[![enter image description here](https://i.sstatic.net/01Nan.jpg)](https://i.sstatic.net/01Nan.jpg)

Now this one is from V-Ray with falloff at 8,7, which is the setting I want to implement, but can't figure out how. I've seen many examples of limiting the hemisphere by cone angle but the image just renders black

[![enter image description here](https://i.sstatic.net/N8ECX.jpg)](https://i.sstatic.net/N8ECX.jpg)

EDIT:
Thanks to username_1 I got it working, the code and the result meanwhile:

```cpp
    float ao = 1.0f;
    float dist = distance(gi_rec.p, rec.p);
    if (dist < d) {
        ao = !gi_hit / dist;
    }

```

[![enter image description here](https://i.sstatic.net/cv3jb.jpg)](https://i.sstatic.net/cv3jb.jpg)

**Tags:** ray, render, occlusion


---

## 1 answers

### Answer by username_1 on 2023-02-10. Score: 0 | Accepted answer

Assume that rays with a distance larger than $D$ won't contribute to the occlusion. Since I don't know exactly of V-ray implements their interpolation, we can create a weight function $w(\frac{d}{D})$ where $w(x) = \left\{\begin{matrix}
f(x), \quad 0 \geq x \geq 1 \\
0, \quad otherwise
\end{matrix}\right.$

and compute $AO = 1 - \frac{1}{N} \sum\_{i=0}^N w(\frac{d\_i}{D})$.

A simple example would be to let $f(x) = 1-x$ but this gives $w$ a non-continuous first derivative. Adding some additional constraints besides $f(0)=1, f(1)=0$, like $f'(1) = 0, f''(1)=0$ would give a polynomial like $f(x) = 1-3x+3x^2-x^3$ which decreases in value a bit faster than linear and would give smoother results.

> **Comments:**
> **username_0**: yep, you're right, thank you!! I didn't implement everything you showed but I got similar results with the code at my edited question.  
> **username_0**: It would be too much to ask for at least a pseudocode of your non-linear interpolation? This math is a bit over my head now lol  
> **username_1**: Maybe like this: https://www.shadertoy.com/view/dljSDW  

---

