Arnold(C4DToA)阿诺德渲染教程(71) – Vector Displacement 向量置换

Arnold 允许着色器置换多边形网格节点中的顶点。这些顶点按照着色器所返回向量的方向和幅值进行置换。

在此示例着色器中,我们根据噪波函数计算非线性置换。与传统噪波置换着色器一样,该着色器可以沿曲面法线进行置换,但也可以选择采用置换的峰值和谷值。

Arnold(C4DToA)阿诺德渲染教程(71) – Vector Displacement 向量置换 - R站|学习使我快乐! - 1

这可以通过计算噪波函数及其在两个曲面导数的方向上的增量来完成。该增量将确定这些导数因置换而偏转的幅度。通过反复偏转导数,我们创建了从曲面走弧线的非线性置换。这相当于置换曲面、计算法线,然后重复置换。

Arnold(C4DToA)阿诺德渲染教程(71) – Vector Displacement 向量置换 - R站|学习使我快乐! - 2

type abs_perlin
freq 0.025
amplitude 80
Arnold(C4DToA)阿诺德渲染教程(71) – Vector Displacement 向量置换 - R站|学习使我快乐! - 3
type recursive
freq 0.025
amplitude 40
bloom 3
Arnold(C4DToA)阿诺德渲染教程(71) – Vector Displacement 向量置换 - R站|学习使我快乐! - 4
type abs_recursive
freq 0.025
amplitude 40
bloom 3
Arnold(C4DToA)阿诺德渲染教程(71) – Vector Displacement 向量置换 - R站|学习使我快乐! - 5
type abs_perlin
freq 0.025
amplitude -40
bloom -4

源代码:

/*
 * nonlinear noise displacement shader
 */
#include 
#include 
 
enum
{
   p_octaves,
   p_freq,
   p_amplitude,
   p_bloom,
   p_type
};
 
AI_SHADER_NODE_EXPORT_METHODS(NonlinNzMethods);
 
#define ENUM_SCALAR_TYPES { "perlin", "abs_perlin", "recursive", "abs_recursive", NULL };
#define PERLIN        0
#define ABS_PERLIN    1
#define RECURSIVE     2
#define ABS_RECURSIVE 3
const char *types_enum[] = ENUM_SCALAR_TYPES;
 
node_parameters
{
   AiParameterInt ("octaves"  , 3);
   AiParameterFlt ("freq"     , 1);
   AiParameterFlt ("amplitude", 1);
   AiParameterFlt ("bloom"    , 1);  
   AiParameterEnum("type"     , PERLIN, types_enum);
}
 
