Triangle normals and lighting are computed inside the fragment shader for the multi-material painting gizmo.

It results in a six-fold reduction of the amount of data transferred into GPU because there is no need to duplicate vertices for every triangle. Also, normals aren't needed to be transferred to GPU.
This commit is contained in:
Lukáš Hejl 2021-06-25 18:09:53 +02:00
parent a467d0e30e
commit 6194e67e68
4 changed files with 233 additions and 68 deletions

View file

@ -54,22 +54,26 @@ varying float world_pos_z;
varying float world_normal_z;
varying vec3 eye_normal;
uniform bool compute_triangle_normals_in_fs;
void main()
{
// First transform the normal into camera space and normalize the result.
eye_normal = normalize(gl_NormalMatrix * gl_Normal);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
if (!compute_triangle_normals_in_fs) {
// First transform the normal into camera space and normalize the result.
eye_normal = normalize(gl_NormalMatrix * gl_Normal);
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
// Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
// Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
vec3 position = (gl_ModelViewMatrix * gl_Vertex).xyz;
intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
// Perform the same lighting calculation for the 2nd light source (no specular applied).
NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
}
model_pos = gl_Vertex;
// Point in homogenous coordinates.
@ -77,19 +81,17 @@ void main()
world_pos_z = world_pos.z;
// compute deltas for out of print volume detection (world coordinates)
if (print_box.actived)
{
if (print_box.actived) {
delta_box_min = world_pos.xyz - print_box.min;
delta_box_max = world_pos.xyz - print_box.max;
}
else
{
} else {
delta_box_min = ZERO;
delta_box_max = ZERO;
}
// z component of normal vector in world coordinate used for slope shading
world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * gl_Normal)).z : 0.0;
if (!compute_triangle_normals_in_fs)
world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * gl_Normal)).z : 0.0;
gl_Position = ftransform();
// Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded.