shader中有多个pass只有第一个pass生效

  • Creator 版本:3.8

  • 目标平台:

  • 重现方式:

  • 首个报错:

  • 之前哪个版本是正常的:

  • 手机型号:

  • 手机浏览器:

  • 编辑器操作系统:

  • 重现概率:

刚接触shader,想在第二个pass中获取第一个pass处理完后的sampler2D再进行处理,但是发现只有第一个pass的效果实现了
// Copyright © 2017-2020 Xiamen Yaji Software Co., Ltd.

CCEffect %{

  techniques:

  - passes:

    - vert: sprite-vs:vert

      frag: sprite-fs:frag

    - vert: blur-vs:vertBlur

      frag: blur-fs:fragBlur1

    - vert: blur-vs:vertBlur

      frag: blur-fs:fragBlur2

}%

CCProgram sprite-vs %{

  precision highp float;

  #include <builtin/uniforms/cc-global>

  in vec3 a_position;

  in vec2 a_texCoord;

  in vec4 a_color;

  out vec4 color;

  out vec2 uv0;

  vec4 vert () {

    vec4 pos = vec4(a_position, 1);

    pos = cc_matViewProj * pos;

    color = a_color;

    uv0 = a_texCoord;

    return pos;

  }

}%

CCProgram sprite-fs %{

  precision highp float;

  #include <builtin/internal/embedded-alpha>

  #include <builtin/internal/alpha-test>

  in vec4 color;

  in vec2 uv0;

  #if USE_TEXTURE

    #pragma builtin(local)

    layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture;

  #endif

  float luminance(vec4 o) {

    return 0.2125 * o.r + 0.7154 * o.g + 0.0721 * o.b;

  }

  vec4 frag () {

    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE

      o *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0);

    #endif

    float val = clamp(luminance(o) - 0.3, 0.0, 1.0);

    o *= color;

    o *= val;

    ALPHA_TEST(o);

    return o;

  }

}%

CCProgram blur-vs %{

  precision highp float;

  #include <builtin/uniforms/cc-global>

  in vec3 a_position;

  in vec2 a_texCoord;

  in vec4 a_color;

  out vec4 color;

  out vec2 uv0;

  out vec4 uv01;

  out vec4 uv23;

  vec4 vertBlur () {

    vec4 pos = vec4(a_position, 1);

    pos = cc_matViewProj * pos;

    color = a_color;

    uv0 = a_texCoord;

    uv01 = vec4(a_texCoord.x - 1.0 / 842.0, a_texCoord.y - 1.0 / 550.0, a_texCoord.x + 1.0 / 842.0, a_texCoord.y + 1.0 / 550.0);

    uv23 = vec4(a_texCoord.x - 2.0 / 842.0, a_texCoord.y - 2.0 / 550.0, a_texCoord.x + 2.0 / 842.0, a_texCoord.y + 2.0 / 550.0);

    return pos;

  }

}%

