Sprite设置自定义材质,浏览器运行不显示

在编辑器内是 Sprite 可以正常显示的,对应的材质效果也有,但在浏览器中节点存在, Sprite 组件也存在,但图片看不见。

查了不少文章,已经把 spriteFrame 的 Packable 去掉了勾选,项目设置宏勾选了CLEANUP_IMAGE_CACHE ,同时在脚本中的最外层写了 macro.CLEANUP_IMAGE_CACHE = true; DynamicAtlasManager.instance.enabled = false;。而且试了3.8.5、3.8.4、3.4.1,都不行。

CCEffect %{
  techniques:
  - name: opaque
    passes:
    - vert: legacy/main-functions/general-vs:vert # builtin header
      frag: hole-fs:frag
      properties: &props
        holeCenter: { value: [0.5, 0.5] }  # 挖孔的中心位置
        holeSize: { value: [0.4, 0.4] }    # 挖孔的宽度和高度
        holeBlurRadius: { value: 0.05 }     # 虚化半径
  - name: transparent
    passes:
    - vert: general-vs:vert # builtin header
      frag: hole-fs:frag
      blendState:
        targets:
        - blend: true
          blendSrc: src_alpha
          blendDst: one_minus_src_alpha
          blendSrcAlpha: src_alpha
          blendDstAlpha: one_minus_src_alpha
      properties: *props
}%

CCProgram hole-fs %{
  precision highp float;
  #include <legacy/output>
  #include <sprite-texture>

  uniform Constant {
    vec2 holeCenter;  // 挖孔的中心
    vec2 holeSize;    // 挖孔的宽度和高度
    float holeBlurRadius;  // 虚化半径
  };

  in vec2 v_uv; // 纹理坐标

  vec4 frag () {
    // 计算矩形的四条边距离
    float distX = max(abs(v_uv.x - holeCenter.x) - holeSize.x * 0.5, 0.0);
    float distY = max(abs(v_uv.y - holeCenter.y) - holeSize.y * 0.5, 0.0);
    
    // 计算离矩形边缘的总距离
    float dist = length(vec2(distX, distY));

    // 应用虚化效果:在边缘处应用逐渐减小的透明度
    float fade = smoothstep(0.0, holeBlurRadius, dist);

    // 如果当前像素在孔内或已经超出虚化边缘,则丢弃该像素
    if (fade < 0.1) {
        discard;
    }

    // 否则显示纹理,乘上透明度(虚化效果)
    vec4 col = texture(cc_spriteTexture, v_uv);
    col.a *= fade;  // 根据虚化程度调整透明度

    return col;
  }
}%

1赞

抱歉,你试图上传的文件太大了(最大限制为4096%KB)。

:joy:上传不了项目压缩包,可我就是个新建2D空项目,一个.effect、一个材质、一个场景和一个脚本而已呀

import { _decorator, Component, DynamicAtlasManager, macro, Node } from 'cc';
const { ccclass, property } = _decorator;

macro.CLEANUP_IMAGE_CACHE = true;
DynamicAtlasManager.instance.enabled = false;

@ccclass('main')
export class main extends Component {
    start() {

    }

    update(deltaTime: number) {
        
    }
}

今天遇到了,可以检查下摄像机z和far的大小,可能是一个问题。

相机的Visibility属性和节点的layer属性检查了吗?

试着改了,都没效果。但只要去掉这个材质,就可以正常显示,无论是编辑器内的摄像机画面,还是在浏览器中预览。

检查了,相机的Visibility属性包含UI_2D,节点的Layer设置为UI_2D。

最后解决了吗???

最近都没继续研究。

刚才试了下,运行后会报出“[.WebGL-0x77b4033ea900] GL_INVALID_OPERATION: glDrawElements: It is undefined behaviour to have a used but unbound uniform buffer.”警告,应该就是之前没写对吧,虽然记得当前运行好像没有警告。

把官方内置 sprite 的 effect 和我之前写的交给 chatgpt,让它帮我融合下,给出的 effect 勾选 USE_TEXTURE 确实可以正常运行,但多了很多不明白的代码 :joy:

有空再学习吧,把 chatgpt 的代码贴一下,但不确定有没有多余的代码。

CCEffect %{
  techniques:
  - passes:
    - vert: sprite-vs:vert
      frag: sprite-fs:frag
      depthStencilState:
        depthTest: false
        depthWrite: false
      blendState:
        targets:
        - blend: true
          blendSrc: src_alpha
          blendDst: one_minus_src_alpha
          blendDstAlpha: one_minus_src_alpha
      rasterizerState:
        cullMode: none
      properties:
        alphaThreshold: { value: 0.5 }
        holeCenter: { value: [0.5, 0.5] }
        holeSize: { value: [0.4, 0.4] }
        holeBlurRadius: { value: 0.05 }
}%

CCProgram sprite-vs %{
  precision highp float;
  #include <builtin/uniforms/cc-global>
  #if USE_LOCAL
    #include <builtin/uniforms/cc-local>
  #endif
  #if SAMPLE_FROM_RT
    #include <common/common-define>
  #endif
  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);

    #if USE_LOCAL
      pos = cc_matWorld * pos;
    #endif

    #if USE_PIXEL_ALIGNMENT
      pos = cc_matView * pos;
      pos.xyz = floor(pos.xyz);
      pos = cc_matProj * pos;
    #else
      pos = cc_matViewProj * pos;
    #endif

    uv0 = a_texCoord;
    #if SAMPLE_FROM_RT
      CC_HANDLE_RT_SAMPLE_FLIP(uv0);
    #endif
    color = a_color;

    return pos;
  }
}%

CCProgram sprite-fs %{
  precision highp float;
  #include <builtin/internal/embedded-alpha>
  #include <builtin/internal/alpha-test>

  in vec4 color;

  #if USE_TEXTURE
    in vec2 uv0;
    #pragma builtin(local)
    layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture;
  #endif

  layout(set = 1, binding = 0) uniform HoleUniforms {
    vec2 holeCenter;
    vec2 holeSize;
    float holeBlurRadius;
  };

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

    #if USE_TEXTURE
      o *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0);
      #if IS_GRAY
        float gray  = 0.2126 * o.r + 0.7152 * o.g + 0.0722 * o.b;
        o.r = o.g = o.b = gray;
      #endif
    #endif

    float distX = max(abs(uv0.x - holeCenter.x) - holeSize.x * 0.5, 0.0);
    float distY = max(abs(uv0.y - holeCenter.y) - holeSize.y * 0.5, 0.0);
    float dist = length(vec2(distX, distY));
    float fade = smoothstep(0.0, holeBlurRadius, dist);

    if (fade < 0.1) {
      discard;
    }

    o.a *= fade;

    o *= color;
    ALPHA_TEST(o);
    return o;
  }
}%