few basic questions

As always you amazed me Marcus :slight_smile:
What an helpful time you’ve given to my case, thanks you alot, just give me time to digest all this, I will be back when i will have some more progress, I still haven’t test out :slight_smile:

i just discovered yesterday the video tutorial series made by bradford Smith that was a lot of information to take in consideration link : http://bradfolio.com/category/tutorials/zbrush-tutorials/
note for Brad if you come across this theard : (i know you are not that far from here ^^)
hehe i liked you shared your workflow. )

I really haven’t took in consideration the 2.5D tools and the layer slots, i want to make this full none destructive workflow using the subtools stack, and let the user choose the workflow he liked to apply for the job he want to achieve.

when i render something the background is always, cause i use the bpr render and export, shaded, mask, depth, ao, sss, floor and shadows from there, the psd file are always one locked background layer in photoshop, even if i uncheck Flatten in render passes .
Define a color in document, doesn’t apply and render:environement:color doesn’t works too.

Zapplink is the only option I have to get all active layers slots and export into a layered psd files.
with zapplink, we can’t define a custom path for the generated file. so i don’t really know what option are still possible.

At this moment i would like to prevent from making ome action script for photoshop to rebuild the psd from many psd file. i have no idea how i could do differently.

to open the saved render passes into a psd editor, but i mainly use photoshop to work with, i use this tools : “psd document bridge”

Texture:GrabDocAndDepth just makes one layer PSD with the depth that is stored into the alpha channel
And “document:export” does nothing better ,same with mrgbZgrabber.

I have no idea how will be the performance in the viewport, with this none destructive workflow , if we have plenty of subtools with each of them that could have a huge amount of polygons, like for tiled Rock ground or brick, or nature ground…
That’s something i would see when the texturing workflow will have been completely determined.

hello again,
really i am doing slow progress because of a lack of motivation, and many issue i am running in that annoy me a lot.

I really like to found a fix when you render using bpr, then the exported texture are their seams briken because Zbrush insert a black border line all around the canvas.
if you apply an offset to 512*512 on my 1k texture you get this issue :


so the workaround that work well , because i am not liking the use of spot healing brush on the seams to fix them in photoshop

my texture canvas will be 1024k on the ui but in real the texture exported will be 10261026.
as you just need to remove one pixel from the border photoshop Edit > Canvas Size will do the job for me.
just have to change from 1026
1026 to 1024*1024 and don’t touch the cropping options to keep it centered.

Now when i apply the offset it give me this nice result and no use of the spot healing brush : )


I am still learning a lot of zbrush features, i think that i reach a point now , become a super expert :slight_smile:

I would like to get some feedback to know from texture artists if they like to have a full 3d workflow to create tiled texture.
because at don’t really want to use the 2.5D tools . But i am very open for adding tool related to this workflow.
I think about that to start

  • get current texture and save it on disk with this naming convention “%ZPROJECTNAME%_texturegrab.*”
  • get alpha texture and save it on the disk with this naming convention “%ZPROJECTNAME%_depthgrab.*”
  • add a buttons in psd document bridge section to open the “%ZPROJECTNAME%_texturegrab.*” into photoshop
  • add a buttons in psd document bridge section to open the “%ZPROJECTNAME%_depthgrab.*” into photoshop

It could be important to know how to make sure the user keep a none destructive workflow with the use of the Ztool library saved within the Zproject file. but i am sure if i know already how it will going in real production work, seems too early for that.

I will add a sort of joystick on the ui that will duplicate the current subtool and nudge it with deformation set to 200.

ok back with a concept picture to illustrate the idea and share the it with you.


hope you like.

What do you think ?

hello again,
tbh, i despair i should make a guide to show how Zbrush never give a correct tiled map.

i exported a bunch of tiled patterns from Substance designer ( high def 16bit luminance texture exported as psd file)
settings in Designer :


just to be sure the exported texture are not wrong, i load the texture in PS and apply an filter > other > offset and the tiling is working perfectly.


now i want to be sure it tiles correctly into UE4


no comment, perfect seams.

mrgbzGrabber without autocrop give 2 pixel black line on top and bottom, and it override the 2 pixel lines that make the tile to be correct on to a plane3D mesh.

mrgbZgrabber + autocrop : remove 2 pixel from the height onto the canvas so the final texture is 1024*1022

Texture grab doc :

  • give the correct document size 1024*1024
  • but it act exaclty like mrgbzgrabber with autocrop enable


it repeat the last pixel line, that is in fact the second row of pixel on the texture. and break the seams…
same for the last row of pixel from the bottom of the plane3D, it repeat the before last row of pixels.

Alpha:Grab Doc, does exactly the same than Texture:Grab doc.

