lowkey42/mirrage

Importance-Sampling (-ish)

Closed this issue · 1 comments

Klassisches Importance-Sampling ist vermutlich nicht direkt mit dem aktuellen Sampling-Pattern vereinbar aber eine einfache Verbesserung der Trefferquote könnte evtl. bereits dadurch erzielt werden, dass die Winkel der Punkte (in Polarkoordinaten) in Richtung der Screen-Space Normale des Ausgangspunktes verschoben (gewichtet mit 1-Z).

Fürs Protokoll:

Python-Code für Verteilung der Samples:

import matplotlib.pyplot as plt
import math

def lerp(a, b, t):
    return a + (b-a)*t


fig, ax = plt.subplots()
ax.add_artist(plt.Circle((0.5, 0.5), 0.5, color='grey'))
ax.add_artist(plt.Circle((0.5, 0.5), 0.25, color='darkgrey'))
plt.gca().set_aspect('equal', adjustable='box')

phi = ((math.sqrt(5)+1)/2)**2.0
step = math.pi * 2.0 / phi

r_outer = 0.5;
r_inner = r_outer/2;


normal = (1, 0, 0.0)

N = 128

for i in range(0, N):
    t = math.sqrt(i*1.0) / math.sqrt(N);
    r = r_inner + (r_outer - r_inner)*t;
    
    angle = math.fmod(i * step, 2*math.pi);
    
    ar = angle / (2*math.pi)
        
    d = ar*2 if ar<0.5 else (1-ar)*2
    org_d = d;
    print(math.degrees(angle), d)
    
    #d = 3.54*d - 5.69*d*d + 3.06*d*d*d
    #d = 3.667*d - 7.083*d*d + 4.16667*d*d*d
    #d = 1.325*d - 3.542*d*d + 2.9*d*d*d + 0.1
    d = 2.5*d - 5.42*d*d + 3.6*d*d*d + 0.1
    
    d += (1-d) * normal[2]
    
    if ar<0.5:
        angle = lerp(0, angle, d)
    else:
        angle = lerp(angle, math.pi*2, 1-d)
    
    angle += 0.5*math.pi + math.atan2(normal[1], normal[0])
    
    x = 0.5 + math.sin(angle)*r
    y = 0.5 + math.cos(angle)*r
    ax.add_artist(plt.Circle((x, 1-y), 0.005, color=(1, org_d, org_d)))
    

fig.savefig('/tmp/plotcircles.png')

Beispiel:
plotcircles