Python 中的花卉矩阵组合





3.00/5 (2投票s)
使用 RenderMan 场景描述 (rib) 协议进行脚本编写的基础。
引言
本作业演示了使用 RenderMan
场景描述(rib)协议进行脚本编写的基础。通过创建在 3D 空间中进行转换的基本几何体,介绍了 XYZ 坐标系的基本原理。初步渲染使用了基本的着色,以便更容易地看到几何体。
图 1 是我作为作业参考的示例图片,并试图在 RenderMan
中匹配该图片。为了完成这项作业,我使用了以下语言和工具:
- Cutter(一个适用于各种脚本语言的便捷文本编辑器,与许多
RenderMan
兼容的渲染器(例如PRMan
、3Delight
等)以及 Maya 等建模软件包紧密集成。作者 Malcom Kesson,来自 SCAD 的一位了不起的人,是该工具的作者,也是我正在遵循的这些作业格式的制定者。这是他的链接:www.fundza.com & http://www.sfdm.scad.edu/faculty/mkesson/。 - Python(一种功能极其强大的语言,由于其简洁性、可移植性和更高级的功能,正迅速成为大多数 CG 应用程序的首选脚本语言)。从这里下载:https://pythonlang.cn/
- 3Delight(一款惊人的
RenderMan
兼容渲染器,是您无需花费任何成本即可体验RenderMan
的最佳选择!)。从这里获取:http://www.3delight.com/en/
对于这项作业,我将任务分为不同的阶段。以下是各阶段的详细信息和代码片段。
第 1 步 - 向日葵的内部图案
仔细观察参考图像中的向日葵(向日葵有许多变种,所以我只坚持参考图像中的那种),可以看到这朵向日葵在种子的内部排列方式上表现出非常独特的图案。Google 立即为我提供了更多信息。
因此,第一个任务是确定向日葵的内部图案,它遵循 Matlab 示例中显示的特定图案,该示例是从向日葵的 Wikipedia 条目下载的。它使用以下数学公式来形成这种形状:
// n=1:500;
// r=sqrt(n);
// t=137.5*pi/180*n;
// plot(r.*cos(t),r.*sin(t),'o')
我使用 Cutter 来原型化 rib,然后使用 Python 来运行循环,我使用了 Cone 原语(而不是在上面的 Matlab 示例代码中绘制一个 'o')来制作向日葵的种子图案。以下是代码片段和渲染视图:
// While(n < div):
// p=0.1
// r=0.25*sqrt(n)
// a=137.5*pi/180*n
// X=r*cos(a)
// Y=r*sin(a)
// Z=6-(N/div)*6
// Riattributebegin()
// Riscale(a/div,a/div,a/div)
// Ritranslate(x,y,z)
// RiColor((0.63921568627450980392156862745098,
// 0.50980392156862745098039215686275,
// 0.13725490196078431372549019607843))
// RiCone(0.2,0.2,360)
// Riattributeend()
// n=n+1
| |
上面的 Matlab 代码只能在 2D(XY 平面)上绘制种子图案,但实际上,种子是排列在球体上的,而不是平面上的。可以使用真正的球坐标来确定种子在球体上的分布,但我作弊了,只是简单地使用了球体半径(在本例中为零)与该球体原点之间的线性插值。插值因子是循环中逐渐增加的半径。这样,当 Matlab 示例代码通过计算循环迭代器的平方根来不断增加半径时,我一直在逐渐减小种子坐标的 z
值,直到零,以提供一种“凸起”的形状,其中种子在中心靠近相机,并在移向边界时逐渐向深度推移。在计算出适当的 x、y 和 z 坐标值后,还使用线性插值计算了一个缩放因子,以产生随着向边界移动而逐渐放大的锥体(种子)效果。最后,所有这些值都通过 rib 的适当的平移和缩放命令在绘制锥体原语之前应用。
第 2 步 - 随机化圆形锥体
接下来是种子中间的圆环。我需要使锥体排列成一个具有一定宽度的圆形环,其中锥体(种子)密度更高,并且位置随机,不遵循任何严格的模式。为此,我使用了 Python 的随机函数来获取随机值,将它们添加到我使用 sin/cos 函数计算的极坐标中,并在 rib 文件中使用 Python 在 xy 平面上绘制锥体。
添加一个包含相关代码和图片的表格。
图 4 是随机格式的锥体排列,而在图 5 中,您可以看到图 3 和图 4 的组合。为了制作锥体的随机图案,我首先在绘制内部种子图案时获得了退出循环时的最大半径值,然后运行一个循环直到中间圆环的半径,并通过使用 Python 的随机函数和一些操作,获得我期望范围的值,然后平移锥体并将它们绘制出来以形成圆环。
第 3 步 - 圆形上的随机曲线
如果您仔细观察向日葵的内侧,您会发现它有一些毛发状的东西,大小随机,排列方式也随机,为了实现这种效果,我使用了曲线(Curves)。在图 6 中,您可以看到我用来制作向日葵第三个圆环的曲线样本,该圆环大小和位置都是随机的。图 7 是图 5 和图 6 的组合。要制作图 5 上的最外层圆环,我首先取图 5 的最大半径值,并在此基础上增加一些值,然后为我的基于曲线的圆环定义另一个半径。要制作曲线,我需要一个数组参数。我的任务 图 7 图 6 不是制作曲线,而是使其大小和位置随机。为了完成这项任务,我首先创建了在所需值之间进行随机化的函数,并在运行时创建数组,这样绘制的每条曲线都是随机的,并且彼此之间会发生变化。您可以在作业的源代码中找到名为 rf()
的函数。
第 4 步 - 向日葵的花瓣
在这一步,我需要制作向日葵的花瓣。最初,我使用 Renderman
的细分曲面(subdivision surfaces)来制作花瓣,然后旋转花瓣以产生花瓣效果,并使用缩放来调整花瓣大小。我制作了三层不同的花瓣,每一层都沿着 Z 轴缩进并进行一些旋转,以产生随机花瓣的外观。但后来我在 MAYA 中制作了三个不同的花瓣,然后使用这些 图 9 图 8 花瓣使用 Read Archive 功能来制作向日葵。最初,我使用细分曲面在 Renderman
中制作花瓣,并旋转图 7 上的花瓣以产生随机排列的花瓣外观。我缩放了花瓣及其颜色。为了产生分层花瓣的外观,我将每层花瓣圆沿正 Z 轴平移,然后我在 MAYA 中制作了三个不同的花瓣,并用它们代替了我在 Renderman
中使用细分曲面制作的花瓣。花瓣的选择标准是在运行时使用名为 randomizebound(a,b)
的函数来确定的。我创建了这个函数来获取我期望范围内的值,您可以在我使用 Python 制作的作业源代码中找到它。这个函数接受两个参数,第一个是下限,第二个是上限,并返回介于这两个边界之间的值(不包括边界)。
下面是 Python 代码:
from math import sin, cos, pi ,sqrt,tan
from cgkit.ri import *
import random
import os
#############################Initial Variables#######################
a = 0.0
r = 2.0
n = 0.0
div=500
numdiv=100
######################################################################
#####################Random Generation Function ######################
def rf():
v=-2+random.random()*4
return v
#######################################################################
####################Petal model using SubDiv ##########################
def subdivmes():
RiScale(0.10,0.10,0.10)
RiSubdivisionMesh("catmull-clark",[8],[0,1,2,3,4,5,6,7],
["interpolateboundary"],[0,0],[],[],"P",
[0, 1, -1, -1, 2, -1, -1, 4, -1, -1, 6, -1, 0, 10, -1, 1, 6, -1, 1, 4, -1, 1, 2, -1])
# RiReadArchive("D:/PythonExample/petal.rib")
########################################################################
def petal():
size=randomizebound(32,40)
RiScale(size,size,0)
RiColor((0.85882352941176470588235294117647,
0.85882352941176470588235294117647,0.14509803921568627450980392156863))
# RiReadArchive("D:/PythonExample/petal.rib")
def petal1():
size=randomizebound(32,40)
RiScale(size,size,0)
RiColor((0.92549019607843137254901960784314,
0.90588235294117647058823529411765,0.16078431372549019607843137254902))
# RiReadArchive("D:/PythonExample/petal1.rib")
def petal2():
size=randomizebound(8,10)
RiScale(size,size,0)
RiColor((0.89411764705882352941176470588235,
0.77254901960784313725490196078431,0.14509803921568627450980392156863))
#RiReadArchive("D:/PythonExample/petal3.rib")
####################Randomize Scaling for Petal########################
def scale():
size=(random.random()*10)/2
return size
#######################################################################
####################### Random Function with Boundries#################
def randomizebound(lowerbound, uperbound):
return lowerbound+(random.random())*(uperbound-lowerbound)
#######################################################################
RiBegin("D:\\PythonExample\\sampleflower.rib")
RiDisplay("circle.tiff", "framebuffer", "rgb")
RiProjection("perspective", "fov", 110)
RiTranslate(0, 0, 50)
###RiRotate(40,0,1,0 )
###RiRotate(45,0,0,1)
#RiRotate(-90,1,0,0)
RiWorldBegin()
###################### InternalRing Of SunFlower ######################
y=2
while(n < div):
p=0.1
r=0.25*sqrt(n)
a=137.5*pi/180*n
x=r*cos(a)
y=r*sin(a)
z=6-(n/div)*6
RiAttributeBegin()
RiScale(a/div,a/div,a/div)
RiTranslate(x,y,z)
RiColor((0.63921568627450980392156862745098,
0.50980392156862745098039215686275,0.13725490196078431372549019607843))
RiCone(0.2,0.2,360)
RiAttributeEnd()
n=n+1
################### End Internal Ring OF SunFlower #####################
##################### MiddleRing of Sunflower ##########################
rstart=0.25*sqrt(div)+1
i=0.0
while(i<10):
r=rstart+((i/10)*2)
n=0.0
a=0.0
while(n<20):
a=(n/20*360.0)*pi/180.0
x=r*cos(a)
y=r*sin(a)
RiAttributeBegin()
RiScale(2,2,2)
xrand=-0.75+(random.random()*2)
yrand=-0.75+(random.random()*2)
RiTranslate(x+xrand, y+yrand, 0)
RiColor((0.68235294117647058823529411764706,
0.48235294117647058823529411764706,0.15686274509803921568627450980392))
RiCone(0.2,0.2,360)
RiAttributeEnd()
n=n+1
i=i+1
################## End MiddleRing of SunFlower##########################
################ OuterMost Ring of SunFlower ###########################
n=0.0
r=r+11
while(n < div):
a=(n/div*360.0)*pi/180.0
x=r*cos(a)
y=r*sin(a)
## y=2+(sin((90-(n/div)*90)*(pi/180))*2)
RiAttributeBegin()
RiTranslate(x+rf(),y+rf(),0)
matrix = [[-6, 0 ,0],
[-3, rf(),0],
[0, rf(),0],
[3, rf(),0],
[6, rf(),0]]
#print matrix
RiAttributeBegin()
RiScale(0.20,0.20,0)
RiColor((0.75686274509803921568627450980392,0.51764705882352941176470588235294,
0.15294117647058823529411764705882))
RiRotate(n/div*360,0,0,1)
RiBasis("bezier", 3, "bezier", 3)
RiCurves("cubic", [5], "nonperiodic", "P", matrix, "constantwidth",0.8)
RiAttributeEnd()
RiAttributeEnd()
n=n+1
################ END OuterMost Ring of SunFlower ########################
################ First Ring of Petals ###################################
n=0.0
r=r
numdiv=20
while(n < numdiv):
a=(n/numdiv*360.0)*pi/180.0
x=r*cos(a)
y=r*sin(a)
# size=randomizebound(30,35)
RiAttributeBegin()
angle=(n/numdiv)*360.0
RiTranslate(x,y,-1.5)
RiRotate(angle,0,0,1)
# RiScale(size,size,0)
#RiColor((0.89411764705882352941176470588235,0.77254901960784313725490196078431,
0.14509803921568627450980392156863))
RiRotate(10,1,0,0)
subdivmes()
#RiReadArchive("D:/PythonExample/1petal.rib")
#petal()
RiAttributeEnd()
n=n+1
################# End First Ring Of Petals#################################
################ Second Ring of Petals ####################################
n=0.0
r=r
print numdiv
while(n < numdiv):
a=(n/numdiv*360.0)*pi/180.0
x=r*cos(a)
y=r*sin(a)
size=randomizebound(32,40)
RiAttributeBegin()
angle=(n/numdiv)*360.0
#RiColor((0.92549019607843137254901960784314,0.90588235294117647058823529411765,
0.16078431372549019607843137254902))
RiTranslate(x,y+rf()*2,-1)
RiRotate(angle,0,0,1)
RiRotate(10,0,0,1)
RiScale(size,size,0)
RiRotate(12,1,0,0)
#subdivmes()
#petal()
RiAttributeEnd()
n=n+1
################### End Second Ring Of Petals ############################
#################### Third Ring of Petals ################################
n=0.0
r=r
print numdiv
while(n < numdiv):
a=(n/numdiv*360.0)*pi/180.0
x=r*cos(a)
y=r*sin(a)
# size=randomizebound(3,8)
number=randomizebound(0,3)
print number
RiAttributeBegin()
angle=(n/numdiv)*360.0
# RiColor((0.85882352941176470588235294117647,0.85882352941176470588235294117647,
0.14509803921568627450980392156863))
RiTranslate(x,y+rf()*2,-0.5)
RiRotate(angle,0,0,1)
RiRotate(15,1,0,0)
# RiScale(size,size,0)
#subdivmes()
if(number>0) and (number <1):
petal()
subdivmes()
if(number>1) and (number <2):
# print "condition2"
petal()
subdivmes()
if (number >2) and (number <3):
petal2()
subdivmes()
# RiReadArchive("D:/PythonExample/petal3.rib")
# petal()
RiAttributeEnd()
n=n+1
################### End Third Ring Of Petals #############################
RiWorldEnd()
RiEnd()
os.system("renderdl D:/PythonExample/sampleflower.rib")