GLSL Get Fixed-Pipeline Texture

toneburst's picture

Anyone know if it's possible to fetch the texture applied to an object (say an image piped into the Image port of a Sprite) if the object is inside a GLSL Shader?

I'd like to be able to have a Iterator create a number of Sprites with different textures applied to them, but modulate the colours of the Sprites with a GLSL Shader. Because different images will be applied to each Sprite instance, I can't simply use a sampler2D input into the Shader itself.

Possible? Impossible? Pointless...?

a|x

dust's picture
Re: GLSL Get Fixed-Pipeline Texture

i don't know if its possible but i think its a valid a request. i ran into this problem while making a displacement shader. i wanted to get the displaced vertex's out so i could use them on a separate mesh up one level so i could get the lighting patch to work on with my displacement. i don't really know enough about glsl to offer any real advice but maybe thats on that is something to be addressed on the kernel level if not with the glsl language all together. i understand what your asking you want to pass the info like "varying"

maybe a plugin could do that for you. i don't know much about how glsl works with cocoa seeing i have really only played a bit with he iphone but lets assume that you have a teapot that has a set of variables. i would think in cocoa you would be passing the glsl info to the variables of the teapot somehow or you would be using some sort of get/set ? in any case theoretically you could query the teapots variables and use them as some sort of output to your plugin. it has to be possible someway.

right now it seems like magic cause you place your teapot inside the glsl patch do some uniform floats to modify but you connect nothing up to the teapot. now if you made a teapot that had lets say an OSC object inside of it as well that would datagram your modifications then you might be able to but like i said you would know better than me when it comes to the glsl side of things.

just seems like it has to be built into the language or you have to make some sort of plugin that queries the state of an object your modifying.

either way you perceive this problem there should be away to get your data out of the shader or to pass it down the line.

i don't know enough about kernels and how you would pull data from their respective instantiations. my java teacher explained how you can save a list of data from the heap / stack, of constants and instantiated objects etc... as a memory array dump or something. i guess this would be like a nib file ? so maybe there is some kind of kernel hack you can do as well but thats way beyond me.

defiantly post if you figure away to do this, i would be interested in the displacement context if at all possible.

gtoledo3's picture
Re: GLSL Get Fixed-Pipeline Texture

