Adding ViroKit. Needs AWSCore :(

This commit is contained in:
John Lyon-Smith
2018-03-27 17:46:15 -07:00
parent 2ab15e7dc1
commit 02e06dface
844 changed files with 86921 additions and 21 deletions

View File

@@ -0,0 +1,123 @@
/*
Implementation for the Cook-Torrance specular BRDF. Consists of a Distribution function, a
Fresnel equation, and a Geometry function.
*/
/*
Fresnel equation: describes the ratio of surface reflection at different surface angles.
*/
highp vec3 fresnel_schlick(highp float cosTheta, highp vec3 F0) {
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
}
highp vec3 fresnel_schlick_roughness(highp float cosTheta, highp vec3 F0, highp float roughness) {
return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0);
}
/*
Trowbridge-Reitz GGX normal distribution function: approximates the amount the surface's
microfacets are aligned to the halfway vector influenced by the roughness of the surface.
Primary function approximating microfacets.
*/
highp float distribution_ggx(highp vec3 N, highp vec3 H, highp float roughness) {
highp float a = roughness * roughness;
highp float a2 = a * a;
highp float NdotH = max(dot(N, H), 0.0);
highp float NdotH2 = NdotH * NdotH;
highp float nom = a2;
highp float denom = (NdotH2 * (a2 - 1.0) + 1.0);
denom = PI * denom * denom;
return nom / denom;
}
/*
Schlick GGX geometry function: describes the self-shadowing property of the microfacets. When
a surface is relatively rough the surface's microfacets can overshadow other microfacets, reducing
the light the surface reflects.
*/
highp float geometry_schlick_ggx(highp float NdotV, highp float roughness) {
highp float r = (roughness + 1.0);
highp float k = (r * r) / 8.0;
highp float nom = NdotV;
highp float denom = NdotV * (1.0 - k) + k;
return nom / denom;
}
/*
Smith method combines the obstruction from the view direction with the shadowing from the light
direction vector. Each is computed with Schlick and combined through Smith.
*/
highp float geometry_smith(highp vec3 N, highp vec3 V, highp vec3 L, highp float roughness) {
highp float NdotV = max(dot(N, V), 0.0);
highp float NdotL = max(dot(N, L), 0.0);
highp float ggx2 = geometry_schlick_ggx(NdotV, roughness);
highp float ggx1 = geometry_schlick_ggx(NdotL, roughness);
return ggx1 * ggx2;
}
highp float smooth_distance_attenuation(highp float squared_distance, highp float inv_squared_attenuation_radius) {
highp float factor = squared_distance * inv_squared_attenuation_radius;
highp float smooth_factor = clamp(1.0f - factor * factor, 0.0, 1.0);
return smooth_factor * smooth_factor;
}
highp float compute_distance_attenuation(highp vec3 unnormalized_light_vector, highp float inv_squared_attenuation_radius) {
highp float squared_distance = dot(unnormalized_light_vector, unnormalized_light_vector);
highp float attenuation = 1.0 / (max(squared_distance, 0.01 * 0.01));
attenuation *= smooth_distance_attenuation(squared_distance, inv_squared_attenuation_radius);
return attenuation;
}
highp float compute_attenuation_pbr(const VROLightUniforms light, highp vec3 surface_pos,
out highp vec3 L) {
highp float attenuation = 1.0;
// Directional light
if (light.type == 1) {
L = -normalize(light.direction.xyz);
// For directional light luminous intensity is simply a scalar (as if we're
// using Lambert)
highp float luminous_intensity = light.intensity / (1000.0);
attenuation = luminous_intensity;
}
// Omni Light
else if (light.type == 2) {
highp vec3 unnormalized_light_vector = light.position.xyz - surface_pos;
L = normalize(unnormalized_light_vector);
// Intensity is integrated over the solid angle to get power (luminous flux)
// For a point light this simplifies to I = phi / (4.0 * PI). We use PI
// becuase we don't want spotlight intensity to differ from omni intensity
highp float luminous_intensity = light.intensity / PI;
highp float inverse_square_attenuation_radius = 1.0 / (light.attenuation_end_distance * light.attenuation_end_distance);
attenuation *= compute_distance_attenuation(unnormalized_light_vector, inverse_square_attenuation_radius);
attenuation *= luminous_intensity;
}
// Spotlight
else if (light.type == 3) {
highp vec3 unnormalized_light_vector = light.position.xyz - surface_pos;
L = normalize(unnormalized_light_vector);
// For a spotlight we use a simple equation for intensity since we don't want
// intensity to be stronger for smaller cones given the same power (luminous flux)
highp float luminous_intensity = light.intensity / PI;
highp float inverse_square_attenuation_radius = 1.0 / (light.attenuation_end_distance * light.attenuation_end_distance);
attenuation *= compute_distance_attenuation(unnormalized_light_vector, inverse_square_attenuation_radius);
attenuation *= compute_angle_attenuation(L, light.direction.xyz, light.spot_inner_angle, light.spot_outer_angle);
attenuation *= luminous_intensity;
}
return attenuation;
}