<< Photo 3D 戻る RibFilter その4 環境マップ生成 >>

simpleFaceシェーダ

MacRenderManと一緒に動く、VIDI Presenter3Dのサイトで見つけた変顔シェーダ、コンパイルエラーになるところは、書き直した。
prmanで動きました。
以下、ソースです。ありがとうございます。
sphereFace.jpg
sphereFace2.jpg

/* simpleFace5.sl
* copyright(c) 1995 - dsward "at_mark" aol.com
* generate a simple face - two eyes and a mouth
* Parameters (usually in range 0.0 to 1.0)
* Mouth controls -
* mouthLevel - placement of center of the mouth
* mouthWidth - width of mouth
* mouthOffset - vertical offset of edges from center,
* positive=smile, negative=frown
* mouthOpen - mouth opening size
* mouthOpacity - opacity 0=transparent, 1=opaque mouthColor
* Eye controls - a pupil, eye and ring
* eyeLevel - placement of the eyes
* eyeOffset - distance from faceCenter to center of each eye
* eyeRadius - radius of the ring around the eye
* pupilAngle - angle of pupil from center of eye, typically from 0 to pi*2
* pupilOffset - distance between center of pupil and center of eye
* Colors -
* mouthColor, pupilColor, eyeColor, ringColor
* General controls -
* faceCenter - the center for eye and mouth placement
* mapCode - 0 = default
* 1 = invert s
* 2 = invert t
* 3 = invert s and t
* 4 = swap s and t
* 5 = swap s and t, invert s
* 6 = swap s and t, invert t
* 7 = swap s and t, invert s and t
* scaleS - scaling factor for aspect ratio (may be greater than 1.0)
* fuzz - anti-aliasing factor
* Ka, Kd - the usual meanings for matte shading
*
* thanks to the Renderman Repository, the Musgrave site and the Steve May site
* for information and examples of procedural shaders.
*/

surface simpleFace5(
float mouthLevel = 0.35; float mouthOffset = 0.05;
float mouthWidth = 0.5; float mouthOpen = 0.02; float mouthOpacity = 1.0;
float eyeLevel = 0.55; float eyeOffset = 0.09; float eyeRadius = 0.05;
float pupilAngle = 0.0; float pupilOffset = 0.0; float pupilRadius = 0.025;
color mouthColor = color(0, 0, 0);
color pupilColor = color(0, 0, 1);
color eyeColor = color(1, 1, 1);
color ringColor = color(0, 0, 0);
float faceCenter = 0.5;
float mapCode = 0.0;
float scaleS = 2.0;
float fuzz = 0.0025;
float Ka = 1.0;
float Kd = 1.0;
)
{
color inkColor;
float inkOpacity;
point eyeCenter;
point pupilCenter;
float width;
point mouthPosition;
float mouthPoint, mouthEdge;
float halfOpen, halfWidth;
float d, d1,d2;
point p2;
float interceptLower, interceptUpper;
color currentColor, finalColor;
color currentOpacity;
point currentPosition;
normal Nf;
float eyeLoop;
float invertS = 0;
float invertT = 0;
float mapST = mapCode;
width = eyeRadius / 8; /* width of ring around eye */

/* convert current s,t to a point for distance calculations */
if (mapST < 4.0)
{
currentPosition = ((1 - s) * scaleS, 1 - t, 0);
}
else
{
mapST = mapST - 4;
currentPosition = ((1 - t) * scaleS, 1 - s, 0); /* swap s, t mapping */
}

/* invert s, t mappings if specified */
if (mapST == 1) invertS = 1.0;
if (mapST == 2) invertT = 1.0;
if (mapST == 3)
{
invertS = 1.0;
invertT = 1.0;
}

if (invertS != 0)
{
setxcomp(currentPosition, 1 - xcomp(currentPosition));
}

if (invertT != 0)
{
setycomp(currentPosition, 1 - ycomp(currentPosition));
}

currentOpacity = Os;
currentColor = Cs;
inkColor = Cs;
inkOpacity = 0;

/* two eyes */
for (eyeLoop = 0; eyeLoop < 2; eyeLoop = eyeLoop + 1)
{
if (eyeLoop == 0.0)
{
/* left eye */
eyeCenter = ((faceCenter + eyeOffset), eyeLevel, 0);
}
else
{
/* right eye */
eyeCenter = ((faceCenter - eyeOffset), eyeLevel, 0);
}

d = distance(eyeCenter, currentPosition);

/* check for wrap around */
if (d > eyeRadius + width)
{
p2= point (xcomp(eyeCenter) + scaleS, eyeLevel, 0);
d = distance(p2, currentPosition);
if (d <= eyeRadius + width)
eyeCenter = ((xcomp(eyeCenter) + scaleS), eyeLevel, 0);
}

if (d > eyeRadius + width)
{
p2= point (xcomp(eyeCenter) + scaleS, eyeLevel, 0);
d = distance(p2, currentPosition);
if (d <= eyeRadius + width)
eyeCenter = ((xcomp(eyeCenter) - scaleS), eyeLevel, 0);
}

if (d <= eyeRadius + width)
{
if (d <= eyeRadius)
{
pupilCenter = eyeCenter;
setxcomp(pupilCenter, xcomp(pupilCenter) +
(cos(pupilAngle) * pupilOffset));
setycomp(pupilCenter, ycomp(pupilCenter) +
(sin(pupilAngle) * pupilOffset));
d1 = distance(pupilCenter, currentPosition);
if (d1 <= pupilRadius)
{
currentColor = pupilColor;
inkColor = eyeColor;
inkOpacity = smoothstep(pupilRadius - fuzz, pupilRadius, d1);
}
else
{
currentColor = eyeColor;
inkColor = ringColor;
inkOpacity = smoothstep( (eyeRadius - width / 2) - fuzz,
(eyeRadius - width / 2) + fuzz, d) -
smoothstep( (eyeRadius + width / 2) - fuzz,
(eyeRadius + width / 2) + fuzz, d);
}
}
else
{
currentColor = Cs;
inkColor = ringColor;
inkOpacity = smoothstep( (eyeRadius - width / 2) - fuzz,
(eyeRadius - width / 2) + fuzz, d) -
smoothstep( (eyeRadius + width / 2) - fuzz,
(eyeRadius + width / 2) + fuzz, d);
}
}
}

/* mouth */
halfOpen = mouthOpen / 2;
halfWidth = mouthWidth / 2;
mouthPosition = currentPosition;

/* check for wrap-around */
if (faceCenter - halfWidth < 0.0)
{
if (xcomp(mouthPosition) + faceCenter + halfWidth > scaleS)
{
setxcomp(mouthPosition, xcomp(mouthPosition) - scaleS);
}
}

if (faceCenter + halfWidth > scaleS)
{
if (xcomp(mouthPosition) < scaleS - faceCenter)
{
setxcomp(mouthPosition, xcomp(mouthPosition) + scaleS);
}
}

if (xcomp(mouthPosition) >= faceCenter - halfWidth)
{
if (xcomp(mouthPosition) <= faceCenter + halfWidth)
{
mouthPoint = (xcomp(mouthPosition) -
(faceCenter - halfWidth))/ mouthWidth;
mouthEdge = mouthLevel + mouthOffset;
interceptLower = float spline(mouthPoint, mouthEdge, mouthEdge,
mouthLevel - halfOpen, mouthEdge, mouthEdge);
if (ycomp(mouthPosition) >= interceptLower)
{
interceptUpper = float spline(mouthPoint,
mouthEdge, mouthEdge,
mouthLevel + halfOpen,
mouthEdge, mouthEdge);
if (ycomp(mouthPosition) <= interceptUpper)
{
currentColor = Cs;
inkColor = mouthColor;
inkOpacity = smoothstep(interceptLower - fuzz,
interceptLower + fuzz,
ycomp(mouthPosition)) -
smoothstep(interceptUpper - fuzz,
interceptUpper + fuzz,
ycomp(mouthPosition));
currentOpacity = 1.0 -
(inkOpacity * (1.0 - mouthOpacity));
}
}
}
}

finalColor = mix(currentColor, inkColor, inkOpacity);

Nf = faceforward(normalize(N),I);
Ci = Os * finalColor * ( Ka*ambient() + Kd*diffuse(Nf) ) ;
Oi = currentOpacity;
}


