13 import maya.api.OpenMaya
as om
14 import maya.api.OpenMayaRender
as omr
24 The presence of this function tells Maya that the plugin produces, and
25 expects to be passed, objects created using the Maya Python API 2.0.
34 def smoothstep(t, a, b):
40 return t*t*(3.0 - 2.0*t)
42 def linearstep(t, a, b):
47 return (t - a)/(b - a)
52 class brickTextureNode(om.MPxNode):
54 id = om.MTypeId( 0x8100d )
68 return brickTextureNode()
72 nAttr = om.MFnNumericAttribute()
76 brickTextureNode.aColor1 = nAttr.createColor(
"brickColor",
"bc")
81 nAttr.default = (.75, .3, .1)
83 brickTextureNode.aColor2 = nAttr.createColor(
"jointColor",
"jc")
88 nAttr.default = (.75, .75, .75)
90 brickTextureNode.aBlurFactor = nAttr.create(
"blurFactor",
"bf", om.MFnNumericData.kFloat)
98 child1 = nAttr.create(
"uCoord",
"u", om.MFnNumericData.kFloat)
99 child2 = nAttr.create( "vCoord",
"v", om.MFnNumericData.kFloat)
100 brickTextureNode.aUVCoord = nAttr.create(
"uvCoord",
"uv", child1, child2)
102 nAttr.storable =
True
103 nAttr.readable =
True
104 nAttr.writable =
True
107 child1 = nAttr.create(
"uvFilterSizeX",
"fsx", om.MFnNumericData.kFloat)
108 child2 = nAttr.create(
"uvFilterSizeY",
"fsy", om.MFnNumericData.kFloat)
109 brickTextureNode.aFilterSize = nAttr.create(
"uvFilterSize",
"fs", child1, child2)
111 nAttr.storable =
True
112 nAttr.readable =
True
113 nAttr.writable =
True
117 brickTextureNode.aOutColor = nAttr.createColor(
"outColor",
"oc")
118 nAttr.keyable =
False
119 nAttr.storable =
False
120 nAttr.readable =
True
121 nAttr.writable =
False
124 om.MPxNode.addAttribute(brickTextureNode.aColor1)
125 om.MPxNode.addAttribute(brickTextureNode.aColor2)
126 om.MPxNode.addAttribute(brickTextureNode.aBlurFactor)
127 om.MPxNode.addAttribute(brickTextureNode.aFilterSize)
128 om.MPxNode.addAttribute(brickTextureNode.aUVCoord)
130 om.MPxNode.addAttribute(brickTextureNode.aOutColor)
133 om.MPxNode.attributeAffects(brickTextureNode.aColor1, brickTextureNode.aOutColor)
134 om.MPxNode.attributeAffects(brickTextureNode.aColor2, brickTextureNode.aOutColor)
135 om.MPxNode.attributeAffects(brickTextureNode.aBlurFactor, brickTextureNode.aOutColor)
136 om.MPxNode.attributeAffects(brickTextureNode.aFilterSize, brickTextureNode.aOutColor)
137 om.MPxNode.attributeAffects(brickTextureNode.aUVCoord, brickTextureNode.aOutColor)
140 om.MPxNode.__init__(self)
151 def compute(self, plug, block):
153 if (plug != brickTextureNode.aOutColor)
and (plug.parent() != brickTextureNode.aOutColor):
156 uv = block.inputValue( brickTextureNode.aUVCoord ).asFloat2()
157 surfaceColor1 = block.inputValue( brickTextureNode.aColor1 ).asFloatVector()
158 surfaceColor2 = block.inputValue( brickTextureNode.aColor2 ).asFloatVector()
161 uv[0] -= math.floor(uv[0])
162 uv[1] -= math.floor(uv[1])
167 blur = block.inputValue( brickTextureNode.aBlurFactor ).asFloat()
170 v2 = v1 + brickHeight
171 v3 = v2 + borderWidth
172 v4 = v3 + brickHeight
175 u3 = u2 + borderWidth
178 fs = block.inputValue( brickTextureNode.aFilterSize ).asFloat2()
182 t = max(min(linearstep(uv[1], v1 - dv, v1 + dv) - linearstep(uv[1], v2 - dv, v2 + dv), max(linearstep(uv[0], u3 - du, u3 + du), 1 - linearstep(uv[0], u2 - du, u2 + du))), min(linearstep(uv[1], v3 - dv, v3 + dv) - linearstep(uv[1], v4 - dv, v4 + dv), linearstep(uv[0], u1 - du, u1 + du) - linearstep(uv[0], u4 - du, u4 + du)))
184 resultColor = t*surfaceColor1 + (1.0 - t)*surfaceColor2
187 outColorHandle = block.outputValue( brickTextureNode.aOutColor )
188 outColorHandle.setMFloatVector( resultColor )
189 outColorHandle.setClean()
191 def postConstructor(self):
197 class brickTextureNodeOverride(omr.MPxShadingNodeOverride):
200 return brickTextureNodeOverride(obj)
202 def __init__(self, obj):
203 omr.MPxShadingNodeOverride.__init__(self, obj)
206 fragmentMgr = omr.MRenderer.getFragmentManager()
207 if fragmentMgr !=
None:
208 if not fragmentMgr.hasFragment(
"brickTextureNodePluginFragment"):
209 fragmentBody =
"<fragment uiName=\"brickTextureNodePluginFragment\" name=\"brickTextureNodePluginFragment\" type=\"plumbing\" class=\"ShadeFragment\" version=\"1.0\">"
210 fragmentBody +=
" <description><![CDATA[Brick procedural texture fragment]]></description>"
211 fragmentBody +=
" <properties>"
212 fragmentBody +=
" <float3 name=\"brickColor\" />"
213 fragmentBody +=
" <float3 name=\"jointColor\" />"
214 fragmentBody +=
" <float name=\"blurFactor\" />"
215 fragmentBody +=
" <float2 name=\"uvCoord\" semantic=\"mayaUvCoordSemantic\" flags=\"varyingInputParam\" />"
216 fragmentBody +=
" <float2 name=\"uvFilterSize\" />"
217 fragmentBody +=
" </properties>"
218 fragmentBody +=
" <values>"
219 fragmentBody +=
" <float3 name=\"brickColor\" value=\"0.75,0.3,0.1\" />"
220 fragmentBody +=
" <float3 name=\"jointColor\" value=\"0.75,0.75,0.75\" />"
221 fragmentBody +=
" </values>"
222 fragmentBody +=
" <outputs>"
223 fragmentBody +=
" <float3 name=\"outColor\" />"
224 fragmentBody +=
" </outputs>"
225 fragmentBody +=
" <implementation>"
226 fragmentBody +=
" <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.1\">"
227 fragmentBody +=
" <function_name val=\"brickTextureNodePluginFragment\" />"
228 fragmentBody +=
" <source><![CDATA["
229 fragmentBody +=
"float btnplinearstep(float t, float a, float b) \n"
230 fragmentBody +=
"{ \n"
231 fragmentBody +=
" if (t < a) return 0.0f; \n"
232 fragmentBody +=
" if (t > b) return 1.0f; \n"
233 fragmentBody +=
" return (t - a)/(b - a); \n"
234 fragmentBody +=
"} \n"
235 fragmentBody +=
"float3 brickTextureNodePluginFragment(float3 color1, float3 color2, float blur, float2 uv, float2 fs) \n"
236 fragmentBody +=
"{ \n"
237 fragmentBody +=
" uv -= floor(uv); \n"
238 fragmentBody +=
" float v1 = 0.05f; float v2 = 0.45f; float v3 = 0.55f; float v4 = 0.95f; \n"
239 fragmentBody +=
" float u1 = 0.05f; float u2 = 0.45f; float u3 = 0.55f; float u4 = 0.95f; \n"
240 fragmentBody +=
" float du = blur*fs.x/2.0f; \n"
241 fragmentBody +=
" float dv = blur*fs.y/2.0f; \n"
242 fragmentBody +=
" float t = max( \n"
243 fragmentBody +=
" min(btnplinearstep(uv.y, v1 - dv, v1 + dv) - btnplinearstep(uv.y, v2 - dv, v2 + dv), \n"
244 fragmentBody +=
" max(btnplinearstep(uv.x, u3 - du, u3 + du), 1.0f - btnplinearstep(uv.x, u2 - du, u2 + du))), \n"
245 fragmentBody +=
" min(btnplinearstep(uv.y, v3 - dv, v3 + dv) - btnplinearstep(uv.y, v4 - dv, v4 + dv), \n"
246 fragmentBody +=
" btnplinearstep(uv.x, u1 - du, u1 + du) - btnplinearstep(uv.x, u4 - du, u4 + du))); \n"
247 fragmentBody +=
" return t*color1 + (1.0f - t)*color2; \n"
248 fragmentBody +=
"} \n]]>"
249 fragmentBody +=
" </source>"
250 fragmentBody +=
" </implementation>"
251 fragmentBody +=
" <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.0\">"
252 fragmentBody +=
" <function_name val=\"brickTextureNodePluginFragment\" />"
253 fragmentBody +=
" <source><![CDATA["
254 fragmentBody +=
"float btnplinearstep(float t, float a, float b) \n"
255 fragmentBody +=
"{ \n"
256 fragmentBody +=
" if (t < a) return 0.0f; \n"
257 fragmentBody +=
" if (t > b) return 1.0f; \n"
258 fragmentBody +=
" return (t - a)/(b - a); \n"
259 fragmentBody +=
"} \n"
260 fragmentBody +=
"float3 brickTextureNodePluginFragment(float3 color1, float3 color2, float blur, float2 uv, float2 fs) \n"
261 fragmentBody +=
"{ \n"
262 fragmentBody +=
" uv -= floor(uv); \n"
263 fragmentBody +=
" float v1 = 0.05f; float v2 = 0.45f; float v3 = 0.55f; float v4 = 0.95f; \n"
264 fragmentBody +=
" float u1 = 0.05f; float u2 = 0.45f; float u3 = 0.55f; float u4 = 0.95f; \n"
265 fragmentBody +=
" float du = blur*fs.x/2.0f; \n"
266 fragmentBody +=
" float dv = blur*fs.y/2.0f; \n"
267 fragmentBody +=
" float t = max( \n"
268 fragmentBody +=
" min(btnplinearstep(uv.y, v1 - dv, v1 + dv) - btnplinearstep(uv.y, v2 - dv, v2 + dv), \n"
269 fragmentBody +=
" max(btnplinearstep(uv.x, u3 - du, u3 + du), 1.0f - btnplinearstep(uv.x, u2 - du, u2 + du))), \n"
270 fragmentBody +=
" min(btnplinearstep(uv.y, v3 - dv, v3 + dv) - btnplinearstep(uv.y, v4 - dv, v4 + dv), \n"
271 fragmentBody +=
" btnplinearstep(uv.x, u1 - du, u1 + du) - btnplinearstep(uv.x, u4 - du, u4 + du))); \n"
272 fragmentBody +=
" return t*color1 + (1.0f - t)*color2; \n"
273 fragmentBody +=
"} \n]]>"
274 fragmentBody +=
" </source>"
275 fragmentBody +=
" </implementation>"
276 fragmentBody +=
" <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\">"
277 fragmentBody +=
" <function_name val=\"brickTextureNodePluginFragment\" />"
278 fragmentBody +=
" <source><![CDATA["
279 fragmentBody +=
"float btnplinearstep(float t, float a, float b) \n"
280 fragmentBody +=
"{ \n"
281 fragmentBody +=
" if (t < a) return 0.0f; \n"
282 fragmentBody +=
" if (t > b) return 1.0f; \n"
283 fragmentBody +=
" return (t - a)/(b - a); \n"
284 fragmentBody +=
"} \n"
285 fragmentBody +=
"vec3 brickTextureNodePluginFragment(vec3 color1, vec3 color2, float blur, vec2 uv, vec2 fs) \n"
286 fragmentBody +=
"{ \n"
287 fragmentBody +=
" uv -= floor(uv); \n"
288 fragmentBody +=
" float v1 = 0.05f; float v2 = 0.45f; float v3 = 0.55f; float v4 = 0.95f; \n"
289 fragmentBody +=
" float u1 = 0.05f; float u2 = 0.45f; float u3 = 0.55f; float u4 = 0.95f; \n"
290 fragmentBody +=
" float du = blur*fs.x/2.0f; \n"
291 fragmentBody +=
" float dv = blur*fs.y/2.0f; \n"
292 fragmentBody +=
" float t = max( \n"
293 fragmentBody +=
" min(btnplinearstep(uv.y, v1 - dv, v1 + dv) - btnplinearstep(uv.y, v2 - dv, v2 + dv), \n"
294 fragmentBody +=
" max(btnplinearstep(uv.x, u3 - du, u3 + du), 1.0f - btnplinearstep(uv.x, u2 - du, u2 + du))), \n"
295 fragmentBody +=
" min(btnplinearstep(uv.y, v3 - dv, v3 + dv) - btnplinearstep(uv.y, v4 - dv, v4 + dv), \n"
296 fragmentBody +=
" btnplinearstep(uv.x, u1 - du, u1 + du) - btnplinearstep(uv.x, u4 - du, u4 + du))); \n"
297 fragmentBody +=
" return t*color1 + (1.0f - t)*color2; \n"
298 fragmentBody +=
"} \n]]>"
299 fragmentBody +=
" </source>"
300 fragmentBody +=
" </implementation>"
301 fragmentBody +=
" </implementation>"
302 fragmentBody +=
"</fragment>"
304 fragmentMgr.addShadeFragmentFromBuffer(fragmentBody,
False)
306 def supportedDrawAPIs(self):
307 return omr.MRenderer.kOpenGL | omr.MRenderer.kOpenGLCoreProfile | omr.MRenderer.kDirectX11
309 def fragmentName(self):
310 return "brickTextureNodePluginFragment"
316 sRegistrantId =
"brickTexturePlugin"
318 def initializePlugin(obj):
319 plugin = om.MFnPlugin(obj,
"Autodesk",
"4.5",
"Any")
321 userClassify =
"texture/2d:drawdb/shader/texture/2d/brickTexture"
322 plugin.registerNode(
"brickTexture", brickTextureNode.id, brickTextureNode.creator, brickTextureNode.initialize, om.MPxNode.kDependNode, userClassify)
324 sys.stderr.write(
"Failed to register node\n")
329 omr.MDrawRegistry.registerShadingNodeOverrideCreator(
"drawdb/shader/texture/2d/brickTexture", sRegistrantId, brickTextureNodeOverride.creator)
331 sys.stderr.write(
"Failed to register override\n")
334 def uninitializePlugin(obj):
335 plugin = om.MFnPlugin(obj)
337 plugin.deregisterNode(brickTextureNode.id)
339 sys.stderr.write(
"Failed to deregister node\n")
344 omr.MDrawRegistry.deregisterShadingNodeOverrideCreator(
"drawdb/shader/texture/2d/brickTexture", sRegistrantId)
346 sys.stderr.write(
"Failed to deregister override\n")