当前位置: 首页 > news >正文

Cocos Creator 3.8 修改纹理像素值

修改的代码:

import { _decorator, Component, RenderTexture, Sprite, Texture2D, ImageAsset, SpriteFrame, Vec2, gfx, director, log, math, v2 } from 'cc';const { ccclass, property } = _decorator;@ccclass('GradientTransparency')
export class GradientTransparency extends Component {public readPixels (texture:Texture2D, x = 0, y = 0, width?: number, height?: number) : Uint8Array | null {log('width:', width, ' height:', height);width = width || texture.width;height = width || texture.height;log('texture:', texture);const gfxTexture = texture.getGFXTexture();if (!gfxTexture) {return null;}const bufferViews: ArrayBufferView[] = [];const regions: gfx.BufferTextureCopy[] = [];const region0 = new gfx.BufferTextureCopy();region0.texOffset.x = x;region0.texOffset.y = y;region0.texExtent.width = width;region0.texExtent.height = height;regions.push(region0);const buffer = new Uint8Array(width * height * 4);bufferViews.push(buffer);director.root?.device.copyTextureToBuffers(gfxTexture, bufferViews, regions)return buffer;}public smoothstep(edge0: number, edge1: number, x: number): number {// 将 x 限制在 [edge0, edge1] 范围内//const t = Math.max(0, Math.min(1, (x - edge0) / (edge1 - edge0)));const t = Math.min(Math.max((x - edge0) / (edge1 - edge0), 0.0), 1.0);// 使用三次 Hermite 插值return t * t * (3 - 2 * t);}/*** 修改 Sprite 的透明度* @param sprite 目标 Sprite* @param points 给定的圆心点(UV 坐标,范围 [0, 1])* @param radius1 第一个透明度分界点的半径(完全透明半径)* @param radius2 第二个透明度分界点的半径(渐变透明半径)*/modifySpriteAlpha(sprite: Sprite, points: Vec2[], radius1: number, radius2: number) {const spriteFrame = sprite.spriteFrame;if (!spriteFrame) {console.error("SpriteFrame 不存在!");return;}const texture = spriteFrame.texture;if (!texture) {console.error("Texture 不存在!");return;}// 创建 RenderTextureconst renderTexture = new RenderTexture();renderTexture.reset({width: spriteFrame.width,height: spriteFrame.height,});// 获取像素数据log('spriteFrame:', spriteFrame);const pixels = this.readPixels(spriteFrame.texture as Texture2D, 0, 0, spriteFrame.width, spriteFrame.height);log('pixels:', pixels);const width = spriteFrame.width;const height = spriteFrame.height;// 最大不透明度const maxAlpha = 200;// 遍历每个像素for (let y = 0; y < height; y++) {for (let x = 0; x < width; x++) {const index = (y * width + x) * 4; // 每个像素的起始索引let alpha = pixels[index + 3]; // 当前像素的 alpha 通道// 将像素点转换为 UV 坐标const uv = new Vec2(x / width, y / height);// 计算与每个点的距离并修改透明度points.forEach(point => {const distance = uv.clone().subtract(point).multiply(v2(width, height)).length(); // 距离(按像素计算)//let realPoint = v2(point.x * width, point.y * height);//const distance = Vec2.distance(realPoint, v2(x, y));if (distance < radius1) {alpha = 0; // 完全透明} else if (distance >= radius1 && distance < radius2) {//alpha = alpha = this.smoothstep(radius1, radius2, distance) * maxAlpha;/*const t = (distance - radius1) / (radius2 - radius1); // 计算线性插值const calculatedAlpha = (1 - t) * maxAlpha; // 渐变透明alpha = Math.min(alpha, calculatedAlpha); // 重叠透明度处理,叠加上限为 128*/} else {alpha = Math.min(alpha, maxAlpha); // 超出范围,保持不透明度为 128}});pixels[index + 3] = 255 - alpha; // 更新 alpha 通道}}// 创建新的 ImageAssetconst newImageAsset = new ImageAsset();newImageAsset.reset({_data: pixels,_compressed: false,width: width,height: height,format: Texture2D.PixelFormat.RGBA8888,});// 创建新的 Texture2Dconst newTexture = new Texture2D();newTexture.image = newImageAsset;// 创建新的 SpriteFrameconst newSpriteFrame = new SpriteFrame();newSpriteFrame.texture = newTexture;// 应用新的 SpriteFramesprite.spriteFrame = newSpriteFrame;}
}

调用的代码:

import { _decorator, Component, Sprite, Vec2 } from "cc";
import { GradientTransparency } from "./fogImplement";const { ccclass, property } = _decorator;@ccclass('MainController')
export class MainController extends Component {@property(Sprite)targetSprite: Sprite = null; // 拖入目标 SpriteonLoad() {}onClick(){const gradientTransparency = this.getComponent(GradientTransparency);if (gradientTransparency && this.targetSprite) {// 设置两个 UV 坐标点const points = [new Vec2(0.5, 0.5)];  //, new Vec2(0.7, 0.7)const radius1 = 100; // 第一个分界点(完全透明)const radius2 = 200; // 第二个分界点(渐变透明)gradientTransparency.modifySpriteAlpha(this.targetSprite, points, radius1, radius2);}}
}

http://www.lryc.cn/news/518576.html

相关文章:

  • 如何评价deepseek-V3 VS OpenAI o1 自然语言处理成Sql的能力
  • SQL左连接的两种不同情况示例和外连接示例
  • 【渗透测试术语总结】
  • Unity2D初级背包设计后篇 拓展举例与不足分析
  • Kafka优势剖析-幂等性和事务
  • MyBatis深入了解
  • 语音技术与人工智能:智能语音交互的多场景应用探索
  • Openwrt @ rk3568平台 固件编译实践(二)- ledeWRT版本
  • Windows下调试Dify相关组件(1)--前端Web
  • 对话|企业如何构建更完善的容器供应链安全防护体系
  • HTML5 缩放动画(Zoom In/Out)详解
  • C语言——文件IO 【文件IO和标准IO区别,操作文件IO】open,write,read,dup2,access,stat
  • 【C++习题】22.随机链表的复制
  • 备考蓝桥杯:数据结构概念浅谈
  • 【TI毫米波雷达】DCA1000不使用mmWave Studio的数据采集方法,以及自动化实时数据采集
  • 创建型模式3.建造者模式
  • 【集成学习】Boosting算法详解
  • 【Orca】Orca - Graphlet 和 Orbit 计数算法
  • 58. Three.js案例-创建一个带有红蓝配置的半球光源的场景
  • 【Git原理和使用】Git 分支管理(创建、切换、合并、删除、bug分支)
  • 义乌购的反爬虫机制怎么应对?
  • 消息中间件面试
  • 基于CLIP和DINOv2实现图像相似性方面的比较
  • 利用Python爬虫获取API接口:探索数据的力量
  • 【LeetCode】力扣刷题热题100道(1-5题)附源码 链表 子串 中位数 回文子串(C++)
  • Docker启动失败 - 解决方案
  • 【Duilib】 List控件支持多选和获取选择的多条数据
  • android系统的一键编译与非一键编译 拆包 刷机方法
  • SQL语言的函数实现
  • OSPF - 2、3类LSA(Network-LSA、NetWork-Sunmmary-LSA)