POV-Ray : Newsgroups : povray.pov4.discussion.general : Wood pattern and v4.0. : Re: Wood pattern and v4.0. Server Time
7 Oct 2024 06:27:03 EDT (-0400)
  Re: Wood pattern and v4.0.  
From: Bald Eagle
Date: 19 Sep 2023 20:45:00
Message: <web.650a406c78885d761f9dae3025979125@news.povray.org>
https://www.cs.cornell.edu/~srm/publications/SG05-wood-lr.pdf

https://www.cs.cornell.edu/~srm/publications/SG05-wood.html

has a link to a tar/gz archive with code.   :)



/*
 * woodreflectance.sl -- wood (anisotropic)
 *
 * DESCRIPTION:
 *   Simple wood shader, driven by four textures:
 *    RGB diffuse color
 *    RGB fiber (anisotropic highlight) color
 *    x,y,z of unit vector giving local fiber orientation in local
 *      coordinates
 *    beta, a "roughness" parameter to control width of highlight.
 *   If any of these files is not specified, we fall back on a
 *    uniform parameter. So far, every map has had uniform beta.
 *
 * PARAMETERS:
 *
 *   diffuse_texture: name of file containing 3-channel texture
 *     modulating color across the patch.
 *
 *   fiber_texture: name of file containing 3-channel texture
 *     modulating fiberColor across the patch. This map is divided by
 *     20 because it generally contains values greater than 1, which
 *     would be clamped in an integer pixel format.
 *
 *   axis_texture: name of file containing 3-channel texture
 *     modulating fiberAxis across the patch. Values are mapped
 *     [0:max] -> [-1:1] for each component, since most image file
 *     formats are unsigned.
 *
 *   beta_texture: name of file containing 1-channel texture
 *     modulating beta across the patch.
 *
 *   eta: Index of refraction of surface finish. Used to modulate
 *     highlight and subsurface with varying angle. eta=0 used to
 *     signal absence of overcoat.
 *
 *   color, fiberColor: fallback diffuse and directional colors if
 *     texture is missing
 *
 *   fiberAxis: fallback fiber direction if texture is missing
 *
 *   beta: width of subsurface highlight if texture is missing
 *
 *   roughness: width of surface (white) highlight
 *
 *   Ka, Kd, Ks: normal Renderman coefficients. Ka and Kd modulate the
 *     diffuse component (parameter "color"), and Ks is a fudge factor
 *     on the surface (white) highlight.
 *
 * ANTIALIASING: provided by texture lookup
 *
 * REFERENCE: Stephen R. Marschner, Stephen H. Westin,
 *              Adam Arbree, and Jonathan T. Moon,
 *            "Measuring and Modeling the Appearance of
 *               Finished Wood", SIGGRAPH 2005
 *
 * AUTHOR: written by Stephen H. Westin,
 *                    Cornell University Program of
 *                    Computer Graphics
 *         last modified by $Author: westin $
 *
 * VERSION: $Revision: 1.2 $
 *
 * HISTORY:
 * $Log: woodreflectance.sl,v $
 * Revision 1.2  2005/05/10 20:02:15  westin
 * Modified to use 4 TIFF texture maps rather than a single
 *  10-channel map.
 *
 * Revision 1.1  2005/05/09 21:10:18  westin
 * Working version of shader; used for animation on Proceedings DVD-ROM.
 *
 */

