此示例演示了如何获取现有的着色器代码并在 Maya 中为 GLSL/CgFX 环境对其进行自定义,以便可以在 OpenGL 模式下将它与 ShaderFX 一起使用。然后,该示例演示了如何为 HLSL 环境自定义代码,以便也可以在 Maya 中在 DirectX 11 模式下使用。
本例中所用的着色器代码取自 https://www.shadertoy.com/view/ldB3zc,由 Iñigo Quilez 提供。您可以访问此站点,以获得以下示例代码并对其进行修改以在 Maya 中使用。
以下工作流的视频演示现已可用。有关详细信息,请参见下面的视频教程。
float hash1( float n ) { return fract(sin(n)*43758.5453); }
vec2 hash2( vec2 p ) { p = vec2( dot(p,vec2(127.1,311.7)), dot(p,vec2(269.5,183.3)) ); return fract(sin(p)*43758.5453); }
vec4 voronoi( in vec2 x, float w )
{
vec2 n = floor( x );
vec2 f = fract( x );
vec4 m = vec4( 8.0, 0.0, 0.0, 0.0 );
for( int j=-2; j<=2; j++ )
for( int i=-2; i<=2; i++ )
{
vec2 g = vec2( float(i),float(j) );
vec2 o = hash2( n + g );
// animate
o = 0.5 + 0.5*sin( iGlobalTime + 6.2831*o );
// distance to cell
float d = length(g - f + o);
// do the smooth min for colors and distances
vec3 col = 0.5 + 0.5*sin( hash1(dot(n+g,vec2(7.0,113.0)))*2.5 + 3.5 + vec3(2.0,3.0,0.0));
float h = smoothstep( 0.0, 1.0, 0.5 + 0.5*(m.x-d)/w );
m.x = mix( m.x, d, h ) - h*(1.0-h)*w/(1.0+3.0*w); // distance
m.yzw = mix( m.yzw, col, h ) - h*(1.0-h)*w/(1.0+3.0*w); // cioloe
}
return m;
}
void main( void )
{
vec2 p = gl_FragCoord.xy/iResolution.yy;
float k = 2.0 + 70.0 * pow( 0.5 + 0.5*sin(0.25*6.2831*iGlobalTime), 4.0 );
k = 0.5 - 0.5*cos(0.25*6.2831*iGlobalTime);
vec4 c = voronoi( 6.0*p, k );
vec3 col = c.yzw;
col *= 1.0 - 0.8*c.x*step(p.y,0.33);
col *= mix(c.x,1.0,step(p.y,0.66));
col *= smoothstep( 0.005, 0.007, abs(p.y-0.33) );
col *= smoothstep( 0.005, 0.007, abs(p.y-0.66) );
gl_FragColor = vec4( col, 1.0 );
}
若要修改此代码,使其与 SFX_GLSL_*/SFX_CGFX_3 兼容,以便可以在 Maya 中在 OpenGL 模式下与 ShaderFX 一起使用,请执行以下操作:
gl_FragCoord.xy 是 GLSL 中所用的一个全局变量,用于获得纹理坐标。在 Maya 中,您使用 UV 集来获得纹理坐标。
将 main (void) 更改为函数定义,使其与“自定义代码”(Custom Code)节点默认提供的函数定义类似:
CustomCode1178Output CustomCode1178Func( float2 UV )
struct CustomCode1178Output
{
float3 color;
};
将 iGlobalTime 替换为 time。
将 float time 作为输入参数添加到函数定义中。
将 float time 作为输入参数添加到 voronoi 函数定义中。
添加 time 作为名为 voronoi 的输入参数。
CustomCode1178Output OUT; OUT.color = col; return OUT;

