如何将Texture2D中点击像素的同色全部替换为绿色?
如何批量修改Texture2D中同颜色的所有像素?
我是纹理操作的新手,若有表述不当之处请见谅。我希望实现:当玩家点击某个像素时,将纹理中所有与该点击像素颜色相同的像素都改为绿色。我尝试使用Texture2D.GetPixel和Texture2D.SetPixel方法,但仅能修改一个特定位置的单个像素,代码如下:
if (Input.GetMouseButtonDown(0)) { mColor = mTexture.GetPixel(0,0); mTexture.SetPixel(0, 0, Color.green); mTexture.Apply(); }请问是否有办法实现将所有同色像素改为绿色的需求?
当然可以实现,核心思路是遍历纹理的所有像素,把和点击目标颜色一致的像素替换成绿色。这里给你梳理关键步骤和完整实现:
关键注意点
- 首先要把鼠标点击的屏幕坐标转换为纹理上的实际像素坐标,你之前的代码固定取(0,0)并不是点击位置
- 用
GetPixels()一次性获取所有像素数组,比逐个调用GetPixel()效率高很多,尤其适合大纹理 - 必须开启纹理的Read/Write Enabled选项(在Inspector面板的纹理设置里),否则无法读写像素
完整代码示例
public Texture2D mTexture; private Camera mMainCamera; void Start() { mMainCamera = Camera.main; // 检查纹理是否可读写 if (!mTexture.isReadable) { Debug.LogError("请在纹理的Inspector设置中开启Read/Write Enabled!"); } } void Update() { if (Input.GetMouseButtonDown(0)) { // 射线检测获取点击的3D物体纹理坐标 Ray ray = mMainCamera.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out RaycastHit hit)) { // 将UV坐标转换为纹理像素坐标 int texX = Mathf.FloorToInt(hit.textureCoord.x * mTexture.width); int texY = Mathf.FloorToInt(hit.textureCoord.y * mTexture.height); // 获取点击位置的目标颜色 Color targetColor = mTexture.GetPixel(texX, texY); // 一次性获取所有像素数组 Color[] allPixels = mTexture.GetPixels(); // 遍历替换同色像素 for (int i = 0; i < allPixels.Length; i++) { // 颜色比较考虑浮点精度,直接用Color.Equals即可 if (allPixels[i].Equals(targetColor)) { allPixels[i] = Color.green; } } // 将修改后的像素数组赋值回纹理 mTexture.SetPixels(allPixels); // 应用修改到GPU mTexture.Apply(); } } }
额外提示
- 如果是修改UI上的纹理,不需要射线检测,可通过
RectTransformUtility.ScreenPointToLocalPointInRectangle转换坐标后计算像素位置 - 超大纹理遍历可能卡顿,可放到协程中分帧处理,或者用GPU Shader实现(效率更高)
内容的提问来源于stack exchange,提问作者DC37
相关产品推荐
相关产品推荐