it would give you something like that when you apply an offset in photoshop (zoom at 200% ) :


Next post i will show how my workaround is somehow a little bit better cause it make the use of BPR possible.

Edit : i forget to talk about ZappLink, but it like mrgbzgrabber and with autocrop disable.

still investigate on this
the most important question i have, is probably this question :

Is the mrgbzgrabber tool is compatible with BPR preview and best ?
that would mean i must to export my render passes from the texture and alpha section .

I am going to share my sources , that’s a good point to show how i want to reproduce workflow based on main PRo tips

So here is a list of tutorial about tiling textures made in Zbrush

tutorials :

Destructive 2.5D worflow by Bradford Smith nice tutorial serie full of very goods informations, so at some point it could be used to generate extra texture map to compose with in photoshop.


Destructive workflow with photoshop fix on seams and utilize the spot healing tool.

https://www.youtube.com/watch?v=jHuprKbYW08 ( fix seams in photoshop using the paint brush which is not good practice ;))

In that tutorial there is an important information, bpr render, with best enable and remove shows or use a flat shader to render so you get ride of the seam issue.
This is not working for me with zapplink, it copy the first vertical pixel row and do the same on the bottom, which break the continuity of the tiling seams.

Tate Mosesian tiling series ( Mix destructive + none destructive workflow , still in my mind if one of the element can’t to be edited later, it become a real destructive workflow )
So in this tutorial serie Tate Mosesian utilizes Zapplink to load the render in Photoshop and use the layers > fill with “content Aware” enable to fix the seams.

Tiling with Wrap mode

https://www.youtube.com/watch?v=e04k4Cz8UBo (wrap mode)

this one is nice because the plane3d is greatly improved to reduce the number of polygon on the paint you scult with the wrap mode enable
also i know there is a tweak with the suddivision of the plane 3D mesh to make the wrap mode to work correclty, when you add more tiling level ( wrap set to 2 or more)

it’s also interesting because he use the bpr render passes slots to save all the passes.
But the fix for the seams issue is not an acceptable fix ( he copy the 3 last pixel and past them onto the black border
, and reeat that on vertical axis).

that one has a really strange method to make it tile, it utilizing the symmetry the make the seams to match the opposed border.
not very interesting.

tutorial with NanoTile /nanomeshes :

this one is very interesting because i when to make it a possibility in my plugin.
I know Joseph Drust use the mrgbzGrabber with BPR and Preview mode
The tutorial just don’t show how the seams are in photoshop.

With maya worflow, interesting but not what i want, because i want to just do everything within Zbrush.Even fix seam issue in photoshop is really annoying to me.


technical discussions :


Very interesting , this bring my there Marcus :slight_smile:


Your script is the PERFECT way for fixing Seams issue .

Can you explain me Marcus, a little bit about your process with that plugin, there is no artfact on the seams, like it is with mrgbzgrabber when i use it without autocrop even with bpr set to best.


I **** the seams, hm, i fixed the sums arg
the best has been done, no need of you script Marcus :slight_smile:

I use a marge when i render, and a framer subtool that is a little bit bigger then the tilable area.
for 10241024 the canvas is 10321032
when i load all bpr render passes in photoshop, even SSS and AO ( it’s important)
I stack them all into layer, i just apply a canvas size from 1032 to 1024
and it give me a perfect seamless texture without any artfact, or padding issue that we get with mrgbzgrabber and grab doc(alpha/texture)

so you just don’t need to focus on the seams, just at the very end when you are done !!!

I was about to make something using texture /alpha grab doc and but i don’t need this anymore, even if i will add that possibility for people that make habit of the function.
I found how to drop and transform:fit a polymesh, when the canvas is fully empty, that can still be interesting for later.

the new issue i running through, is nudging the subtool , because it seems to take in consideration the ztool boundary
to define what represent the value of 100 when i apply a deformation:offset.
so it offset base on the large plane that is bigger than the tilable area.
or I have to found the correct deformation value for the offset based on the bigger plane scale.

tilable texturing with a None destructive workflow using BPR render and QuickSketchMaster Plugin + Photoshop .


Enjoy :wink:

Great stuff, nice solution! :+1:

Glad you like Marcus :wink:

Have a look at this theard on polycount, i started to publicly communicate about the plugin.

dang, i reach a pick, a f***ing pain in the neck :confused:
it looks like i had reached the maximum number of variable i can use into a Zscript. is that possible Marcus ?

ctrl + f on vardef and i get 270 entries, probably less that are really in use i can’t to measure that.
i had this same error message and it was a typo , but the message remained the same.


i get the same issue with no typo or anything else, if i remove a block of vardef that are not relly complete, the ui button that give me this issue has no more issue.
that would onfirm i hit the maximum of vars that can be into one ZSC file.