float scalarfunc(AtVector P, int type, int octaves)
{
   float doubler = 1;
   float NzAccum = 0;
 
   switch (type)
   {
      case PERLIN:
         return AiPerlin3(P);
      case ABS_PERLIN:
         return fabs(AiPerlin3(P));
      case RECURSIVE:
         for (int i = 0; i < octaves; i++) {
            NzAccum += AiPerlin3(P*doubler) / doubler;
            doubler *= 2;
         }
         return NzAccum;
      case ABS_RECURSIVE:
         for (int i = 0; i < octaves; i++) { NzAccum += fabs(AiPerlin3(P*doubler)) / doubler; doubler *= 2; } return NzAccum; } return AiPerlin3(P); } shader_evaluate { AtVector Ploc, Uloc, Vloc; // noise sample location, and over in U and V locations float Np, Nu, Nv; // noise at P, noise at location over in U and V float Udelt, Vdelt; // delta in the noise over in U and V float delta = .01; // distance delta for noise samples int octaves = AiShaderEvalParamInt(p_octaves); float freq = AiShaderEvalParamFlt(p_freq); float amplitude = AiShaderEvalParamFlt(p_amplitude); float bloom = AiShaderEvalParamFlt(p_bloom); int type = AiShaderEvalParamInt(p_type); AtVector U, V; if (sg->dPdu != AI_V3_ZERO && sg->dPdv != AI_V3_ZERO)
   {
      // tangents available, use them
      U = sg->dPdu;
      V = sg->dPdv;
   }
   else
   {
      // no tangents given, compute a pair
      AiV3BuildLocalFramePolar(U, V, sg->N);
   }
 
   if (type > ABS_PERLIN)
   {
      // adjust delta to highest frequency in recursive noise
      delta *= pow(.5,  octaves) * 2;
   }
   Ploc = sg->Po * freq;
   Uloc = Ploc + U * delta;
   Vloc = Ploc + V * delta;
 
   // noise sampled at P, and over in U and V
   Np = scalarfunc(Ploc, type, octaves);
   Nu = scalarfunc(Uloc, type, octaves);
   Nv = scalarfunc(Vloc, type, octaves);
 
   Udelt = (Nu - Np) * bloom;
   Vdelt = (Nv - Np) * bloom;
 
   AtVector Pstepped = sg->P;  
   int steps = 10;
   float stepscale = amplitude / steps;
 
   for (int i = 0; i < steps; i++) { // stepdir is the cross product of the derivatives AtVector stepdir = AiV3Cross(U,V); // deflect the derivatives U = AiV3Normalize(U + (stepdir * Udelt * stepscale)); V = AiV3Normalize(V + (stepdir * Vdelt * stepscale)); Pstepped += stepdir * Np * stepscale; } sg->out.VEC() = Pstepped - sg->P;
}
 
node_initialize
{
}
 
node_update
{
}
 
node_finish
{
}
 
node_loader
{
   if (i > 0) return false;
    
   node->methods      = NonlinNzMethods;
   node->output_type  = AI_TYPE_VECTOR;
   node->name         = "nonlinear_noise";
   node->node_type    = AI_NODE_SHADER;
   strcpy(node->version, AI_VERSION);
   return true;
}

以下 .ass 文件使用此着色器:

options
{
 AA_samples 3
 xres 640
 yres 480
 GI_diffuse_depth 1
 GI_diffuse_samples 3
}
 
plane
{
 name myplane
 point 0 -8 0
 normal 0 1 0
 shader groundshader
}
 
polymesh
{
 name mysph
 nsides 6 1 UINT 4 4 4 4 4 4
 vidxs 24 1 UINT
  0 4 5 1 1 5 6 2 2 6 7 3 3 7 4 0 3 0 1 2 4 7 6 5
 vlist 8 1 b64VECTOR
  AAB6wwAAAAAAAHrDAAB6QwAAAAAAAHrDAAB6QwAAAAAAAHpDAAB6wwAAAAAAAHpDAAB6wwAA+kMAAHrDAAB6QwAA+kMAAHrDAAB6QwAA+kMAAHpDAAB6wwAA+kMAAHpD
 smoothing on
 subdiv_type catclark
 subdiv_iterations 7
 disp_map sphere_disp
 disp_padding 50
 matrix
  0.94693 0 0.321439 0
  0 1 0 0
  -0.321439 0 0.94693 0
  0 0 0 1
 shader sphere_surf
}
 
standard_surface
{
 name sphere_surf
 base 0.3
 base_color 0.8 0.8 1
 specular 1
 specular_color 0.8 0.8 1
 specular_roughness 0.3
 subsurface 0.5
 subsurface_color 1 0.05 0.2
 subsurface_radius 80 80 80
}
 
nonlinear_noise
{
 name sphere_disp
 type perlin
 freq 0.025
 amplitude 80
 bloom 1
}
 
standard_surface
{
 name groundshader
 base 1
 base_color 0.4 0.4 0.4
 specular 0
}
 
persp_camera
{
 name mycamera
 fov 11
 position 3677.0129 1039.1904 597.0592
 look_at 0 250 0
 up 0 1 0
}
 
point_light
{
 name key
 position -6000 10000 6000
 radius 400
 color 1 0.7 0.2
 intensity 1
 exposure 28
}
 
skydome_light
{
 name mysky
 color 0.7 0.8 0.9
 intensity 0.9
}
Arnold(C4DtoA)

Arnold(C4DToA)阿诺德渲染教程(70) – Displacement 置换

2018-1-10 14:02:50

Arnold(C4DtoA)

Arnold(C4DToA)阿诺德渲染教程(72) – 使用自发光材质实现折射焦散效果

2018-1-11 16:25:47

4 条回复 A文章作者 M管理员
  1. 超出理解范围了,5555~~~

  2. 这个有些完全看不懂。。。

  3. 666

  4. what

有新私信 私信列表
搜索