噪声图图片降解方案求助

动画

这是我做的噪声图降解。但是可能比较费资源。
大家看看能不能优化一下。
efferct 代码如下

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 }

      dissolve: { value: white, editor: { tooltip: ‘dissolve map’ } }

      dissolveThreshold: { value: 0, editor: { range: [0, 1, 0.01], slide: true } }

}%

CCProgram sprite-vs %{

precision highp float;

#include

#if USE_LOCAL

#include <cc-local>

#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

pos = cc_matViewProj * pos;

uv0 = a_texCoord;

color = a_color;

return pos;

}

}%

CCProgram sprite-fs %{

precision highp float;

#include

in vec4 color;

#if USE_TEXTURE

in vec2 uv0;

#pragma builtin(local)

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

uniform sampler2D dissolve;

#endif

uniform Dissolve {

 float dissolveThreshold;

};

vec4 frag () {

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

float value = 1.0;

#if USE_TEXTURE

  vec4 dissolveMap = texture(dissolve, uv0);

  value *= dissolveMap.r;

#endif

if(value < dissolveThreshold){

  discard;

}

#if USE_TEXTURE

  o *= texture(cc_spriteTexture, uv0);

#endif

o *= color;

ALPHA_TEST(o);

if(value < dissolveThreshold + 0.05){

  o = vec4(0.9, 0.6, 0.3, o.a);

}

return o;

}

}%

然后是ts代码

import { _decorator, Component, Node, Material, Sprite, Label, tween, Tween } from ‘cc’;

const { ccclass, property } = _decorator;

@ccclass(‘RenderToTexture’)

export class RenderToTexture extends Component {

@property(Material)

dissolveMaterial: Material = null;

private originalMaterials: Map<Node, Material> = new Map();

private dissolveMaterials: Map<Node, Material> = new Map();

private _dissolveThreshold: number = 0;

get dissolveThreshold() {

    return this._dissolveThreshold;

}

set dissolveThreshold(value: number) {

    this._dissolveThreshold = value;

    this.updateDissolveThreshold(value);

}

onLoad() {

    // 初始加载时应用材质

    this.applyDissolveMaterialToAllChildren(this.node);

}

start() {

    this.applyDissolveMaterialToAllChildren(this.node);

}

applyDissolveMaterialToAllChildren(parent: Node) {

    parent.children.forEach(child => {

        const sprite = child.getComponent(Sprite);

        if (sprite) {

            this.originalMaterials.set(child, sprite.customMaterial);

            const mat = new Material();

            mat.copy(this.dissolveMaterial);

            this.dissolveMaterials.set(child, mat);

            sprite.customMaterial = mat;

        }

        const label = child.getComponent(Label);

        if (label) {

            this.originalMaterials.set(child, label.customMaterial);

            const mat = new Material();

            mat.copy(this.dissolveMaterial);

            this.dissolveMaterials.set(child, mat);

            label.customMaterial = mat;

        }

        // 递归调用以确保所有子孙节点都应用材质

        this.applyDissolveMaterialToAllChildren(child);

    });

}

updateDissolveThreshold(value: number) {

    this.dissolveMaterials.forEach((material, node) => {

        material.setProperty('dissolveThreshold', value);

    });

}

startDissolveEffect(duration: number) {

    tween(this)

        .to(duration, { dissolveThreshold: 1 })

        .start();

}

resetMaterials(parent: Node) {

    parent.children.forEach(child => {

        const sprite = child.getComponent(Sprite);

        if (sprite && this.originalMaterials.has(child)) {

            sprite.customMaterial = this.originalMaterials.get(child);

        }

        const label = child.getComponent(Label);

        if (label && this.originalMaterials.has(child)) {

            label.customMaterial = this.originalMaterials.get(child);

        }

        this.resetMaterials(child);

    });

}

}

我想说为什么可以优化。因为我的节点 是这样的image
父节点lane没有任何图像使用effect没有效果。需要用循环遍历他的子节点添加effect,然后每次都要去调每一个节点的值,这样很麻烦。有没有一劳永逸的办法。不能用canvas,不能使用不同图层,因为会有很多个不同的lane。

我想说用camera做单张降解。

但有可能你目前的方案性能更好点,

所以自己做做测试咯

暂时还没到手机端测试,一个两个应该没什么问题。先就这么整。如果遇到好的方法再说 Shader刚学。之前都不知道这个是做什么用的

我是菜鸡,但有个优化思路,仅供参考。
我看你代码是用tween的方式逐帧调整降解阈值,可能性能不太好,可以考虑在着色器里用游戏时间cc_time.x( Cocos Shader 内置全局 Uniform | Cocos Creator )作为参数计算出降解阈值,这样只用设置一次“开始降解的时间”,然后在着色器里用cc_time.x减去开始降解时间,将结果值在“降解的duration”内进行比较来确定降解阈值。注意:“开始降解的时间”的值应该用director.root.cumulativeTime来获取,因为着色器中cc_time.x使用的是渲染器的积累时间“cumulativeTime”。

谢谢提供思路,我刚学几天可能也听不大懂。我试试 性能怎么样