<commit_before>
#include "constants.glsl"
#include "geometry.glsl"

/** Fresnel approximation.
	\param F0 fresnel based coefficient
	\param VdotH angle between the half and view directions
	\return the Fresnel term
*/
vec3 F(vec3 F0, float VdotH){
	float approx = exp2((-5.55473 * VdotH - 6.98316) * VdotH);
	return F0 + approx * (1.0 - F0);
}

/** GGX Distribution term.
	\param NdotH angle between the half and normal directions
	\param alpha the roughness squared
	\return the distribution term
*/
float D(float NdotH, float alpha){
	float halfDenum = NdotH * NdotH * (alpha * alpha - 1.0) + 1.0;
	float halfTerm = alpha / max(0.0001, halfDenum);
	return halfTerm * halfTerm * INV_M_PI;
}

/** Visibility term of GGX BRDF, V=G/(n.v)(n.l)
\param NdotL dot product of the light direction with the surface normal
\param NdotV dot product of the view direction with the surface normal
\param alpha squared roughness
\return the value of V
*/
float V(float NdotL, float NdotV, float alpha){
	// Correct version.
	float alpha2 = alpha * alpha;
	float visL = NdotV * sqrt((-NdotL * alpha2 + NdotL) * NdotL + alpha2);
	float visV = NdotL * sqrt((-NdotV * alpha2 + NdotV) * NdotV + alpha2);
    return 0.5 / max(0.0001, visV + visL);
}

/** Linearized visibility term of GGX BRDF, V=G/(n.v)(n.l)
\param NdotL dot product of the light direction with the surface normal
\param NdotV dot product of the view direction with the surface normal
\param alpha squared roughness
\return the value of V
*/
float Vfast(float NdotL, float NdotV, float alpha){
    float visV = NdotL * (NdotV * (1.0 - alpha) + alpha);
    float visL = NdotV * (NdotL * (1.0 - alpha) + alpha);
	return 0.5 / max(0.0001, visV + visL);
}

/** Evaluate the GGX BRDF for a given normal, view direction and
	material parameters.
	\param n the surface normal
	\param v the view direction
	\param l the light direction
	\param F0 the Fresnel coefficient
	\param roughness the surface roughness
	\return the BRDF value
*/
vec3 ggx(vec3 n, vec3 v, vec3 l, vec3 F0, float roughness){
	// Compute half-vector.
	vec3 h = normalize(v+l);
	// Compute all needed dot products.
	float NdotL = clamp(dot(n,l), 0.0, 1.0);
	float NdotV = clamp(dot(n,v), 0.0, 1.0);
	float NdotH = clamp(dot(n,h), 0.0, 1.0);
	float VdotH = clamp(dot(v,h), 0.0, 1.0);
	float alpha = max(0.0001, roughness*roughness);

	return D(NdotH, alpha) * Vfast(NdotL, NdotV, alpha) * F(F0, VdotH);
}

/** Return the (pre-convolved) radiance for a given normal, view direction and
	material parameters. Directions are in world space.
	\param n the surface normal (world space)
	\param v the view direction (world space)
	\param p the surface position (world space)
	\param roughness the surface roughness
	\param cubeMap the environment map texture
	\param cubePos position of the cubemap
	\param cubeCenter center of the parallax correction box
	\param cubeExtent half size of the parallax correction box (infinity if < 0.0)
	\param cubeRotCosSin precomputed cos/sin of the parallax correction box orientation
	\param upLod the maximal mip level to fetch
	\return the radiance value
	*/
vec3 radiance(vec3 n, vec3 v, vec3 p, float roughness, samplerCube cubeMap, vec3 cubePos, vec3 cubeCenter, vec3 cubeExtent, vec2 cubeRotCosSin, float upLod){
	// Reflect the ray
	vec3 r = -reflect(v,n);

	// Compute the direction to fetch in the cubemap.
	if(cubeExtent.x > 0.0){
		// We go from world to box frame.
		vec3 rBox = rotateY(r, cubeRotCosSin);
		vec3 pBox = rotateY(p - cubeCenter, cubeRotCosSin);
		vec2 roots;
		if(intersectBox(pBox, rBox, cubeExtent, roots)){
			float dist = max(roots.x, roots.y);
			vec3 hitPos = p + dist * r;
			r = (hitPos - cubePos);
		}
	}
	vec3 specularColor = textureLod(cubeMap, r, upLod * roughness).rgb;
	return specularColor;
}
<commit_msg>PBR Shaders: improve reflection fetch when outside the parallax proxy.<commit_after>
#include "constants.glsl"
#include "geometry.glsl"