CCProgram blur-fs %{

  precision highp float;

  #include <embedded-alpha>

  #include <alpha-test>

  in vec4 pos0;

  #if USE_TEXTURE

    in vec2 uv0;

    #pragma builtin(local)

    layout(set = 2, binding = 11) uniform sampler2D cc_spriteTexture;

  #endif

  vec4 fragBlur1 () {

    #if USE_TEXTURE

      vec2 tex_offset = vec2(1.0 / 842.0, 1.0 / 550.0);

      vec3 result = texture(cc_spriteTexture, uv0).rgb * 0.227027;

      result += texture(cc_spriteTexture, uv0 + vec2(tex_offset.x * 1.0, 0.0)).rgb * 0.1945946;

      result += texture(cc_spriteTexture, uv0 - vec2(tex_offset.x * 1.0, 0.0)).rgb * 0.1945946;

      result += texture(cc_spriteTexture, uv0 + vec2(tex_offset.x * 2.0, 0.0)).rgb * 0.1216216;

      result += texture(cc_spriteTexture, uv0 - vec2(tex_offset.x * 2.0, 0.0)).rgb * 0.1216216;

      result += texture(cc_spriteTexture, uv0 + vec2(tex_offset.x * 3.0, 0.0)).rgb * 0.054054;

      result += texture(cc_spriteTexture, uv0 - vec2(tex_offset.x * 3.0, 0.0)).rgb * 0.054054;

      result += texture(cc_spriteTexture, uv0 + vec2(tex_offset.x * 4.0, 0.0)).rgb * 0.016216;

      result += texture(cc_spriteTexture, uv0 - vec2(tex_offset.x * 4.0, 0.0)).rgb * 0.016216;

      vec4 FragColor = vec4(result, 1.0);

      ALPHA_TEST(FragColor);

      return FragColor;

    #else

      return vec4(1.0);

    #endif

  }

  vec4 fragBlur2 () {

    #if USE_TEXTURE

      vec2 tex_offset = vec2(1.0 / 842.0, 1.0 / 550.0);

      vec3 result = texture(cc_spriteTexture, uv0).rgb * 0.227027;

      result += texture(cc_spriteTexture, uv0 + vec2(0.0, tex_offset.x * 1.0)).rgb * 0.1945946;

      result += texture(cc_spriteTexture, uv0 - vec2(0.0, tex_offset.x * 1.0)).rgb * 0.1945946;

      result += texture(cc_spriteTexture, uv0 + vec2(0.0, tex_offset.x * 2.0)).rgb * 0.1216216;

      result += texture(cc_spriteTexture, uv0 - vec2(0.0, tex_offset.x * 2.0)).rgb * 0.1216216;

      result += texture(cc_spriteTexture, uv0 + vec2(0.0, tex_offset.x * 3.0)).rgb * 0.054054;

      result += texture(cc_spriteTexture, uv0 - vec2(0.0, tex_offset.x * 3.0)).rgb * 0.054054;

      result += texture(cc_spriteTexture, uv0 + vec2(0.0, tex_offset.x * 4.0)).rgb * 0.016216;

      result += texture(cc_spriteTexture, uv0 - vec2(0.0, tex_offset.x * 4.0)).rgb * 0.016216;

      vec4 FragColor = vec4(result, 1.0);

      ALPHA_TEST(FragColor);

      return FragColor;

    #else

      return vec4(1.0);

    #endif

  }

}%

是想实现类似bloom的效果,卡在这一步了

多个pass用到还是同一套纹理数据。这样是无法做到后一个使用前一个的结果的。你需要搞个rendertexture之类的将上一个结果存下来,经过多次渲染实现。

你可以参考下大佬的模糊效果写法https://forum.cocos.org/t/topic/151605

谢谢大佬回复,我研究研究

解决了吗?如何让后面的pass使用前面的结果texture呀?

可以参考3.8.5添加的基于BuiltinPipelinePass的DepthOfField例子。
多pass的bloom,也可以参考3.8.6分支的bloom的实现,同样基于BuiltinPipelinePass。
也可以参考3.8.4的bloom,算法差不多,代码组织上有点区别。

那么材质 的shader 上支持多pass吗? 还是只能用在渲染管线之中?

多pass的触发,需要通过管线完成。
比如多pass bloom这样的,其中需要多次设置RenderPass,绑定贴图资源。
流程比较复杂,单靠effect的多pass难以描述。
effect中的pass,更多是记录了有哪些pass可以被调用。
具体调用哪个,需要在管线控制。

懂了,感谢解答:+1:

再问一下,因为我们的场景会分不同的层,3.8.4在使用新管线的时候 的灯光只对default层的物体起作用,其他层的模型只能被环境光照亮。因为这个问题我们一直在使用旧版的渲染管线。目前这个问题得到解决了吗?

管线调用pass引擎的哪几个文件可以参考

目前没解决,需要些时间。

3.8.6的builtin-bloom-pass.ts或者3.8.4~3.8.6的builtin-pipeline.ts。
红框的内容选择了effect中的pass,这里选了pass1

1赞

好的我去看看