예제 #1
0
    def sample(self, it, sampler, active=True):
        bs = BSDFSample.zeros_like(it.p)
        spectrum = torch.zeros_like(it.p)

        cos_theta_i = it.wi[..., 2]
        active = (cos_theta_i > 0) & active
        f_i = fresnel(cos_theta_i, self.eta)[0]
        spec_sample_weight = self.spec_sample_weight()
        p_spec = f_i * spec_sample_weight
        p_diff = (1 - f_i) * (1 - spec_sample_weight)
        p_spec = (p_spec) / (p_spec + p_diff)
        p_diff = 1 - p_spec
        sample_spec = active & (sampler.sample(p_spec.shape) < p_spec)
        # sample_diff = active & (~sample_spec)
        bs.wo = torch.where(
            sample_spec.unsqueeze(-1),
            reflect(it.frame[..., 2], it.wi),
            square_to_cos_hemisphere(
                sampler.sample(it.shape()[:-1] + (2, ), device=it.device())),
        )
        bs.pdf = torch.where(
            sample_spec,
            p_spec,
            p_diff * square_to_cos_hemisphere_pdf(bs.wo),
        ).clamp(min=1e-10)
        f_o = fresnel(bs.wo[..., 2], self.eta)[0]
        spectrum = torch.where(
          sample_spec.unsqueeze(-1),
          self.specular * (f_i/bs.pdf).unsqueeze(-1),
          self.diffuse.expand_as(it.p) / (1- self.fdr_int) \
          *  bs.pdf.unsqueeze(-1) * self.inv_eta_2 *\
          (1 - f_i.unsqueeze(-1)) * (1 - f_o.unsqueeze(-1))
        )

        return bs, spectrum
예제 #2
0
 def sample(self, it, sampler, active=True):
     cos_theta_i = it.wi[..., 2]
     bs = BSDFSample.zeros_like(it.p)
     bs.wo = square_to_cos_hemisphere(
         sampler.sample(it.shape()[:-1] + (2, ), device=it.device()))
     bs.wo = F.normalize(bs.wo, dim=-1)
     bs.pdf = square_to_cos_hemisphere_pdf(bs.wo)
     bs.eta = 1.0
     spectrum = self.act(self.mlp(param_rusin2(it.wi, bs.wo)))
     return bs, spectrum
예제 #3
0
    def eval_and_pdf(self, it, wo, active=True):
        cos_theta_i = it.wi[..., 2]
        cos_theta_o = wo[..., 2]
        #active = (cos_theta_i > 0) & (cos_theta_o > 0) & active

        spectrum = self.preproc(cos_theta_o.unsqueeze(-1) * self.reflectance)
        #spectrum[~active] = 0
        pdf = square_to_cos_hemisphere_pdf(wo)
        #pdf[~active] = 0

        return spectrum, pdf
예제 #4
0
    def eval_and_pdf(self, it, wo, active=True):
        cos_theta_i = it.wi[..., 2]
        cos_theta_o = wo[..., 2]
        # active = (cos_theta_i > 0) & (cos_theta_o > 0) & active
        R = reflect(it.frame[..., 2], it.wi)
        spectral = (R * wo).sum(dim=-1).clamp(min=1e-20).pow(self.min_spec +
                                                             self.shine.exp())
        spectrum = cos_theta_i.unsqueeze(-1) * self.diffuse/math.pi + \
                   spectral.unsqueeze(-1) * self.specular/math.pi
        # just a guess of the PDF since it's not physically based
        pdf = square_to_cos_hemisphere_pdf(wo)

        #spectrum[~active] = 0
        #pdf[~active] = 0
        return spectrum, pdf
예제 #5
0
    def sample(self, it, sampler, active=True):
        cos_theta_i = it.wi[..., 2]

        bs = BSDFSample.zeros_like(it.p)

        active = (cos_theta_i > 0) & active
        if not active.any(): return bs, torch.zeros_like(it.p)

        bs.wo = square_to_cos_hemisphere(
            sampler.sample(it.shape()[:-1] + (2, ), device=it.device()))
        bs.wo = F.normalize(bs.wo, dim=-1)
        bs.pdf = square_to_cos_hemisphere_pdf(bs.wo)
        bs.eta = 1.0
        bs.sampled_component = 0
        # cast spectrum to same shape as interaction
        spectrum = self.preproc(self.reflectance).expand(*it.shape()).clone()
        #spectrum[(~active) | (bs.pdf <= 0), :] = 0
        return bs, spectrum
예제 #6
0
    def eval_and_pdf(self, it, wo, active=True):
        cos_theta_i = it.wi[..., 2]
        cos_theta_o = wo[..., 2]
        active = (cos_theta_i > 0) & (cos_theta_o > 0) & active
        f_i = fresnel(cos_theta_i, self.eta)[0]
        f_o = fresnel(cos_theta_o, self.eta)[0]
        pdf = square_to_cos_hemisphere_pdf(wo)
        spectrum = (self.diffuse.expand_as(it.p)/(1 - self.fdr_int)) \
          *  self.inv_eta_2 * (pdf * (1 - f_i) * (1 - f_o)).unsqueeze(-1)

        # DeltaReflection

        ssw = self.spec_sample_weight()
        prob_specular = ssw * f_i
        prob_diffuse = (1 - f_i) * (1 - ssw)
        prob_diffuse = prob_diffuse / (prob_specular + prob_diffuse)
        pdf = pdf * prob_diffuse

        #spectrum[~active] = 0
        #pdf[~active] = 0
        return spectrum, pdf
예제 #7
0
    def sample(self, it, sampler, active=True):
        cos_theta_i = it.wi[..., 2]

        bs = BSDFSample.zeros_like(it.p)

        active = (cos_theta_i > 0) & active
        if not active.any(): return bs, torch.zeros_like(it.p)

        bs.wo = square_to_cos_hemisphere(
            sampler.sample(it.shape()[:-1] + (2, ), device=it.device()))
        bs.pdf = square_to_cos_hemisphere_pdf(bs.wo)
        bs.eta = 1.0
        bs.sampled_component = 0
        # cast spectrum to same shape as interaction
        cos_theta_o = bs.wo[..., 2]
        active = (cos_theta_o > 0) & active
        R = reflect(it.frame[..., 2], it.wi)
        spectral = (R * bs.wo).sum(dim=-1).clamp(
            min=1e-20).pow(self.min_spec + self.shine.exp())
        spectrum = cos_theta_i.unsqueeze(-1) * self.diffuse/math.pi + \
                   spectral.unsqueeze(-1) * self.specular/math.pi
        spectrum[(~active) | (bs.pdf <= 0), :] = 0
        return bs, spectrum