我正在尝试实现(在C#中)一种图像扰动算法,该算法出现在“纹理和建模- K. Perlin等人”(如果有人拥有它的话,第91页)一书中,它扭曲了一幅图像。以下代码使用Renderman语言:纹理访问
Ct = texture("example.tx", s, t);
被取代
point Psh;
float ss, tt;
Psh = transform("shader", P);
ss = s + 0.2 * snoise(Psh);
tt = t + 0.2 * snoise(Psh+(l.5,6.7,3.4));
Ct = texture("example.tx", ss, tt);把左边的图像转换成右边的图像。

从我未发现的情况来看,我们没有访问坐标$(s,t)\\在$(ss,tt)$ (ss,tt)$中访问轻盈的扰动坐标$(ss,tt)$,并在$(s,t)$位置显示它们,从而创建了一个看起来有点不安的图像。
$snoise(x)$定义为$( noise (x)*2)-1$,将噪声从$$映射到$$,在RenderMan documentation $noise(P)$中,P是点,返回基于某种噪声(最有可能是perlin或格)的值。(http://renderman.pixar.com/resources/current/RenderMan/noiseFunctions.html)
我不明白的是转换函数是怎么做的,它应该将3d点P映射到“着色器”空间,以及如何实现它。另外,我不确定噪音(X)是否返回一个3d点、一个浮点(会更有意义),如果我可以使用Perlin的噪声的一个简单的2d实现来达到相同的效果。
发布于 2015-11-12 13:40:36
正如您所推测的,transform()函数将点从一个协调空间转换到另一个协调空间。(还有vtransform()和ntransform(),分别用于转换方向向量和法向量。)字符串参数指定要转换到的协调空间。
渲染人阴影指南对此有如下看法:
在着色器执行开始时,所有点、向量、法线和矩阵变量都表示在“当前”坐标系中。确切地说,哪个坐标系是“当前”的,是与实现有关的。碰巧"current“是PRMan*的”摄像机“,但您不应该指望这种行为--其他符合RenderMan的呈现器(包括Pixar的未来呈现器)完全有可能使用其他空间(如"world")作为”当前“空间。
接着又举了一个这样的例子。大多数照明计算应该在相机空间进行,但是评估噪声函数应该在物体的协调系统中进行,因为你希望物体在世界空间中移动时,噪声保持不变。
在您的C#实现中,还需要将被阴影的点从相机空间转换到对象的协调系统。也许你已经在计算纹理坐标之前做过这件事了。如果不是,则需要乘以对象的转换矩阵。请记住,此转换点的唯一用途是作为Perlin噪声生成器的输入(如种子)。它设置了噪音变化的区域:世界空间协调。
在RSL中,noise()函数可以返回您喜欢的任何类型:float、color、point或vector。当您将它添加到另一个float (u或v)时,您将在这段代码中得到一个float。实际上,添加到s和t中的两个s调用正在作用于生成一个单一的2D噪声矢量。在您自己的代码中,如果使用2D向量来存储纹理坐标,则可以使用返回2D向量的单个噪声函数在一行代码中获得相同的效果。
如果您对制作一个不错的噪声发生器感兴趣,着色玩具有许多具有不同特性(各向同性或非各向同性、可配置的平滑性和带宽)的不同变体的噪声着色器,值得寻找灵感和实现提示。
https://computergraphics.stackexchange.com/questions/1703
复制相似问题