Пример #1
0
/**
 * gimp_vector3_normalize:
 * @vector: a pointer to a #GimpVector3.
 *
 * Normalizes the @vector so the length of the @vector is 1.0. The nul
 * vector will not be changed.
 **/
void
gimp_vector3_normalize (GimpVector3 *vector)
{
  gdouble len;

  len = gimp_vector3_length (vector);

  if (len != 0.0)
    {
      len = 1.0 / len;
      vector->x *= len;
      vector->y *= len;
      vector->z *= len;
    }
  else
    {
      *vector = gimp_vector3_zero;
    }
}
Пример #2
0
static GimpRGB
phong_shade (GimpVector3 *pos,
	     GimpVector3 *viewpoint,
	     GimpVector3 *normal,
	     GimpVector3 *light,
	     GimpRGB      *diff_col,
	     GimpRGB      *spec_col,
	     gint         type)
{
  GimpRGB       ambientcolor, diffusecolor, specularcolor;
  gdouble      NL, RV, dist;
  GimpVector3  L, NN, V, N;

  /* Compute ambient intensity */
  /* ========================= */

  N = *normal;
  ambientcolor = *diff_col;
  gimp_rgb_multiply (&ambientcolor, mapvals.material.ambient_int);

  /* Compute (N*L) term of Phong's equation */
  /* ====================================== */

  if (type == POINT_LIGHT)
    gimp_vector3_sub (&L, light, pos);
  else
    L = *light;

  dist = gimp_vector3_length (&L);

  if (dist != 0.0)
    gimp_vector3_mul (&L, 1.0 / dist);

  NL = 2.0 * gimp_vector3_inner_product (&N, &L);

  if (NL >= 0.0)
    {
      /* Compute (R*V)^alpha term of Phong's equation */
      /* ============================================ */

      gimp_vector3_sub (&V, viewpoint, pos);
      gimp_vector3_normalize (&V);

      gimp_vector3_mul (&N, NL);
      gimp_vector3_sub (&NN, &N, &L);
      RV = gimp_vector3_inner_product (&NN, &V);
      RV = pow (RV, mapvals.material.highlight);

      /* Compute diffuse and specular intensity contribution */
      /* =================================================== */

      diffusecolor = *diff_col;
      gimp_rgb_multiply (&diffusecolor, mapvals.material.diffuse_ref);
      gimp_rgb_multiply (&diffusecolor, NL);

      specularcolor = *spec_col;
      gimp_rgb_multiply (&specularcolor, mapvals.material.specular_ref);
      gimp_rgb_multiply (&specularcolor, RV);

      gimp_rgb_add (&diffusecolor, &specularcolor);
      gimp_rgb_multiply (&diffusecolor, mapvals.material.diffuse_int);
      gimp_rgb_clamp (&diffusecolor);

      gimp_rgb_add (&ambientcolor, &diffusecolor);
    }

  return ambientcolor;
}
Пример #3
0
static GimpRGB
phong_shade (GimpVector3 *position,
             GimpVector3 *viewpoint,
             GimpVector3 *normal,
             GimpVector3 *lightposition,
             GimpRGB      *diff_col,
             GimpRGB      *light_col,
             LightType    light_type)
{
  GimpRGB       diffuse_color, specular_color;
  gdouble      nl, rv, dist;
  GimpVector3  l, v, n, lnormal, h;

  /* Compute ambient intensity */
  /* ========================= */

  n = *normal;

  /* Compute (N*L) term of Phong's equation */
  /* ====================================== */

  if (light_type == POINT_LIGHT)
    gimp_vector3_sub (&l, lightposition, position);
  else
    {
      l = *lightposition;
      gimp_vector3_normalize (&l);
    }

  dist = gimp_vector3_length (&l);

  if (dist != 0.0)
    gimp_vector3_mul (&l, 1.0 / dist);

  nl = MAX (0., 2.0 * gimp_vector3_inner_product (&n, &l));

  lnormal = l;
  gimp_vector3_normalize (&lnormal);

  if (nl >= 0.0)
    {
      /* Compute (R*V)^alpha term of Phong's equation */
      /* ============================================ */

      gimp_vector3_sub (&v, viewpoint, position);
      gimp_vector3_normalize (&v);

      gimp_vector3_add (&h, &lnormal, &v);
      gimp_vector3_normalize (&h);

      rv = MAX (0.01, gimp_vector3_inner_product (&n, &h));
      rv = pow (rv, mapvals.material.highlight);
      rv *= nl;

      /* Compute diffuse and specular intensity contribution */
      /* =================================================== */

      diffuse_color = *light_col;
      gimp_rgb_multiply (&diffuse_color, mapvals.material.diffuse_int);
      diffuse_color.r *= diff_col->r;
      diffuse_color.g *= diff_col->g;
      diffuse_color.b *= diff_col->b;
      gimp_rgb_multiply (&diffuse_color, nl);

      specular_color = *light_col;
      if (mapvals.material.metallic)  /* for metals, specular color = diffuse color */
        {
          specular_color.r *= diff_col->r;
          specular_color.g *= diff_col->g;
          specular_color.b *= diff_col->b;
        }
      gimp_rgb_multiply (&specular_color, mapvals.material.specular_ref);
      gimp_rgb_multiply (&specular_color, rv);

      gimp_rgb_add (&diffuse_color, &specular_color);
      gimp_rgb_clamp (&diffuse_color);
    }

  gimp_rgb_clamp (&diffuse_color);

  return diffuse_color;
}