/** Fresnel approximation.
	\param F0 fresnel based coefficient
	\param VdotH angle between the half and view directions
	\return the Fresnel term
*/
vec3 F(vec3 F0, float VdotH){
	float approx = exp2((-5.55473 * VdotH - 6.98316) * VdotH);
	return F0 + approx * (1.0 - F0);
}

/** GGX Distribution term.
	\param NdotH angle between the half and normal directions
	\param alpha the roughness squared
	\return the distribution term
*/
float D(float NdotH, float alpha){
	float halfDenum = NdotH * NdotH * (alpha * alpha - 1.0) + 1.0;
	float halfTerm = alpha / max(0.0001, halfDenum);
	return halfTerm * halfTerm * INV_M_PI;
}

/** Visibility term of GGX BRDF, V=G/(n.v)(n.l)
\param NdotL dot product of the light direction with the surface normal
\param NdotV dot product of the view direction with the surface normal
\param alpha squared roughness
\return the value of V
*/
float V(float NdotL, float NdotV, float alpha){
	// Correct version.
	float alpha2 = alpha * alpha;
	float visL = NdotV * sqrt((-NdotL * alpha2 + NdotL) * NdotL + alpha2);
	float visV = NdotL * sqrt((-NdotV * alpha2 + NdotV) * NdotV + alpha2);
    return 0.5 / max(0.0001, visV + visL);
}

/** Linearized visibility term of GGX BRDF, V=G/(n.v)(n.l)
\param NdotL dot product of the light direction with the surface normal
\param NdotV dot product of the view direction with the surface normal
\param alpha squared roughness
\return the value of V
*/
float Vfast(float NdotL, float NdotV, float alpha){
    float visV = NdotL * (NdotV * (1.0 - alpha) + alpha);
    float visL = NdotV * (NdotL * (1.0 - alpha) + alpha);
	return 0.5 / max(0.0001, visV + visL);
}

/** Evaluate the GGX BRDF for a given normal, view direction and
	material parameters.
	\param n the surface normal
	\param v the view direction
	\param l the light direction
	\param F0 the Fresnel coefficient
	\param roughness the surface roughness
	\return the BRDF value
*/
vec3 ggx(vec3 n, vec3 v, vec3 l, vec3 F0, float roughness){
	// Compute half-vector.
	vec3 h = normalize(v+l);
	// Compute all needed dot products.
	float NdotL = clamp(dot(n,l), 0.0, 1.0);
	float NdotV = clamp(dot(n,v), 0.0, 1.0);
	float NdotH = clamp(dot(n,h), 0.0, 1.0);
	float VdotH = clamp(dot(v,h), 0.0, 1.0);
	float alpha = max(0.0001, roughness*roughness);

	return D(NdotH, alpha) * Vfast(NdotL, NdotV, alpha) * F(F0, VdotH);
}

/** Return the (pre-convolved) radiance for a given normal, view direction and
	material parameters. Directions are in world space.
	\param n the surface normal (world space)
	\param v the view direction (world space)
	\param p the surface position (world space)
	\param roughness the surface roughness
	\param cubeMap the environment map texture
	\param cubePos position of the cubemap
	\param cubeCenter center of the parallax correction box
	\param cubeExtent half size of the parallax correction box (infinity if < 0.0)
	\param cubeRotCosSin precomputed cos/sin of the parallax correction box orientation
	\param upLod the maximal mip level to fetch
	\return the radiance value
	*/
vec3 radiance(vec3 n, vec3 v, vec3 p, float roughness, samplerCube cubeMap, vec3 cubePos, vec3 cubeCenter, vec3 cubeExtent, vec2 cubeRotCosSin, float upLod){
	// Reflect the ray
	vec3 r = -reflect(v,n);

	// Compute the direction to fetch in the cubemap.
	if(cubeExtent.x > 0.0){
		// We go from world to box frame.
		vec3 rBox = rotateY(r, cubeRotCosSin);
		vec3 pBox = rotateY(p - cubeCenter, cubeRotCosSin);
		vec2 roots;
		intersectBox(pBox, rBox, cubeExtent, roots);
		float dist = max(roots.x, roots.y);
		vec3 hitPos = p + dist * r;
		r = (hitPos - cubePos);
	}
	vec3 specularColor = textureLod(cubeMap, r, upLod * roughness).rgb;
	return specularColor;
}

{'fraction_non_alphanumeric': 0.1061401207032275, 'fraction_numerical': 0.026502230385725533, 'mean_word_length': 3.7613991255465336, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6606726', 'n_tokens_mistral': 2850, 'n_tokens_neox': 2645, 'n_words': 999}