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()
194 def postConstructor(self):
200 class brickTextureNodeOverride(omr.MPxShadingNodeOverride):
203 return brickTextureNodeOverride(obj)
205 def __init__(self, obj):
206 omr.MPxShadingNodeOverride.__init__(self, obj)
209 fragmentMgr = omr.MRenderer.getFragmentManager()
210 if fragmentMgr !=
None:
211 if not fragmentMgr.hasFragment(
"brickTextureNodePluginFragment"):
212 fragmentBody =
"<fragment uiName=\"brickTextureNodePluginFragment\" name=\"brickTextureNodePluginFragment\" type=\"plumbing\" class=\"ShadeFragment\" version=\"1.0\">"
213 fragmentBody +=
" <description><![CDATA[Brick procedural texture fragment]]></description>"
214 fragmentBody +=
" <properties>"
215 fragmentBody +=
" <float3 name=\"brickColor\" />"
216 fragmentBody +=
" <float3 name=\"jointColor\" />"
217 fragmentBody +=
" <float name=\"blurFactor\" />"
218 fragmentBody +=
" <float2 name=\"uvCoord\" semantic=\"mayaUvCoordSemantic\" flags=\"varyingInputParam\" />"
219 fragmentBody +=
" <float2 name=\"uvFilterSize\" />"
220 fragmentBody +=
" </properties>"
221 fragmentBody +=
" <values>"
222 fragmentBody +=
" <float3 name=\"brickColor\" value=\"0.75,0.3,0.1\" />"
223 fragmentBody +=
" <float3 name=\"jointColor\" value=\"0.75,0.75,0.75\" />"
224 fragmentBody +=
" </values>"
225 fragmentBody +=
" <outputs>"
226 fragmentBody +=
" <float3 name=\"outColor\" />"
227 fragmentBody +=
" </outputs>"
228 fragmentBody +=
" <implementation>"
229 fragmentBody +=
" <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.1\">"
230 fragmentBody +=
" <function_name val=\"brickTextureNodePluginFragment\" />"
231 fragmentBody +=
" <source><![CDATA["
232 fragmentBody +=
"float btnplinearstep(float t, float a, float b) \n"
233 fragmentBody +=
"{ \n"
234 fragmentBody +=
" if (t < a) return 0.0f; \n"
235 fragmentBody +=
" if (t > b) return 1.0f; \n"
236 fragmentBody +=
" return (t - a)/(b - a); \n"
237 fragmentBody +=
"} \n"
238 fragmentBody +=
"float3 brickTextureNodePluginFragment(float3 color1, float3 color2, float blur, float2 uv, float2 fs) \n"
239 fragmentBody +=
"{ \n"
240 fragmentBody +=
" uv -= floor(uv); \n"
241 fragmentBody +=
" float v1 = 0.05f; float v2 = 0.45f; float v3 = 0.55f; float v4 = 0.95f; \n"
242 fragmentBody +=
" float u1 = 0.05f; float u2 = 0.45f; float u3 = 0.55f; float u4 = 0.95f; \n"
243 fragmentBody +=
" float du = blur*fs.x/2.0f; \n"
244 fragmentBody +=
" float dv = blur*fs.y/2.0f; \n"
245 fragmentBody +=
" float t = max( \n"
246 fragmentBody +=
" min(btnplinearstep(uv.y, v1 - dv, v1 + dv) - btnplinearstep(uv.y, v2 - dv, v2 + dv), \n"
247 fragmentBody +=
" max(btnplinearstep(uv.x, u3 - du, u3 + du), 1.0f - btnplinearstep(uv.x, u2 - du, u2 + du))), \n"
248 fragmentBody +=
" min(btnplinearstep(uv.y, v3 - dv, v3 + dv) - btnplinearstep(uv.y, v4 - dv, v4 + dv), \n"
249 fragmentBody +=
" btnplinearstep(uv.x, u1 - du, u1 + du) - btnplinearstep(uv.x, u4 - du, u4 + du))); \n"
250 fragmentBody +=
" return t*color1 + (1.0f - t)*color2; \n"
251 fragmentBody +=
"} \n]]>"
252 fragmentBody +=
" </source>"
253 fragmentBody +=
" </implementation>"
254 fragmentBody +=
" <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.0\">"
255 fragmentBody +=
" <function_name val=\"brickTextureNodePluginFragment\" />"
256 fragmentBody +=
" <source><![CDATA["
257 fragmentBody +=
"float btnplinearstep(float t, float a, float b) \n"
258 fragmentBody +=
"{ \n"
259 fragmentBody +=
" if (t < a) return 0.0f; \n"
260 fragmentBody +=
" if (t > b) return 1.0f; \n"
261 fragmentBody +=
" return (t - a)/(b - a); \n"
262 fragmentBody +=
"} \n"
263 fragmentBody +=
"float3 brickTextureNodePluginFragment(float3 color1, float3 color2, float blur, float2 uv, float2 fs) \n"
264 fragmentBody +=
"{ \n"
265 fragmentBody +=
" uv -= floor(uv); \n"
266 fragmentBody +=
" float v1 = 0.05f; float v2 = 0.45f; float v3 = 0.55f; float v4 = 0.95f; \n"
267 fragmentBody +=
" float u1 = 0.05f; float u2 = 0.45f; float u3 = 0.55f; float u4 = 0.95f; \n"
268 fragmentBody +=
" float du = blur*fs.x/2.0f; \n"
269 fragmentBody +=
" float dv = blur*fs.y/2.0f; \n"
270 fragmentBody +=
" float t = max( \n"
271 fragmentBody +=
" min(btnplinearstep(uv.y, v1 - dv, v1 + dv) - btnplinearstep(uv.y, v2 - dv, v2 + dv), \n"
272 fragmentBody +=
" max(btnplinearstep(uv.x, u3 - du, u3 + du), 1.0f - btnplinearstep(uv.x, u2 - du, u2 + du))), \n"
273 fragmentBody +=
" min(btnplinearstep(uv.y, v3 - dv, v3 + dv) - btnplinearstep(uv.y, v4 - dv, v4 + dv), \n"
274 fragmentBody +=
" btnplinearstep(uv.x, u1 - du, u1 + du) - btnplinearstep(uv.x, u4 - du, u4 + du))); \n"
275 fragmentBody +=
" return t*color1 + (1.0f - t)*color2; \n"
276 fragmentBody +=
"} \n]]>"
277 fragmentBody +=
" </source>"
278 fragmentBody +=
" </implementation>"
279 fragmentBody +=
" <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\">"
280 fragmentBody +=
" <function_name val=\"brickTextureNodePluginFragment\" />"
281 fragmentBody +=
" <source><![CDATA["
282 fragmentBody +=
"float btnplinearstep(float t, float a, float b) \n"
283 fragmentBody +=
"{ \n"
284 fragmentBody +=
" if (t < a) return 0.0f; \n"
285 fragmentBody +=
" if (t > b) return 1.0f; \n"
286 fragmentBody +=
" return (t - a)/(b - a); \n"
287 fragmentBody +=
"} \n"
288 fragmentBody +=
"vec3 brickTextureNodePluginFragment(vec3 color1, vec3 color2, float blur, vec2 uv, vec2 fs) \n"
289 fragmentBody +=
"{ \n"
290 fragmentBody +=
" uv -= floor(uv); \n"
291 fragmentBody +=
" float v1 = 0.05f; float v2 = 0.45f; float v3 = 0.55f; float v4 = 0.95f; \n"
292 fragmentBody +=
" float u1 = 0.05f; float u2 = 0.45f; float u3 = 0.55f; float u4 = 0.95f; \n"
293 fragmentBody +=
" float du = blur*fs.x/2.0f; \n"
294 fragmentBody +=
" float dv = blur*fs.y/2.0f; \n"
295 fragmentBody +=
" float t = max( \n"
296 fragmentBody +=
" min(btnplinearstep(uv.y, v1 - dv, v1 + dv) - btnplinearstep(uv.y, v2 - dv, v2 + dv), \n"
297 fragmentBody +=
" max(btnplinearstep(uv.x, u3 - du, u3 + du), 1.0f - btnplinearstep(uv.x, u2 - du, u2 + du))), \n"
298 fragmentBody +=
" min(btnplinearstep(uv.y, v3 - dv, v3 + dv) - btnplinearstep(uv.y, v4 - dv, v4 + dv), \n"
299 fragmentBody +=
" btnplinearstep(uv.x, u1 - du, u1 + du) - btnplinearstep(uv.x, u4 - du, u4 + du))); \n"
300 fragmentBody +=
" return t*color1 + (1.0f - t)*color2; \n"
301 fragmentBody +=
"} \n]]>"
302 fragmentBody +=
" </source>"
303 fragmentBody +=
" </implementation>"
304 fragmentBody +=
" </implementation>"
305 fragmentBody +=
"</fragment>"
307 fragmentMgr.addShadeFragmentFromBuffer(fragmentBody,
False)
309 def supportedDrawAPIs(self):
310 return omr.MRenderer.kOpenGL | omr.MRenderer.kOpenGLCoreProfile | omr.MRenderer.kDirectX11
312 def fragmentName(self):
313 return "brickTextureNodePluginFragment"
319 sRegistrantId =
"brickTexturePlugin"
321 def initializePlugin(obj):
322 plugin = om.MFnPlugin(obj,
"Autodesk",
"4.5",
"Any")
324 userClassify =
"texture/2d:drawdb/shader/texture/2d/brickTexture"
325 plugin.registerNode(
"brickTexture", brickTextureNode.id, brickTextureNode.creator, brickTextureNode.initialize, om.MPxNode.kDependNode, userClassify)
327 sys.stderr.write(
"Failed to register node\n")
332 omr.MDrawRegistry.registerShadingNodeOverrideCreator(
"drawdb/shader/texture/2d/brickTexture", sRegistrantId, brickTextureNodeOverride.creator)
334 sys.stderr.write(
"Failed to register override\n")
337 def uninitializePlugin(obj):
338 plugin = om.MFnPlugin(obj)
340 plugin.deregisterNode(brickTextureNode.id)
342 sys.stderr.write(
"Failed to deregister node\n")
347 omr.MDrawRegistry.deregisterShadingNodeOverrideCreator(
"drawdb/shader/texture/2d/brickTexture", sRegistrantId)
349 sys.stderr.write(
"Failed to deregister override\n")