surface
woodreflectance ( float Ka = 1.0,
                        Kd = 1.0,
                        Ks = 1.0;
                  float eta = 1.5;
                  vector fiberAxis = ( 1, 0, 0 );
                  float beta = .1745; /* 10 degrees -> radians */
                  color fiberColor = color ( 1, .6, .4 );
                  string diffuse_texture = "",
                         fiber_texture = "",
                         axis_texture = "",
                         beta_texture = "";
                  float minU = 0, maxU = 1,
                  minV = 0, maxV = 1,
                  roughness = 0.2; )
{

  uniform float sqrt2pi = 2.5066283;

  vector local_z;        /* Surface normal in "world" space */
  vector local_x, local_y; /* Unit vector in "u" and "v" directions */

  normal Nf = faceforward (normalize(N), I); /* Forward-facing normal */
  vector V = normalize(I);                 /* Normalized eye vector */

  color diffuseColor, highlight;
  vector axis;
  float tx_beta;

  vector ssInDir, ssOutDir; /* Light and eye vector, possibly refracted */
  float thInPrime, thOutPrime;
  float halfAngle, diffAngle;
  float fiberFactor, geometryFactor;

  float Kr, Kt;                          /* for output of fresnel() */
  float ssAtten; /* Attenuation from going through the smooth interface twice */

  /* Get local coordinate system in terms of native
     parameters (u,v). We should really use (s,t). */
  local_z = Nf;
  /* Get unit vector in "u" parameter direction */
  local_x = normalize ( dPdu );
  /* Get final local basis vector y perpendicular to x and z. */
  local_y = local_z^local_x;

  /* If there is a clear overcoat, calculate refraction direction and
     attenuation. */
  if ( eta != 1.0 ) {
    vector Rdir;                     /* Dummy */
    fresnel ( V, Nf, 1.0/eta, Kr, Kt, Rdir, ssOutDir );
    ssOutDir = -ssOutDir;
    // Use (1-Kr) rather than Kt, because we are dealing with power,
    // not radiance.
    ssAtten = 1 - Kr;
  } else {
    ssOutDir = -V;
    ssAtten = 1.0;
  }
  normalize(ssOutDir);

  color axisTemp;
  float ourS = minU + u * (maxU - minU),
    ourT = minV + v * (maxV - minV);

  // Get parameters locally from texture maps, if available

  if ( diffuse_texture != "" )
    diffuseColor = color texture ( diffuse_texture, ourS, ourT );
  else
    diffuseColor = Cs;

  if ( fiber_texture != "" )
    highlight = color texture ( fiber_texture, ourS, ourT ) * 20;
  else
    highlight = fiberColor;

  if ( axis_texture != "" ) {
    axisTemp = color texture ( axis_texture, ourS, ourT )
                                   *2 - 1.0;
    /* Transform to local coordinate system */
    axis = comp ( axisTemp, 0 ) * local_x
         - comp ( axisTemp, 1 ) * local_y
         + comp ( axisTemp, 2 ) * local_z;
  }
  else
    axis = comp ( fiberAxis, 0 ) * local_x
         + comp ( fiberAxis, 1 ) * local_y
         + comp ( fiberAxis, 2 ) * local_z;
  normalize(axis);

  if ( beta_texture != "" )
    tx_beta = float texture ( beta_texture, ourS, ourT );
  else
    tx_beta = beta;

  thOutPrime = asin ( ssOutDir.axis );

  /* Calculate anisotropic highlight for each light */
  Ci = 0;
  illuminance ( P, Nf, PI/2 /* Hemisphere */ ) {
    float dummy, ssAttenOut;
    vector Ln = normalize ( L );

    /* Refract at smooth surface */
    if ( eta != 1.0 ) {
      vector Rdir;                           /* dummy */
      fresnel ( -Ln, local_z, 1.0/eta, Kr, Kt, Rdir, ssInDir );
      // Use (1-Kr) rather than Kt, because we are dealing with power,
      // not radiance.
      ssAttenOut = 1 - Kr;
    } else {
      ssInDir = -Ln;
      ssAttenOut = 1.0;
    }

    float ssFactor = max ( 0, -ssInDir.local_z ) * ssAtten*ssAttenOut;
    thInPrime  = asin ( -ssInDir.axis );
    halfAngle = thOutPrime + thInPrime;
    diffAngle = thOutPrime - thInPrime;
    // Compute value of Gaussian at this angle
    fiberFactor = tx_beta * exp ( -pow(halfAngle/tx_beta,2)/2 )
                                      / sqrt2pi;
    float cosIncline = cos(diffAngle / 2);
    geometryFactor = 1 / pow ( cosIncline, 2 );
    fiberFactor *= geometryFactor;
    // Add in diffuse term, attenuated by surface term.
    Ci += Cl * Kd * diffuseColor * ssFactor;
    // Add in fiber highlight, also attenuated.
    Ci += Cl * fiberFactor * highlight * ssFactor;
    /* Second Fresnel call is for strength of surface highlight */
    vector H = normalize ( -V + Ln );
    fresnel ( V, H, 1.0/eta, Kr, Kt );
    // Blinn/Phong highlight with Fresnel attenuation
    Ci += Cl * Ks * Kr
      * pow ( max ( 0, H.local_z ), 1/roughness );
  }

  Ci += Ka * diffuseColor * ambient();
}


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.