Adding ViroKit. Needs AWSCore :(
This commit is contained in:
123
mobile/ios/ViroKit.framework/pbr_fsh.glsl
Normal file
123
mobile/ios/ViroKit.framework/pbr_fsh.glsl
Normal 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user