
// Copyright 2019 Shlomi Steinberg
// 

#pragma once

#include "glm.hpp"

template <typename T>
auto ndf_ggx_isotropic(T roughness, T dotNH) {
	const auto alpha = roughness * roughness;
	const auto alpha2 = alpha * alpha;
	const auto dotNH2 = dotNH * dotNH;
	const auto denom_ndf = dotNH2 * (alpha2 - T(1)) + T(1);

	return T(1) * alpha2 / (glm::pi<T>() * denom_ndf * denom_ndf);
}

template <typename T>
auto ndf_ggx_ansiotropic(const glm::vec<3,T> &X, const glm::vec<3,T> &Y, const glm::vec<3,T> &h, T roughness_x, T roughness_y, T dotNH) {
	const auto alphax = roughness_x * roughness_x;
	const auto alphay = roughness_y * roughness_y;

	const auto a = alphax * alphay;

	const auto ansix = glm::dot(X, h) / alphax;
	const auto ansiy = glm::dot(Y, h) / alphay;

	const auto denom = ansix * ansix + ansiy * ansiy + dotNH * dotNH;

	return T(1) / (glm::pi<T>() * a * denom * denom);
}
