• Godot HelpShaders
  • Spatial shader: How to access fragment color produced in previous material's render passes?

Hi there,

maybe I completely misunderstood how shaders work, but I'm trying to create a ShaderMaterial that would, in a second render pass, apply some shader to an object's texture as defined by a SpatialTexture in the first render pass. I would have expected the fragment built-in COLOR to provide each pixel's color (including transparency) "as calculated so far" by previous passed, but with my current approach I get some (at least to me...) weird results.

A minimum (non)-working sample project consists of two MeshInstances, both having a SpatialMaterial featuring the Godot icon as albedo texture. The right mesh additionaly has a ShaderMaterial with the following shader code as second pass:

shader_type spatial;
render_mode unshaded;

void fragment() {
    ALBEDO = UV.x * COLOR.rgb;
    ALPHA = COLOR.a;
}

I would have expected the right mesh to display the Godot icon as a kind of horizontal brightness gradient; however, it seems that only the previously transparent pixels are affected and turned into non-transparent gradient pixeld.

What am I doing wrong?

Cheers, and happy Easter--

-- Torsten

The COLOR variable in the shader does not hold the previous render pass. It only holds the color of the vertices. You see, vertices are able to hold their own colors, and that variable is what holds those values. As of the current version, you cannot get the previous passes color.

I suggest you look into the docs and learn how Godot's shaders function. https://docs.godotengine.org/en/3.2/tutorials/shading/index.html

Indeed, as far as I know you might be able to use a blending variable but nothing more.

Unless the above is sufficient to you, since you are already writing a custom shader, you probably might as well just do the whole thing in the single shader material.

To give you more insight, all the next_pass feature does is give the associated mesh an extra material to render with, and nothing more.

Thanks everyone for you insightful comments! Things became a bit clearer to me now. (And yes, I had read the documentation before asking my question -- it's just that, at least in my experience, you can't learn and truly understand programming concepts by merely reading about them -- rather, you have to actually try to solve a concrete problem by applying them. And a little shader for post-processing an existing texture seemed a good entry-level problem to me.) What I still don't understand, though, is why those non-transparent pixels of the first pass don't just get overdrawn with the color produced by the fragment code shown above...

Cheers --

-- Torsten

Most likely because COLOR.a evaluates to 1.0 by default, making the alpha full in every fragment.

@SIsilicon28 said: Most likely because COLOR.a evaluates to 1.0.

To me, that doesn't explain why all transparent pixels (the ones at the corners) apparently do get affected by the ALBEDO =... assignment, while all non-transparent pixels retain the color of the underlying primary material. It's my understanding that either all (ALPHA = 1.0) or no (ALPHA = 0.0) pixels should show the ALBEDO value.

Cheers --

-- Torsten

3 years later