Редактирование текстур цветов - WebGL - PullRequest
0 голосов
/ 29 мая 2018

Я применил текстуру к простому кубу, используя WebGL.Текстура представляет собой чекборд с 2 цветами;это результат:

Example

Я хотел бы знать, как редактировать цвет текстуры только для некоторых пикселей, чтобы получить что-то вроде глаз или рта на этом кубе,используя разные цвета.

Это код, который я использовал для создания доски объявлений:

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);
}

1 Ответ

0 голосов
/ 29 мая 2018

Этот вопрос имеет несколько решений.

  1. (лучший вариант) Используйте шейдер для наложения изображения лица, которое вы загружаете, поверх шахматной доски.Это даже позволяет вам избежать использования текстуры для шахматной доски полностью, если вы хотите.Это лучший вариант, потому что изучение шейдеров необходимо для любой графической ситуации.

  2. Загрузите изображение лица и смешайте его в текстуру.

  3. (Плохой вариант, но работает). Используйте некоторую причудливую математику, чтобы нарисовать лицо на текстуре.

Каждый из них требует определенных знаний для выполнения:

  1. Шейдеры

  2. Загрузка текстур из файла

Третий метод самый хитрый, но самый простой в реализации без особых знаний.Я не знаю, насколько сложным вы хотите, чтобы лицо, что-либо более сложное, чем карикатурные глаза и рот, выходит за рамки возможного.

Общая идея - написать функцию, которая делает кривую (например, в Desmos ) через 2 балла.Вот мое уравнение: х (х-30) * 0,03.Внутри JS просто создайте цикл for от 0 до 30, затем оцените эту функцию, и это будет высота нижней части глаза (относительно начальной точки).Вы также можете отменить эту функцию, чтобы получить верхнюю часть глаза.Затем вы можете нарисовать круг для ученика.Затем повторите для другого глаза.Это мое мнение, вам действительно нужно поиграть с ним и проявить творческий подход.

Удачи!

...