/usr/share/k3d/shaders/k3d_locillum.h is in k3d-data 0.8.0.3-3build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | /************************************************************************
* locillum.h - Functions that compute the light response of locillums.
*
* Author: Larry Gritz (gritzl@acm.org)
*
* Reference:
* _Advanced RenderMan: Creating CGI for Motion Picture_,
* by Anthony A. Apodaca and Larry Gritz, Morgan Kaufmann, 1999.
*
* $Revision: 1.1 $ $Date: 2004/05/19 18:15:19 $
*
************************************************************************/
#ifndef LOCILLUM_H
#define LOCILLUM_H
/*
* Oren and Nayar's generalization of Lambert's reflection model.
* The roughness parameter gives the standard deviation of angle
* orientations of the presumed surface grooves. When roughness=0,
* the model is identical to Lambertian reflection.
*/
color
LocIllumOrenNayar (normal N; vector V; float roughness;)
{
/* Surface roughness coefficients for Oren/Nayar's formula */
float sigma2 = roughness * roughness;
float A = 1 - 0.5 * sigma2 / (sigma2 + 0.33);
float B = 0.45 * sigma2 / (sigma2 + 0.09);
/* Useful precomputed quantities */
float theta_r = acos (V . N); /* Angle between V and N */
vector V_perp_N = normalize(V-N*(V.N)); /* Part of V perpendicular to N */
/* Accumulate incoming radiance from lights in C */
color C = 0;
extern point P;
illuminance (P, N, PI/2) {
/* Must declare extern L & Cl because we're in a function */
extern vector L; extern color Cl;
float nondiff = 0;
lightsource ("__nondiffuse", nondiff);
if (nondiff < 1) {
vector LN = normalize(L);
float cos_theta_i = LN . N;
float cos_phi_diff = V_perp_N . normalize(LN - N*cos_theta_i);
float theta_i = acos (cos_theta_i);
float alpha = max (theta_i, theta_r);
float beta = min (theta_i, theta_r);
C += (1-nondiff) * Cl * cos_theta_i *
(A + B * max(0,cos_phi_diff) * sin(alpha) * tan(beta));
}
}
return C;
}
/*
* Greg Ward Larson's anisotropic specular local illumination model.
* The derivation and formulae can be found in: Ward, Gregory J.
* "Measuring and Modeling Anisotropic Reflection," ACM Computer
* Graphics 26(2) (Proceedings of Siggraph '92), pp. 265-272, July, 1992.
* Notice that compared to the paper, the implementation below appears
* to be missing a factor of 1/pi, and to have an extra L.N term.
* This is not an error! It is because the paper's formula is for the
* BRDF, which is only part of the kernel of the light integral, whereas
* shaders must compute the result of the integral.
*
* Inputs:
* N - unit surface normal
* V - unit viewing direction (from P toward the camera)
* xdir - a unit tangent of the surface defining the reference
* direction for the anisotropy.
* xroughness - the apparent roughness of the surface in xdir.
* yroughness - the roughness for the direction of the surface
* tangent perpendicular to xdir.
*/
color
LocIllumWardAnisotropic (normal N; vector V;
vector xdir; float xroughness, yroughness;)
{
float square (float x) { return x*x; }
float cos_theta_r = clamp (N.V, 0.0001, 1);
vector X = xdir / xroughness;
vector Y = (N ^ xdir) / yroughness;
color C = 0;
extern point P;
illuminance (P, N, PI/2) {
/* Must declare extern L & Cl because we're in a function */
extern vector L; extern color Cl;
float nonspec = 0;
lightsource ("__nonspecular", nonspec);
if (nonspec < 1) {
vector LN = normalize (L);
float cos_theta_i = LN . N;
if (cos_theta_i > 0.0) {
vector H = normalize (V + LN);
float rho = exp (-2 * (square(X.H) + square(Y.H)) / (1 + H.N))
/ sqrt (cos_theta_i * cos_theta_r);
C += Cl * ((1-nonspec) * cos_theta_i * rho);
}
}
}
return C / (4 * xroughness * yroughness);
}
/*
* LocIllumGlossy - a possible replacement for specular(), with a
* more uniformly bright core and a sharper falloff. It's a nice
* specular function to use for something made of glass or liquid.
* Inputs:
* roughness - related to the size of the highlight, larger is bigger
* sharpness - 1 is infinitely sharp, 0 is very dull
*/
color LocIllumGlossy ( normal N; vector V;
float roughness, sharpness; )
{
color C = 0;
float w = .18 * (1-sharpness);
extern point P;
illuminance (P, N, PI/2) {
/* Must declare extern L & Cl because we're in a function */
extern vector L; extern color Cl;
float nonspec = 0;
lightsource ("__nonspecular", nonspec);
if (nonspec < 1) {
vector H = normalize(normalize(L)+V);
C += Cl * ((1-nonspec) *
smoothstep (.72-w, .72+w,
pow(max(0,N.H), 1/roughness)));
}
}
return C;
}
#endif /* defined(LOCILLUM_H) */
|