If i have to make a full revamp what make sense, is a split into two plugins
but i must to sort function that are one ech side to remain indepednet, but i can check the statement of the plugin 1 from the plugin 2.

that’s just crazy, as i get screwed :confused:
and i use just the state of the ui of the second plugin to base the action from the plugin 1

Yes, there is a limit to the number of variables. I can’t remember what it is - something like 1024 or 2048. You may be able to get around the limit by using a list variable:

[VarDef, myListVar(2048),0]//defines a list variable of 2048 items

But I can’t remember if that will add to what’s allowed or not. I generally using memory blocks for complex plugins because they persist for the ZBrush session. For floats you can use [MVarDef] etc. which is they easiest way. I wouldn’t create lots of memory blocks - use one or two and then save/recall the values using the index or offset.

Hello Marcus , thx you for the feedback as alway you are welcome and the help is highly appreciated.

I think that it’s not fully correct, i had a try creating a new plugin with
256 vardef and a ui button that Varset from 0 to 1 all of them and it stucks at the 257th vars.
you exemple varlist(2048) is consideraed as array vars, that probably why it can support 1024/2048.

Which is for very very small amount ,just as an example, imagine you export a model, and grab the each vertex position to export a model,
1 vertex position = 3 values, 9 values are necessary to draw a complete triangle.

which mean you could only write the first 227 triangles and not anymore. that’s really cheap :confused:
Even if you can make the var to contain the full position of the vertex,into one Var, it just multiply by three the number of polygon you could export.
i tell you all this just to explain that limitation should not be so low.

Ok i know we have no need of this from Zbrush but it’s sad there is no access to the Zbrush api to make more complex
plugin and speed up the process. instead of doing operation on export obj file then you trat with your own library and executable.

another example that is another challenge to me :
there is no way to code something to get the position of Arraymesh/nanomesh instances position, rotation, scale.
there is nothing that can be done to achieve this.
Nanomesh to one to brush then make make on arraymesh is just an operation that should never been done it kill the perf in Zbrush make the app to not respond for a long time. i lost two day doing some workflow test using nanomesh and araymesh to make complex bricks textures.

So to resume, there is some vars that can be stored as a varlist,
but much of them can’t to be stored with this format varname(1),varname(2) in my plugin
in the same spirit there is no real interest to write into a variable on the disk to declare that i have enabled an option on the
plugin ui.

But i might have found a way for it to work, just that finally doesn’t work :confused:

let me explain this :

i have Two plugins i want to combine into just one UI.

into the header i should have all the modules that are independent, and that just need to get the status of the current settings
into plugin tail.

[IGet, zplugin:myplugin:button1] it works
[ISet, zplugin:myplugin:button1] it doesn’t works
[Iclick, winID] doesn’t works too

To combine both zscript into an unified UI i must to add this at the end of the header plugin

