I applied a texture on a simple cube using WebGL. The texture is a check board with 2 colors ; this is the result :
I would like to know how to edit the color of the texture only for some pixels in order to obtain something like eyes or mouth on this cube , using different colors.
This is the code I used to build the check board :
var colorsArray = [];
var vertexColors = [
vec4( 1.0, 0.0, 1.0, 1.0 ), //
vec4( 1.0, 1.0, 1.0, 1.0 ), //
vec4( 1.0, 0.0, 1.0, 1.0 ), //
vec4( 1.0, 1.0, 1.0, 1.0 ), //
vec4( 1.0, 0.0, 1.0, 1.0 ), //
vec4( 1.0, 1.0, 1.0, 1.0 ), //
vec4( 1.0, 1.0, 1.0, 1.0 ), //
vec4( 1.0, 1.0, 1.0, 1.0 ) //
];
var move_forward = false;
// TEXTURE
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;
//c = 255*(((i & 0x8) == 0) ^ ((j & 0x8) == 0))
image1[4*i*texSize+4*j] = c;
image1[4*i*texSize+4*j+1] = c;
image1[4*i*texSize+4*j+2] = c;
image1[4*i*texSize+4*j+3] = 255;
}
}
var image2 = new Uint8Array(4*texSize*texSize);
// Create a checkerboard pattern
for ( var i = 0; i < texSize; i++ ) {
for ( var j = 0; j <texSize; j++ ) {
image2[4*i*texSize+4*j] = 127+127*Math.sin(0.1*i*j);
image2[4*i*texSize+4*j+1] = 127+127*Math.sin(0.1*i*j);
image2[4*i*texSize+4*j+2] = 127+127*Math.sin(0.1*i*j);
image2[4*i*texSize+4*j+3] = 255;
}
}
var texture1, texture2;
var t1, t2;
var texCoordsArray = [];
var texCoord = [
vec2(0, 0),
vec2(0, 1),
vec2(1, 1),
vec2(1, 0)
];
function configureTexture() {
texture1 = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture1 );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, image1);
gl.generateMipmap( gl.TEXTURE_2D );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST_MIPMAP_LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
texture2 = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture2 );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, image2);
gl.generateMipmap( gl.TEXTURE_2D );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST_MIPMAP_LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
}
This question has multiple solutions.
(Best option) Use a shader to layer an image of the face, which you load in, on top of the checkerboard. This even allows you to avoid using a texture for the checkerboard entirely if you desire. This is the best option because learning shaders is a must for any graphics situation.
Load in the image of the face and blend it together into the texture.
(Bad option, but works) Use some fancy math to draw a face onto the texture.
Each of these requires some knowledge to accomplish:
The third method is the trickiest, but the easiest to implement without much extra knowledge. I don't know how complex you want the face, anything more complex than cartoon eyes and mouth is out of the realm of possibility.
The general idea is to write a function that makes a curve (for example in Desmos) across 2 points. Here's my equation: x(x-30)*0.03. Inside JS, just make a for loop for 0 to 30, then evaluate that function, and that'll be the height of the bottom of the eye (relative to the starting point). You can also negate that function to get the top of the eye. Then you can draw a circle for the pupil. Then repeat for the other eye. That's just my take on it, you really do need to play with it and get creative.
Good luck!