import { Color, Material, Node, UIRenderer, UITransform, Vec2 } from 'cc' import ShaderMaterialPrefab from '../../game/prefab/ShaderMaterialPrefab' export default class ShaderHelper { /** * 清除所有shader * @param showNode * @param material */ public static clearAllEffect( showNode: Node, material: Material = ShaderMaterialPrefab.instance.getComponent(ShaderMaterialPrefab).default, ) { showNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { renderComponent.setSharedMaterial(material, 0) }) showNode.children.forEach((childNode) => { childNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { renderComponent.setSharedMaterial(material, 0) }) }) } /** * 设置图片灰白程度 * @param showNode * @param grayLevel * @param material */ public static setGrayEffect( showNode: Node, grayLevel: number = 1, material: Material = ShaderMaterialPrefab.instance.getComponent(ShaderMaterialPrefab) .grayMaterial, ) { showNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { material.setProperty('grayLevel', grayLevel) renderComponent.setMaterial(material, 0) }) showNode.children.forEach((childNode) => { childNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { material.setProperty('grayLevel', grayLevel) renderComponent.setSharedMaterial(material, 0) }) }) } /** * 播放变灰过程动画 */ public static showGrayMv(showNode: Node) { let grayValue: number = 0.5 const intervalId = setInterval(() => { grayValue += 0.01 if (grayValue >= 1) { grayValue = 1 clearInterval(intervalId) } if (showNode) ShaderHelper.setGrayEffect(showNode, grayValue) }, 1) } /** * 设置图片老化 * @param showNode * @param grayLevel * @param material */ public static setOldPhotoEffect( showNode: Node, grayLevel: number = 1, material: Material = ShaderMaterialPrefab.instance.getComponent(ShaderMaterialPrefab).oldPhoto, ) { showNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { material.setProperty('oldLevel', grayLevel) renderComponent.setSharedMaterial(material, 0) }) showNode.children.forEach((childNode) => { childNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { material.setProperty('oldLevel', grayLevel) renderComponent.setSharedMaterial(material, 0) }) }) } /** * 播放变灰过程动画 */ public static showOldPhotoMv(showNode: Node) { let grayValue: number = 0 const intervalId = setInterval(() => { grayValue += 0.01 if (grayValue >= 1) { grayValue = 1 clearInterval(intervalId) } if (showNode) ShaderHelper.setOldPhotoEffect(showNode, grayValue) }, 1) } /** * 增加内发光特效 * showNode:要增加特效的节点或者他的子节点 * material:发光特效材质 * materialParam: {} * materialParam.glowColor:cc.v4(r,g,b,a) 颜色rbga值的结构体 * materialParam.glowColorSize:这里为约束一下值发光宽度值在 [0.0, 0.1] 因为 0.1+ 之后的效果可能不明显,也可以自己尝试修改,个人测试感觉0.01效果最佳 * materialParam.glowThreshold:这里为约束一下值发光阈值值在 [0.0, 0.5] 因为 0.5+ 之后的效果可能就是其他效果,个人感觉0.1效果最佳 */ public static setGlowInner( showNode: Node, materialParam: any, material: Material = ShaderMaterialPrefab.instance.getComponent(ShaderMaterialPrefab).glowInner, ) { showNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { material.setProperty('glowColor', materialParam.glowColor) material.setProperty('glowColorSize', materialParam.glowColorSize) material.setProperty('glowThreshold', materialParam.glowThreshold) renderComponent.setSharedMaterial(material, 0) }) showNode.children.forEach((childNode) => { childNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { material.setProperty('glowColor', materialParam.glowColor) material.setProperty('glowColorSize', materialParam.glowColorSize) material.setProperty('glowThreshold', materialParam.glowThreshold) renderComponent.setMaterial(material, 0) }) }) } /** * 设置不同颜色的发光 * @param showNode * @param color */ public static setCommonGlowInner(showNode: Node, color: Color = Color.WHITE) { this.setGlowInner(showNode, { glowColor: color, glowColorSize: 0.015, glowThreshold: 0.1, }) } /** * 播放被攻击闪烁过程动画 */ public static showFlash(showNode: Node, totalFlashTimes: number = 1) { let timeCount: number = 0 const color: Color = Color.WHITE let flashTimes: number = 0 const intervalId = setInterval(() => { timeCount += 1 if (timeCount % 50 === 0) { const tempCount: number = timeCount / 50 if (tempCount % 2 === 0) { color.a = 100 this.setGlowInner(showNode, { glowColor: color, glowColorSize: 0.1, glowThreshold: 0, }) } else { flashTimes++ this.setGlowInner(showNode, { glowColor: color, glowColorSize: 0, glowThreshold: 0, }) if (flashTimes > totalFlashTimes) clearInterval(intervalId) } } }, 1) } /** * 马赛克 * @param showNode * @param materialParam * @param material */ public static setMosaic( showNode: Node, materialParam: any, material: Material = ShaderMaterialPrefab.instance.getComponent(ShaderMaterialPrefab).mosaic, ) { showNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { material.setProperty('xBlockCount', materialParam.xBlockCount) material.setProperty('yBlockCount', materialParam.yBlockCount) renderComponent.setSharedMaterial(material, 0) }) showNode.children.forEach((childNode) => { childNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { material.setProperty('xBlockCount', materialParam.xBlockCount) material.setProperty('yBlockCount', materialParam.yBlockCount) renderComponent.setSharedMaterial(material, 0) }) }) } /** * 播放被攻击闪烁过程动画 */ public static showMosaicMv(showNode: Node, callback: Function = null) { let masaicTimes: number = 500 const intervalId = setInterval(() => { masaicTimes -= 2 this.setMosaic(showNode, { xBlockCount: masaicTimes, yBlockCount: masaicTimes, }) if (masaicTimes <= 30) { clearInterval(intervalId) if (callback) callback() } }, 1) } /** * 设置圆角剪切 * @param showNode * @param roundCornerRadius * @param material */ public static setRoundCornerCrop( showNode: Node, roundCornerRadius: number = 0.1, material: Material = ShaderMaterialPrefab.instance.getComponent(ShaderMaterialPrefab) .roundCornerCrop, ) { showNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { // material.setProperty("roundCornerRadius", roundCornerRadius); material.setProperty('xRadius', roundCornerRadius) material.setProperty('yRadius', roundCornerRadius) renderComponent.setSharedMaterial(material, 0) }) showNode.children.forEach((childNode) => { childNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { // material.setProperty("roundCornerRadius", roundCornerRadius); material.setProperty('xRadius', roundCornerRadius) material.setProperty('yRadius', roundCornerRadius) renderComponent.setSharedMaterial(material, 0) }) }) } /** * 设置闪光 * @param showNode * @param lightColor 光颜色 * @param lightWidth 光的宽度 * @param lightAngle 光的角度 * @param enableGradient * @param cropAlpha * @param enableFog * @param material */ public static setFlashLight( showNode: Node, lightColor: Color, lightWidth: number, lightAngle: number = 0, enableGradient: boolean = true, cropAlpha: boolean = true, enableFog: boolean = false, material: Material = ShaderMaterialPrefab.instance.getComponent(ShaderMaterialPrefab) .flashLight, ) { // showNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { // material.setProperty('lightColor', lightColor) // material.setProperty('lightWidth', lightWidth) // material.setProperty('lightAngle', lightAngle) // material.setProperty('enableGradient', enableGradient ? 1 : 0) // material.setProperty('cropAlpha', cropAlpha ? 1 : 0) // material.setProperty('enableFog', enableFog ? 1 : 0) // renderComponent.setSharedMaterial(material, 0) // }) // showNode.children.forEach((childNode) => { // childNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { // material.setProperty('lightColor', lightColor) // material.setProperty('lightWidth', lightWidth) // material.setProperty('lightAngle', lightAngle) // material.setProperty('enableGradient', enableGradient ? 1 : 0) // material.setProperty('cropAlpha', cropAlpha ? 1 : 0) // material.setProperty('enableFog', enableFog ? 1 : 0) // renderComponent.setSharedMaterial(material, 0) // }) // }) const setMaterialProperties = (renderer: UIRenderer) => { try { material.setProperty('lightColor', lightColor) material.setProperty('lightWidth', lightWidth) material.setProperty('lightAngle', lightAngle) material.setProperty('enableGradient', enableGradient ? 1 : 0) material.setProperty('cropAlpha', cropAlpha ? 1 : 0) material.setProperty('enableFog', enableFog ? 1 : 0) renderer.setSharedMaterial(material, 0) } catch (error) { console.error('Error setting material properties:', error) } } const renderComponents = [ ...showNode.getComponents(UIRenderer), ...showNode.children.flatMap(childNode => childNode.getComponents(UIRenderer)), ] renderComponents.forEach((renderComponent: UIRenderer) => { setMaterialProperties(renderComponent) }) } /** * 玩家升级shader动画 * @param showNode * @param callback */ public static showFlashLightMv(showNode: Node, callback: Function = null) { const nowClor: Color = new Color(0, 0, 0, 255) let colorIndex: number = 0 let lightAngle: number = 0 const intervalId = setInterval(() => { if (colorIndex === 0) { nowClor.r = nowClor.r + 2 if (nowClor.r >= 255) colorIndex += 1 } else if (colorIndex === 1) { nowClor.g = nowClor.g + 2 if (nowClor.g >= 255) colorIndex += 1 } else { nowClor.b = nowClor.b + 2 if (nowClor.b >= 255) { clearInterval(intervalId) ShaderHelper.clearAllEffect(showNode) if (callback) callback() return } } lightAngle += 1 this.setFlashLight(showNode, nowClor, 1, lightAngle) }, 1) } public static setFlag( showNode: Node, material: Material = ShaderMaterialPrefab.instance.getComponent(ShaderMaterialPrefab).flag, ) { showNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { renderComponent.setSharedMaterial(material, 0) }) showNode.children.forEach((childNode) => { childNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { renderComponent.setSharedMaterial(material, 0) }) }) } /** * 设置高斯模糊 * @param showNode * @param material */ public static setGaussian( showNode: Node, material: Material = ShaderMaterialPrefab.instance.getComponent(ShaderMaterialPrefab).gaussian, ) { showNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { const tran = renderComponent.node.getComponent(UITransform) material.setProperty('textureSize', new Vec2(tran.contentSize.width, tran.contentSize.height)) renderComponent.setSharedMaterial(material, 0) }) showNode.children.forEach((childNode) => { childNode.getComponents(UIRenderer).forEach((renderComponent: UIRenderer) => { const tran = renderComponent.node.getComponent(UITransform) material.setProperty( 'textureSize', new Vec2(tran.contentSize.width, tran.contentSize.height), ) // material.setProperty("textureSize", cc.v2(showNode.width, showNode.height)); renderComponent.setSharedMaterial(material, 0) }) }) } }