Arnold 允许着色器置换多边形网格节点中的顶点。这些顶点按照着色器所返回向量的方向和幅值进行置换。
在此示例着色器中,我们根据噪波函数计算非线性置换。与传统噪波置换着色器一样,该着色器可以沿曲面法线进行置换,但也可以选择采用置换的峰值和谷值。
这可以通过计算噪波函数及其在两个曲面导数的方向上的增量来完成。该增量将确定这些导数因置换而偏转的幅度。通过反复偏转导数,我们创建了从曲面走弧线的非线性置换。这相当于置换曲面、计算法线,然后重复置换。
type abs_perlin
freq
0.025
amplitude
80
type recursive
freq 0.025
amplitude 40
bloom 3
freq 0.025
amplitude 40
bloom 3
type abs_recursive
freq
0.025
amplitude
40
bloom
3
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 }
超出理解范围了,5555~~~
这个有些完全看不懂。。。
666
what