This is the testing Godot forums! All forum posts unique to this forum will be deleted! Please use the main forums here for any posts you want to keep. All forum rules still apply.

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

tcrasstcrass Posts: 30Member

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


  • SIsilicon28SIsilicon28 Posts: 693Moderator
    edited April 2020

    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.

  • MegalomaniakMegalomaniak Posts: 2,580Admin

    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.

  • SIsilicon28SIsilicon28 Posts: 693Moderator

    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.

  • tcrasstcrass Posts: 30Member

    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

  • SIsilicon28SIsilicon28 Posts: 693Moderator
    edited April 2020

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

  • tcrasstcrass Posts: 30Member

    @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

Leave a Comment

Rich Text Editor. To edit a paragraph's style, hit tab to get to the paragraph menu. From there you will be able to pick one style. Nothing defaults to paragraph. An inline formatting menu will show up when you select text. Hit tab to get into that menu. Some elements, such as rich link embeds, images, loading indicators, and error messages may get inserted into the editor. You may navigate to these using the arrow keys inside of the editor and delete them with the delete or backspace key.