You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebGL纹理颜色编辑:如何修改立方体纹理指定像素

嘿,这个需求超有意思!要在你现有的双色棋盘格纹理上叠加眼睛、嘴巴这类彩色图案,核心思路其实很简单——在生成纹理像素的循环里,给特定区域的像素单独设置彩色值就行。我结合你提供的代码,给你拆解具体的实现步骤:

具体实现步骤

1. 先确定图案的位置与颜色

你的纹理尺寸是256x256,所以像素坐标范围是0~255(x和y方向)。先想好你要画的图案位置:比如把眼睛放在纹理上半部分,嘴巴放在中间偏下的位置,再给它们指定鲜艳的颜色(比如眼睛用深蓝色,嘴巴用红色)。

2. 修改纹理生成代码,加入图案逻辑

你现在生成棋盘格纹理的image1循环里,已经有了给每个像素设置灰度值的逻辑。我们只需要在这个基础上,增加区域判断:如果当前像素落在眼睛/嘴巴的区域内,就覆盖成对应的彩色值。

修改后的image1生成代码如下:

var texSize = 256;
var numChecks = 8;
var c;
var image1 = new Uint8Array(4*texSize*texSize);

for ( var i = 0; i < texSize; i++ ) {
  for ( var j = 0; j < texSize; j++ ) {
    // 先保留原来的棋盘格逻辑
    var patchx = Math.floor(i/(texSize/numChecks));
    var patchy = Math.floor(j/(texSize/numChecks));
    if(patchx%2 ^ patchy%2) c = 255;
    else c = 0;

    // -------------- 新增图案判断逻辑 --------------
    // 左眼:x在80-100,y在100-120,蓝色(0,0,255)
    if (i >= 80 && i <= 100 && j >= 100 && j <= 120) {
      image1[4*i*texSize+4*j] = 0;       // R通道
      image1[4*i*texSize+4*j+1] = 0;     // G通道
      image1[4*i*texSize+4*j+2] = 255;   // B通道
    } 
    // 右眼:x在156-176,y在100-120,蓝色
    else if (i >= 156 && i <= 176 && j >= 100 && j <= 120) {
      image1[4*i*texSize+4*j] = 0;
      image1[4*i*texSize+4*j+1] = 0;
      image1[4*i*texSize+4*j+2] = 255;
    }
    // 嘴巴:x在100-156,y在160-170,红色(255,0,0)
    else if (i >= 100 && i <= 156 && j >= 160 && j <= 170) {
      image1[4*i*texSize+4*j] = 255;
      image1[4*i*texSize+4*j+1] = 0;
      image1[4*i*texSize+4*j+2] = 0;
    }
    // 非图案区域,沿用棋盘格灰度值
    else {
      image1[4*i*texSize+4*j] = c;
      image1[4*i*texSize+4*j+1] = c;
      image1[4*i*texSize+4*j+2] = c;
    }
    // Alpha通道保持不透明
    image1[4*i*texSize+4*j+3] = 255;
  }
}

小提示:画更复杂的形状

如果想要圆形眼睛这类不是矩形的图案,可以用距离公式判断:比如判断当前像素到圆心的距离是否小于半径,示例代码如下:

// 圆形左眼:圆心(90,110),半径10
const centerX = 90, centerY = 110, radius = 10;
const distance = Math.sqrt(Math.pow(i - centerX, 2) + Math.pow(j - centerY, 2));
if (distance <= radius) {
  // 设置蓝色
  image1[4*i*texSize+4*j] = 0;
  image1[4*i*texSize+4*j+1] = 0;
  image1[4*i*texSize+4*j+2] = 255;
}

3. 可选:动态修改纹理(实时更新图案)

如果之后想要动态调整图案(比如让眼睛变色、嘴巴动起来),不用每次重新生成整个纹理,直接修改image1中对应像素的值,再用gl.texSubImage2D更新纹理的局部区域即可,性能会更好:

function updateLeftEyeColor(newR, newG, newB) {
  // 遍历左眼区域的像素,修改颜色
  for (let i = 80; i <= 100; i++) {
    for (let j = 100; j <= 120; j++) {
      const index = 4*i*texSize + 4*j;
      image1[index] = newR;
      image1[index+1] = newG;
      image1[index+2] = newB;
    }
  }
  // 绑定纹理,更新局部区域
  gl.bindTexture(gl.TEXTURE_2D, texture1);
  // 参数说明:纹理类型、层级、起始x、起始y、宽度、高度、格式、数据类型、像素数据
  gl.texSubImage2D(gl.TEXTURE_2D, 0, 80, 100, 21, 21, gl.RGBA, gl.UNSIGNED_BYTE, 
    image1.subarray(4*80*texSize + 4*100, 4*(80+21)*texSize + 4*(100+21)));
  // 如果开启了mipmap,需要重新生成
  gl.generateMipmap(gl.TEXTURE_2D);
}

// 调用示例:把左眼改成绿色
updateLeftEyeColor(0, 255, 0);

这样修改后,你的立方体纹理上就会出现你想要的彩色图案啦,你可以根据自己的喜好调整区域坐标和颜色~

内容的提问来源于stack exchange,提问作者KiririIG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:06:28