こちらはRIBファイルです。
いろいろとパラメータをいじって顔をつくりましょう。

##RenderMan RIB_Structure 1.1
##Scene sphereFace.PICT
##Creator VIDI/Pug, version 0
##CreationDate Tuesday, October 31, 1995 11:20:37 AM
##Frames 1

version 3.03

ShadingRate 0.25
Option "limits" "gridsize" [64]
Option "limits" "bucketsize" [8 16]
PixelSamples 2 2
Hider "hidden" "jitter" [1]
CropWindow [0 1 0 1]
Exposure 1 1
Quantize "rgba" 255 0 255 0
PixelFilter "gaussian" 2 2
ShadingInterpolation "constant"
Format 480 360 1
Display "sphereFace.tif" "file" "rgba"
Projection "perspective" "fov" 35

##CameraOrientation 0.210725 0.27862 -0.648311 -0.28959 0.276892 0.35717
Identity
Rotate 0 0 0 1
Rotate -0.0881412 1 0 0
Rotate 26.4544 0 1 0
Translate -0.210725 -0.27862 0.648311
Rotate 0 0 1 0

Surface "matte"
LightSource "ambientlight" 1 "intensity" [0.1] "lightcolor" [1 1 1]
LightSource "distantlight" 2 "intensity" [1] "lightcolor" [1 1 1] "from" [-1.05748 0.968282 -1.17083] "to" [-0.239685 0.1981 0.534688]

WorldBegin
Sides 2
AttributeBegin
Attribute "identifier" "name" "Design"
Surface "plastic" "Ka" [1] "Kd" [1] "Ks" [0] "roughness" [0.1] "specularcolor" [1 1 1]
AttributeBegin
Attribute "identifier" "shadinggroup" "Sphere 1"
TransformBegin
Transform [1 0 0 0
0 7e-07 1 0
0 -1 7e-07 0
0 0.61 0.61 1]
Surface "simpleFace5"
"float mouthLevel" [0.35]
"float mouthOffset" [0.1]
"float mouthWidth" [0.3]
"float mouthOpen" [0.1]
"float mouthOpacity" [0.5]
"float eyeLevel" [0.55]
"float eyeOffset" [0.09]
"float eyeRadius" [0.05]
"float pupilAngle" [0]
"float pupilOffset" [0]
"float pupilRadius" [0.025]
"color mouthColor" [0 0 0]
"color pupilColor" [0.2 0.4 0.65]
"color eyeColor" [1 0.8 0.8]
"color ringColor" [0 0 0]
"float faceCenter" [0.5]
"float scaleS" [2]
"Ka" [1]
"Kd" [1]
ConcatTransform [1 0 0 0
0 1 0 0
0 0 1 0
0.1 0 0.11 1]
Color [1 0.880062 0.215674]
TransformBegin
Translate -0.5 0 0.23
Sphere [0.39 -0.39 0.39 360]
TransformEnd
TransformEnd
AttributeEnd
AttributeEnd
WorldEnd

面白いですね。感謝しています。
Thank You!!
  • -
  • -

<< Photo 3D 戻る RibFilter その4 環境マップ生成 >>