I had to solve this same scenario one time (as I'm understanding it), and I ended up setting up the identical macro inside of two different render in images, controlled by the same patch time, and used CI blending/blend with mask/whatever mode exactly is called for, to make the desired looking composite.

That might sound like it could be bad for performance, but I get good performance from that (at least in many scenarios), and in a way those CI modes are really tailored for what (I think) you're describing.

Dusty's scenario sounds a little bit different from a quick read through... doesn't sound like what I'm saying is an applicable workaround for that at all.

What are you trying to do on the GLSL with the sprites as far as color modulation; some kind of multi-color gradient or pattern but on each sprite? I'm guessing it's not a simple "one color/one sprite" thing, because of the need for the GLSL.

cwright's picture
Re: GLSL Get Fixed-Pipeline Texture

not possible -- the glsl texture stuff doesn't touch the fixed function texture units, so you can't really access the pixel data (though, incidentally, you can access the texture coordinates, I think, by abusing the texCoord stuff)

the "correct" way to do this (outside of QC) is to simply change the texture input on the shader. For QC, you have to iterate to do this, which is much more expensive.

fsk's picture
Re: GLSL Get Fixed-Pipeline Texture

if the images are static than you could put all of them in one big image (or more if that gets too big) then change the texture coordinates for each sprite in the vertex shader to get a different part of the big image on each of them. you could use the super glsl grid to pass the index to the shader or abuse the color input of the sprite to pass the the index (haven't tried this one but i think it should work).

this is all useless if you need animated textures though:/.

toneburst's picture
Re: GLSL Get Fixed-Pipeline Texture

Quote:
not possible -- the glsl texture stuff doesn't touch the fixed function texture units, so you can't really access the pixel data

Ah, OK. Is this a QC quirk, or just how GLSL shaders work?

Quote:
the "correct" way to do this (outside of QC) is to simply change the texture input on the shader. For QC, you have to iterate to do this, which is much more expensive.

I didn't think you could iterate GLSL Shader patches. It certainly didn't used to work, unless you render each iteration inside a Render In Image patch.

a|x

toneburst's picture
Re: GLSL Get Fixed-Pipeline Texture

Quote:
if the images are static than you could put all of them in one big image

That's an idea. I might try that. The only problem is the amount of Photoshop work required to tile 100 images into a single texture...

Quote:
...or abuse the color input of the sprite to pass the the index (haven't tried this one but i think it should work)

Funny you should mention that. When I was corresponding with cwright about the development of the Super GLSL Grid patch, I did actually try that. It worked pretty well, but obviously you're limited to just being able to pass in 4 float variables (unless you do some fancy packing tricks, which will lose precision). I'd only need 2 floats to pass in X/Y offsets to the texture coords.

a|x

usefuldesign.au's picture
Re: GLSL Get Fixed-Pipeline Texture

toneburst wrote:
That's an idea. I might try that. The only problem is the amount of Photoshop work required to tile 100 images into a single texture... a|x
I know your JS is better than mine tb and I'm pretty sure I can write a .xjs script to grab all the images in a folder (100+) and paste them onto a grid (10.imageX by 10.imageY) on a massive PS canvas.

As for the GLSL… I would love to know what you're all talking there…haha.

toneburst's picture
Re: GLSL Get Fixed-Pipeline Texture

The idea is to have a stack of sprites (up to 100), arranged along the Z-axis, and use GLSL to set opacity and colour based on distance from a movable point in 3D space. It's just a variation on the MediScan piece I did a while back.

a|x

fsk's picture
Re: GLSL Get Fixed-Pipeline Texture

[quote]That's an idea. I might try that. The only problem is the amount of Photoshop work required to tile 100 images into a single texture...[quote]

thats why you don't do it by hand ;). i did it in processing but you could also do it with QC, with directory scanner, render in image and the image writer plugin.

keep in mind that the texture can only be 4096x4096 big.

toneburst's picture
Re: GLSL Get Fixed-Pipeline Texture

Quote:
As for the GLSL… I would love to know what you're all talking there…haha.

Me too.

a|x

toneburst's picture
Re: GLSL Get Fixed-Pipeline Texture

True, true...

I'll get around to trying it sometime. Photoshop's Thumbnail action might equally do it, with a bit of tweaking.

Incidentally, I think the max texture size varies across different GPUs.

a|x

franz's picture
Re: GLSL Get Fixed-Pipeline Texture

Photoshop has a contact sheet script that will do this for you automatically

toneburst's picture
Re: GLSL Get Fixed-Pipeline Texture

The Super GLSL Grid patch appears to be broken when placed inside an Iterator in Snow Leopard/QC 4. I think someone mentioned this a while back. Is this an easy one to fix, cwright?

a|x

toneburst's picture
Re: GLSL Get Fixed-Pipeline Texture

Yes, sorry: that's what I was thinking of.

a|x

cwright's picture
Re: GLSL Get Fixed-Pipeline Texture

it's how GLSL works (plus some QC details) -- you have sampler2Ds for textures in GLSL. To set them, you need to bind your texture names (positive integers) to the various GLSL inputs ("uniforms" in GLSL parlance); the QC patch does this for you in a nice, friendly way. When a texture is set on the GLSL patch, it does the binding. When a texture is set by the patch inside, it sets the texture it receives to another texture unit -- which GLSL isn't aware of/has no way to access.

regarding working in iterators -- they work, and always have as far as I remember (it's just that setting/resetting all the inputs and the shader itself can be an expensive operation in GLSL)

PreviewAttachmentSize
iteratedGLSL.qtz5.58 KB

cwright's picture
Re: GLSL Get Fixed-Pipeline Texture

Yes, max texture size does vary across GPUs (at least 1024, the smallest I've seen on recent hardware is 2048, and most is probably 4096 now, but for slightly older stuff 2048's a safe bet).

cwright's picture
Re: GLSL Get Fixed-Pipeline Texture

No idea -- I've not had much time to test the more esoteric patches, and that's one of them.

toneburst's picture
Re: GLSL Get Fixed-Pipeline Texture

Understood. Would be good if you could have a look at it sometime though. That patch is most useful inside an Iterator, so it not working inside one makes it a bit useless, really- which is a shame...

a|x

cwright's picture
Re: GLSL Get Fixed-Pipeline Texture

Can you be a bit more expressive than just saying "it's broken"? I probably won't have much time to look at it in the near future, but having some idea of what's going on may spark some ideas while I'm working on other stuff.

toneburst's picture
Re: GLSL Get Fixed-Pipeline Texture

Sorry, yes, that wasn't very specific, was it... Apologies.

I will make a little example QTZ.

a|x

gtoledo3's picture
Re: GLSL Get Fixed-Pipeline Texture

Opening up the sample composition is a good start on a setup that reproduces the bug.

I'm the "someone". I always knew I would be someone's someone :)

It does work outside of the iterator.

gtoledo3's picture
Re: GLSL Get Fixed-Pipeline Texture

Ok, my suggestion totally doesn't work for that kind of setup either :)

Now I see what you're getting at. That would be really cool if it could work.

toneburst's picture
Super GLSL Grid/Iterator Non-Working Example

Here's a very simple example. Works with the standard GLSL Grid, doesn't render anything at all with the Super GLSL Grid patch.

The white square in the centre is another Super GLSL instance, outside the Iterator.

a|x

PreviewAttachmentSize
tb_sGLSLGrid_Iterator_Brokeness.qtz9.44 KB

toneburst's picture
Re: GLSL Get Fixed-Pipeline Texture

I've just been messing around with the idea of having a 'contact-sheet' of volume slices, and using per-instance color settings to have a stack of sprites in an Iterator display consecutive cells.

Seems to work pretty well! Thanks for the idea.

a|x

PS apologies for the big file. There are several large textures embedded in the composition.

Also, the texture-size may exceed the max texture size on some systems. I'll probably make smaller versions for future releases.

PreviewAttachmentSize
tb_MediScan_3_021009.qtz9.01 MB

gtoledo3's picture
Re: GLSL Get Fixed-Pipeline Texture

Cool! This is great.

I'm so glad you ended up doing the tile thing... there are tons of auto-tiler apps out there, and I was going to try to poke around for one to send you. It's been awhile since I've had to do this (auto-tiling), and used to do this in an older working environment on Windows with a fake (well, real), print driver.

toneburst's picture
Re: GLSL Get Fixed-Pipeline Texture

I'm sure you can tile stuff using Maths Expression and/or Interpolation patches inside an Iterator, but I never managed to get that to work. The does the job, though.

a|x

Matfink's picture
Re: GLSL Get Fixed-Pipeline Texture

Not sure on your hardware here, but I found that with NVidia h/w I could access the current fixed pipe texture in a shader by just declaring and using a 'uniform sampler2D MyFixPipeTex;' in the frag shader (not setting this from the app at all!). Of course this is probably totally unsupported/undefined but seems to work on all NV hardware I've tried it on 8) Ati is out the window as it fails validation with this setup.

cwright's picture
Re: GLSL Get Fixed-Pipeline Texture

Are you doing this within QC, or in a custom app? In QC, doing your trick results in an input on the GLSL shader patch, which QC will then manage (either setting it to 0 if nothing is attached, or to the input texture on the shader -- the renderer's texture is set to another GL texture, not bound to any GLSL samplers).