# Path: nerfactor/util/math.py
# def log10(x):
# def safe_atan2(x, y, eps=1e-6):
#     def grad(dz):
# def safe_acos(x, eps=1e-6):
#     def grad(dy):
# def safe_l2_normalize(x, axis=None, eps=1e-6):
# def safe_cumprod(x, eps=1e-6):
# def inv_transform_sample(val, weights, n_samples, det=False, eps=1e-5):


import numpy as np
import tensorflow as tf
from nerfactor.util import math as mathutil
        Microfacet Models for Refraction through Rough Surfaces [EGSR '07]
    """
    def __init__(self, default_rough=0.3, lambert_only=False, f0=0.91):
        self.default_rough = default_rough
        self.lambert_only = lambert_only
        self.f0 = f0

    def __call__(self, pts2l, pts2c, normal, albedo=None, rough=None):
        """All in the world coordinates.

        Too low roughness is OK in the forward pass, but may be numerically
        unstable in the backward pass

        pts2l: NxLx3
        pts2c: Nx3
        normal: Nx3
        albedo: Nx3
        rough: Nx1
        """
        if albedo is None:
            albedo = tf.ones((tf.shape(pts2c)[0], 3), dtype=tf.float32)
        if rough is None:
            rough = self.default_rough * tf.ones(
                (tf.shape(pts2c)[0], 1), dtype=tf.float32)
        # Normalize directions and normals
        pts2l = mathutil.safe_l2_normalize(pts2l, axis=2)
        pts2c = mathutil.safe_l2_normalize(pts2c, axis=1)
        normal = mathutil.safe_l2_normalize(normal, axis=1)
        # Glossy
        h = pts2l + pts2c[:, None, :] # NxLx3

# Path: nerfactor/util/math.py
# def log10(x):
# def safe_atan2(x, y, eps=1e-6):
#     def grad(dz):
# def safe_acos(x, eps=1e-6):
#     def grad(dy):
# def safe_l2_normalize(x, axis=None, eps=1e-6):
# def safe_cumprod(x, eps=1e-6):
# def inv_transform_sample(val, weights, n_samples, det=False, eps=1e-5):


# Path: brdf/microfacet/microfacet.py
import numpy as np
import tensorflow as tf
from nerfactor.util import math as mathutil

        Microfacet Models for Refraction through Rough Surfaces [EGSR '07]
    """
    def __init__(self, default_rough=0.3, lambert_only=False, f0=0.91):
        self.default_rough = default_rough
        self.lambert_only = lambert_only
        self.f0 = f0

    def __call__(self, pts2l, pts2c, normal, albedo=None, rough=None):
        """All in the world coordinates.

        Too low roughness is OK in the forward pass, but may be numerically
        unstable in the backward pass

        pts2l: NxLx3
        pts2c: Nx3
        normal: Nx3
        albedo: Nx3
        rough: Nx1
        """
        if albedo is None:
            albedo = tf.ones((tf.shape(pts2c)[0], 3), dtype=tf.float32)
        if rough is None:
            rough = self.default_rough * tf.ones(
                (tf.shape(pts2c)[0], 1), dtype=tf.float32)
        # Normalize directions and normals
        pts2l = mathutil.safe_l2_normalize(pts2l, axis=2)
        pts2c = mathutil.safe_l2_normalize(pts2c, axis=1)
        normal = mathutil.safe_l2_normalize(normal, axis=1)
        # Glossy
        h = pts2l + pts2c[:, None, :] # NxLx3

        h = mathutil.safe_l2_normalize(h, axis=2)