Texture Coordinate vs Function Vector 2 | Texture Sampler vs Composition

Dear Shader Lords of Spark AR,

It’s been quite a while since I notice the difference between them (the title).
Back then, I was still a newborn in the vast shader universe to understand it.
But now I’m more like a baby who learn how to walk, so please bear with me and go back to the basic for a minute.

For today’s problem, it all started when I tried to learn sparksl from Adam Ferriss’ Github: https://github.com/aferriss/sparksl-shader-examples

I tried the basic RGB Split or Chromatic Aberration cuz I thought it’s a good place to jump right in.
He explain everything so crystal clear, I understand instantly how the code works.
I edited the script to put the offset outside, not as a float but as a vec2 so I can access each axis independently on patch editor. Easy, No problem at all.
Everything is buttery smooth until I tried to put the UV variable outside, here is the code:

using namespace std;

vec4 main(Texture2d tex, vec2 uv, vec2 offset) {

  // Sample the texture three times with different offsets
  auto red = tex.sample(uv + offset);
  auto green = tex.sample(uv);
  auto blue = tex.sample(uv - offset);

  // Use just one channel from each texture
  return vec4(red.r, green.g, blue.b, 1.0);

As we see in the code, there is no problem at all. The compilation finished successfully.
It was until I tried to plug in my go to UV provider, Function: Vector 2 to the uv input node.
It throws out an error!! But it works fine if I plug in Vertex Attribute: Texture Coordinate with or without Fragment Stage patch. So it must be because the code is using tex.sample (Texture Sampler in patch form) and not Composition (but I don’t know how to write down Compositon in sparksl or script.)

From there I tried to see the behavior of Texture Sampler VS Compostion in patch editor:

Image 1

I make 2 “group”: TexCoord, and FuncVec2.
I split both of them horizontally and color code them with Magenta and Yellow.

As we can see in the image 1 above, both of them works the same way.
But, are they really the same way under the hood? let’s take a look at Image 2.

Image 2

In here, I swizzle the red green 0blue and 1alpha (rg01) to visualize the uv.
Also, I don’t multiply the result with the color code cuz it will mess up the look and because we have establish that left side is for the TexCoord and right side is for the FuncVec2.

And yup, both are identical, but what if In the TexCoord we skip the fragment stage?

Image 3a

Image 3b

And there you go, we see a difference. it only shows the pixel on the 0,0 coodinate and not the full screen.

So, Is Function vector 2 is the same thing as Texture Coodinate + Fragment Stage?
If it is the same thing, we can just replace Texture Sampler with Composition patch right? Lets try it!

Image 4a

Nope. Texture Sampler throws out an error, while composition patch is able to process the Texture Coordinate + Fragment Stage. Check out Image 4b below to see what the error says:

Image 4b
Image 4c

So it seems like the texture sampler is the problem here.

With that said, here are my questions:

  1. can someone explain to me what is going on here?
  2. can someone show me how to write down the code from Image 1 where I comment them as “TexCoord” and “FuncVec2” in script and sparksl? Especially I want to see the difference in the code between “Texture Coordinate vs Function Vector 2” and “Texture Sampler vs Composition” to understand what’s happening under the hood.
  3. What is / How to write Function: Vector 2 patch and Composition patch in sparksl or script in general? cuz I use them A LOT in patch editor.

Let’s start from there. It’s a bit (a lot) confusing to read the documentation in Spark website.
I wish they could just put a side by side view in each script or shader documentation of how it looks in patch editor form.

Shoutout to Adam Ferriss for the valuable github repository!!!
“What we do in live, echoes in eternity” – Maximus (Gladiator)

I made a small repo for this since I can never remember how it works. I’ve never actually needed to use the function/composition in spark SL. The lazy solution is to just use a shader render pass after your SL patch and it will become sample-able again.

I’m still not sure how to get a function into a shader, but it seems like texture coordinates work just fine for this purpose.

1 Like

Umm… Sorry Josh, I’m not a coding expert yet. So i’m a bit confuse in reading the example code.
Maybe can we simplify it like from the very basic?

So this image (Image A):

In SL is this code below, right?

vec4 main(std::Texture2d tex) {

  vec2 uv = fragment(std::getVertexTexCoord());
  vec4 color = tex.sample(uv);

  return vec4(color);

What I wanna know is the code of this exact image (Image B):
Image B image

I’m curious to see the side by side comparison between them in SL form. Because visually in patch editor it looks the same, only different patch.

Ah, also, The first input for Image A and Image B is just the default camera texture.

Minor detail here, you can just return color; since it’s already a vec4. No need to convert.

I’m still not sure how to pass in function into SL. I’m not sure what type to assign to it, but the texture coordinates will work as a vec2.

Here’s the simplest example that just creates a sampleable output. I haven’t tested it though :slight_smile:

function<vec4(vec2)> composition(function<vec4(vec2)> tex){
  return[](vec2 uv){
function<vec4(vec2)> main(function<vec4(vec2)> tex, vec2 uv){
  function<vec4(vec2)> composed = composition(tex, uv);
  return composed;