-
I wrote a non-differentiable version of the path tracer based on the pbr integrator, it runs successfully but I can't get a result image, and the compiler doesn't report any errors, can anyone see a problem? I can't find the test.png in the results folder import mitsuba as mi
import drjit as dr
mi.set_variant('cuda_ad_rgb')
def mis_weight(pdf_a, pdf_b):
"""
Compute the Multiple Importance Sampling (MIS) weight given the densities
of two sampling strategies according to the power heuristic.
"""
a2 = pdf_a*pdf_a
b2 = pdf_b*pdf_b
w = a2 / (a2 + b2)
return dr.select(dr.isfinite(w), w, 0)
class PathTracer(mi.SamplingIntegrator):
def __init__(self,props):
mi.SamplingIntegrator.__init__(self,props)
self.max_depth = 6
def sample(self: mi.SamplingIntegrator, scene: mi.Scene, sampler, ray: mi.RayDifferential3f, medium: mi.Medium = None, active: bool = True):
bsdf_ctx = mi.BSDFContext()
ray = mi.Ray3f(ray)
depth = mi.UInt32(0)
L = mi.Float(0.0)
beta = mi.Float(1.0)
active = mi.Bool(active)
prev_bsdf_delta = mi.Bool(True)
prev_si = dr.zeros(mi.SurfaceInteraction3f)
prev_bsdf_pdf = mi.Float(1.0)
loop = mi.Loop(name="Basic PathTracer without anything",state=lambda:(sampler,L,depth,ray,beta,active,prev_bsdf_delta,prev_si,prev_bsdf_pdf))
while loop(active):
active_next = mi.Bool(active)
# get interactions
si = scene.ray_intersect(ray,ray_flags=mi.RayFlags.All,coherent=(depth==0))
bsdf = si.bsdf(ray)
# hide emitters ?
if self.hide_emitters:
active_next &= ~(dr.eq(depth,0) & ~si.is_valid())
# --------------------- direct emission ------------------------
ds = mi.DirectionSample3f(scene,si,prev_si)
mis = mis_weight(prev_bsdf_pdf,scene.pdf_emitter_direction(prev_si,ds,~prev_bsdf_delta))
Le = beta * mis * ds.emitter.eval(si,active_next)
# --------------------- emitter sampling ------------------------
# continue tracing to reach more vertex ?
active_next &= (depth + 1 < self.max_depth) & si.is_valid()
# Is emitter sampling possible on the current vertex?
active_em = active_next & mi.has_flag(bsdf.flags(),mi.BSDFFlags.Smooth)
# sample the emitters
ds,em_weight = scene.sample_emitter_direction(si,sampler.next_2d(),True,active_em)
active_em &= (ds.pdf!=0)
#evaluate BSDF*cos(theta)
wo = si.to_local(ds.d)
bsdf_value_em , bsdf_pdf_em = bsdf.eval_pdf(bsdf_ctx,si,wo,active_em)
mis_em = dr.select(ds.delta,1,mis_weight(ds.pdf,bsdf_pdf_em))
Lr_dir = beta * mis_em * bsdf_value_em * em_weight
# --------------------- bsdf sampling -----------------------
# bsdf_weight : bsdf_val*cosθ / pdf
bsdf_sample, bsdf_weight = bsdf.sample(bsdf_ctx,si,sampler.next_1d(),sampler.next_2d(),active_next)
# --------------------- update the variables --------------------------
L = L + Le + Lr_dir
ray = si.spawn_ray(si.to_world(bsdf_sample.wo)) #generate rays for next iteration
beta *= bsdf_weight #update β
prev_si = si
prev_bsdf_pdf = bsdf_weight
prev_bsdf_delta = mi.has_flag(bsdf_sample.sampled_type,mi.BSDFFlags.Delta)
beta_max = dr.max(beta)
active_next &= (beta_max != 0)
depth[si.is_valid()] += 1
active = active_next
return [L,dr.eq(depth,0),[]]
mi.register_integrator("PathTracer", lambda props: PathTracer(props))
if __name__ == "__main__":
scene = mi.load_dict(mi.cornell_box())
# scene = mi.load_file('./scenes/cbox.xml')
integrator = mi.load_dict({
"type":"PathTracer",
# "max_depth":6
})
sensor = scene.sensors()[0]
film = sensor.film()
film.prepare([])
integrator.render(scene,sensor)
image = film.bitmap(raw=True).convert(mi.Bitmap.PixelFormat.RGB, mi.Struct.Type.UInt8, srgb_gamma=True)
image.write('./results/test.png') |
Beta Was this translation helpful? Give feedback.
Answered by
njroussel
Jun 26, 2024
Replies: 1 comment 1 reply
-
Hi @ioissss As mentioned in mitsuba-renderer/drjit#231, all of your equality/inequality tests should be changed to use When running your code myself, I do however get the appropriate error messages in |
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
ioissss
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi @ioissss
As mentioned in mitsuba-renderer/drjit#231, all of your equality/inequality tests should be changed to use
dr.eq
/dr.neq
.When running your code myself, I do however get the appropriate error messages in
stderr
. Something abour your environment is suppressing those messages.