[RoutineDef, addons,
[FileNameSetNext, “quicksketchMaster_tail.txt”]
[IPress, “ZScript:load”]
[RoutineCall, addons]

this way when i reload the main plugin it also loads the second plugin, but it doesn’t reorder the UI,
all content in the tail will be added after.

for example, if i want to preserve this structure, i have to add render button and all the web icons, to be on the tail.

The problem is that it makes the ui defined in the header to not working anymore, the button do not change their status when
I click on them.

Some button works completely, some are stopped in their process and and button do not respond.

So maybe i should stop to try to unify both plugin, and mind it differently.

I got a new idea

i create a custom menu and then i load my plugin component into it.

  • plugin 1
    ** plugin 2
    *** plugin 3
    (?) uncertain

Game tools ( is a custom menu, i load using custom layout )

  • Document Settings*
  • PSD Document Bridge*

  • Texturing Tools**
  • Workflow Tools**
  • Quicksketch master** (quicksketch tools)

  • Workflow Presets
  • Render Options
  • Render Passes
  • Preferences*** (?)
  • License Activation
  • Debug Tools
  • About

But two big constraints :

  • you must to load the ui and then load the plugin or the custom menu is empty, at next zb startup.
  • not easy to integrate into the custom user ui.

i had to create the subpalette withing Zbrush and export the cfg file, if i remove this subpalette the plugin load badly into the ui, and i get a palette that obstruct to click on the menu.

Also to make sure it load correctly i suppose a can script the creation of custom menu , and a second button that load the activate the plugin.
but it also meaning in second time that the user must to disable the plugin before to close zbrush ?
that a little bit too confuse for me now :confused:

sound like i need for a messy to bring me a solution
using Custom menu is quite nice, having a dedicated menu in the tray is fantastic, as you can keep all menu opened and i looks more fancy with the subpallette.

package :

at the installation the user extract pluginName.cfg into Zstartup\UserInterfaceLayout
and all the rest into Zstartup\zplugs64.
note : I can only share the ZSC not the Source code.

so th euser run Zbrush, it will show the new menu if the user switch the layout
so i need to make something to script the creation of the menu into the user layout.
that not a problem.
just that it works only when i delete my plugin_A.zsc , and i load the plugins in order ( at this moment i use a script from a plugin that is part of my dev tools, so it completely independent. )
and at this moment it load the plugin correctly into the custom menu.
if i shutdown zbrush and then restart it i get an error because of the first [IEnable, “plugin:path:of:the:button”] ( a switch)

I am not sure why… i get more and more confuse now.

And some more question that still unresolved, what when i will load plugin_b , etc…
I am not sure what to do even execute macro at the startup is not changing anything ( my guess, i haven’t tested yet, not sure )

new attempt, i feel not far to bring that to work, what you think ? :slight_smile:

plugin package :

  • \plugindatadir\
  • \ZStartup\userInterfaceLayout\pluginName.cgf
  • \ZStartup\Macro\ActivatePlugin.txt
  • plugin_A.zsc
  • plugin_B.zsc
  • plugin_c.zsc

in plugin_A, _b and _c

i use this scheme :
//define routine and vars in the header

[Routinedef, routine01,

[Routinedef, routine02,

[If, [IExists , “MyMenu”],

[ISubPalette, "MyMenu:section1"] [IButton, "MyMenu:Section1:button1", "tooltip", //commands [RoutineCall, routine01] ,,1,,,0 ] [IButton, "MyMenu:Section1:button1", "tooltip", //commands [RoutineCall, routine02] ,,1,,,0 ]

//here the code that create the custom menu within the current layout, and reload the plugin again so it finally found the custom menu.
//it could check the zstartup/macro and in rescuehelp to reload the plugin"S" from there.
]//end IF

it doesn’t work, the plugin load and give no error but nothing happen, and if i reboot zbrush there is an messga that say it skip the plugin from loading to start zbrush :confused:
Edit : i take care to only have button sliders switch, no vardef or routines and still not compiling :frowning:

EDIT 2 : IT works, but with another plugin that only have one button !

iam investigating :idea:

track 1

a special character like /* comentted function */

track 2

exceed the number of call we can make using [If] ?

track 3
a function has to much if statement nested into each other

i still don’t know what causing this, but i am progressing slowly

i have
myplugin_finale.txt // my source backup
myplugin_temp.txt // my source from the one i will pickup routine and UI stuff
mynewplugin_a.txt // here is the first plugin to load and in the one i get confortable to work
mynewplugin_b.txt // same than previous item
mynewplugin_c.txt // same than previous item

in zbrush i must to load each mynewplugin_a, _b, _c from zbrush to compile them, but when done it works
unfortunately i must to load them manually from Zscript:load and then i load the zsc file.

in my external plugin dev tools i have that :

[RoutineDef, LoadPlugin1,

[If, [IExists , "GameTools:About"], //[Note, "gametool menu exists",,2] [FileNameSetNext, "GameTools_a.zsc"] [IPress, "ZScript:load"] ,//else [Note, "gametool menu doens't exists",,2] ]

[RoutineDef, LoadPlugin2,
[note, “plugin b loading…”,5]
[If, [IExists , “GameTools:About”],
//[Note, “gametool menu exists”,2]
[FileNameSetNext, “GameTools_b.zsc”]
[IPress, “ZScript:load”]
[Note, “gametool menu doens’t exists”,2]
[RoutineDef, LoadPlugin3,
[If, [IExists , “GameTools:About”],
//[Note, “gametool menu exists”,2]
[FileNameSetNext, “GameTools_c.zsc”]
[IPress, “ZScript:load”]
[Note, “gametool menu doens’t exists”,2]


[ISubPalette, “Zplugin:Red Dev”]
[IButton, “Zplugin:Red Dev:GameTools reload”," Reloading GameTools ZPlugin",

[RoutineCall, LoadPlugin1] // it load correctly [Delay, 5] //does nothing, i thought it would be helpful to wait for the plugin_a to load before the plugin_b and so on [RoutineCall, LoadPlugin2] //doesn't load [Delay, 5] //does nothing [RoutineCall, LoadPlugin3] //doesn't load


i continue to investigate

at the end of each plugin i still have that :

[note, “gametools menu doesn’t exists”,5]
]//end of the [If , [IExists, “GameTools”],

i notice now that is simply impossible to create a custom menu, because to add something in the menu when i load the pluginS, it require an existent subpalette, and that not possible to create this, even as i haven’t found a way to create the menu with a specific string “GameTools”.