修改后的代码如下所示:
float VoronoiSmooth_hash1( float n ) { return fract(sin(n)*43758.5453); }
float2 VoronoiSmooth_hash2( float2 p ) { p = float2( dot(p,float2(127.1,311.7)), dot(p,float2(269.5,183.3)) ); return fract(sin(p)*43758.5453); }
float4 VoronoiSmooth( in float2 x, float w, float time )
{
float2 n = floor( x );
float2 f = fract( x );
float4 m = float4( 8.0, 0.0, 0.0, 0.0 );
for( int j=-2; j<=2; j++ )
for( int i=-2; i<=2; i++ )
{
float2 g = float2( float(i),float(j) );
float2 o = VoronoiSmooth_hash2( n + g );
// animate
o = 0.5 + 0.5*sin( time + 6.2831*o );
// distance to cell
float d = length(g - f + o);
// do the smooth min for colors and distances
float3 col = 0.5 + 0.5*sin( VoronoiSmooth_hash1(dot(n+g,float2(7.0,113.0)))*2.5 + 3.5 + float3(2.0,3.0,0.0));
float h = smoothstep( 0.0, 1.0, 0.5 + 0.5*(m.x-d)/w );
m.x = mix( m.x, d, h ) - h*(1.0-h)*w/(1.0+3.0*w); // distanec
m.yzw = mix( m.yzw, col, h ) - h*(1.0-h)*w/(1.0+3.0*w); // cioloe
}
return m;
}
struct VoronoiSmoothOutput
{
float3 color;
};
VoronoiSmoothOutput VoronoiSmoothFunc( float2 UV, float time )
{
float2 p = UV;
float k = 2.0 + 70.0 * pow( 0.5 + 0.5*sin(0.25*6.2831*time), 4.0 );
k = 0.5 - 0.5*cos(0.25*6.2831*time);
float4 c = VoronoiSmooth( 6.0*p, k, time );
float3 col = c.yzw;
col *= 1.0 - 0.8*c.x*step(p.y,0.33);
col *= mix(c.x,1.0,step(p.y,0.66));
col *= smoothstep( 0.005, 0.007, abs(p.y-0.33) );
col *= smoothstep( 0.005, 0.007, abs(p.y-0.66) );
VoronoiSmoothOutput OUT;
OUT.color = col;
return OUT;
}
现在,可以为您的自定义代码节点使用此代码。将其按如下所示进行连接,在 ShaderFX 编辑器中和 Viewport 2.0 OpenGL 模式下证明其动画。

如果在 DirectX 11 模式下创建相同的 ShaderFX 网络,然后尝试执行样例渲染,则无法编译着色器样例。为帮助调试,请选择“设置 > 显示样例编译错误”(Settings > Show Swatch Compile Errors)并检查出现的错误。
若要修改此代码,使其与 SFX_HLSL_3/SFX_HLSL_5 兼容,以便可以在 Maya 中在 DirectX 11 模式下与 ShaderFX 一起使用,请执行以下操作:
#if ( defined(SFX_HLSL_3) || defined( SFX_HLSL_5) ) #define fract frac #define mix lerp #endif
修改后的代码如下所示:
#if ( defined(SFX_HLSL_3) || defined( SFX_HLSL_5) )
#define fract frac
#define mix lerp
#endif
float VoronoiSmooth_hash1( float n ) { return fract(sin(n)*43758.5453); }
float2 VoronoiSmooth_hash2( float2 p ) { p = float2( dot(p,float2(127.1,311.7)), dot(p,float2(269.5,183.3)) ); return fract(sin(p)*43758.5453); }
float4 VoronoiSmooth( in float2 x, float w, float time )
{
float2 n = floor( x );
float2 f = fract( x );
float4 m = float4( 8.0, 0.0, 0.0, 0.0 );
for( int j=-2; j<=2; j++ )
for( int i=-2; i<=2; i++ )
{
float2 g = float2( float(i),float(j) );
float2 o = VoronoiSmooth_hash2( n + g );
// animate
o = 0.5 + 0.5*sin( time + 6.2831*o );
// distance to cell
float d = length(g - f + o);
// do the smooth min for colors and distances
float3 col = 0.5 + 0.5*sin( VoronoiSmooth_hash1(dot(n+g,float2(7.0,113.0)))*2.5 + 3.5 + float3(2.0,3.0,0.0));
float h = smoothstep( 0.0, 1.0, 0.5 + 0.5*(m.x-d)/w );
m.x = mix( m.x, d, h ) - h*(1.0-h)*w/(1.0+3.0*w); // distanec
m.yzw = mix( m.yzw, col, h ) - h*(1.0-h)*w/(1.0+3.0*w); // cioloe
}
return m;
}
struct VoronoiSmoothOutput
{
float3 color;
};
VoronoiSmoothOutput VoronoiSmoothFunc( float2 UV, float time )
{
float2 p = UV;
float k = 2.0 + 70.0 * pow( 0.5 + 0.5*sin(0.25*6.2831*time), 4.0 );
k = 0.5 - 0.5*cos(0.25*6.2831*time);
float4 c = VoronoiSmooth( 6.0*p, k, time );
float3 col = c.yzw;
col *= 1.0 - 0.8*c.x*step(p.y,0.33);
col *= mix(c.x,1.0,step(p.y,0.66));
col *= smoothstep( 0.005, 0.007, abs(p.y-0.33) );
col *= smoothstep( 0.005, 0.007, abs(p.y-0.66) );
VoronoiSmoothOutput OUT;
OUT.color = col;
return OUT;
}
使用上述代码创建“自定义代码”(Custom Code)之后,即可创建网络,例如下面这种网络。

有关创建组并使用“默认值”(Default Value)节点的更多详细信息,请参见为组节点提供其他输入并标记组节点端口。
在此示例中,我们提供了一个默认的 UV 集和默认的时间节点,同时允许用户提供其他 UV 集。

观看以下形象地演示上述工作流示例的视频: