Я работал над учебными пособиями по WebGL, такими как webglfundamentals , и столкнулся с камнем преткновения - я считаю, что мне нужно будет использовать созданную мной текстуру для передачи информации непосредственно в фрагментный шейдер, но я не могу индексировать текстуру должным образом.
Цель - передать информацию об источниках света (местоположение и цвет), которые будут учтены в цвете фрагмента. В идеале эта информация является динамической c как по значению, так и по длине.
Воспроизведение
Я создал упрощенную версию проблемы в этой скрипке: WebGL - Тестирование текстуры данных
Вот часть кода.
В одноразовой установке мы создаем текстуру, заполняем ее данными и применяем то, что кажется наиболее надежные настройки для этой текстуры (без мипса, без проблем с упаковкой байтов [?])
// lookup uniforms
var textureLocation = gl.getUniformLocation(program, "u_texture");
// Create a texture.
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// fill texture with 1x3 pixels
const level = 0;
const internalFormat = gl.RGBA; // I've also tried to work with gl.LUMINANCE
// but it feels harder to debug
const width = 1;
const height = 3;
const border = 0;
const type = gl.UNSIGNED_BYTE;
const data = new Uint8Array([
// R, G, B, A (unused) // : 'texel' index (?)
64, 0, 0, 0, // : 0
0, 128, 0, 0, // : 1
0, 0, 255, 0, // : 2
]);
const alignment = 1; // should be uneccessary for this texture, but
gl.pixelStorei(gl.UNPACK_ALIGNMENT, alignment); // I don't think this is hurting
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, width, height, border,
internalFormat, type, data);
// set the filtering so we don't need mips and it's not filtered
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
В последовательности draw (которая может случиться только один раз, но, возможно, может повториться), мы усиливаем что программа должна использовать нашу текстуру
// Tell the shader to use texture unit 0 for u_texture
gl.activeTexture(gl.TEXTURE0); // added this and following line to be extra sure which texture is being used...
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.uniform1i(textureLocation, 0);
Наконец, в фрагментном шейдере мы пытаемся просто надежно использовать один «тексель» в качестве средства передачи информации. Я не могу понять, как получить значения, которые я надежно сохранил в текстуре.
precision mediump float;
// The texture.
uniform sampler2D u_texture;
void main() {
vec4 sample_00 = texture2D(u_texture, vec2(0, 0));
// This sample generally appears to be correct.
// Changing the provided data for the B channel of texel
// index 0 seems to add blue as expected
vec4 sample_01 = texture2D(u_texture, vec2(0, 1));
vec4 sample_02 = texture2D(u_texture, vec2(0, 2));
// These samples are how I expected this to work since
// the width of the texture is set to 1
// For some reason 01 and 02 both show the same color
vec4 sample_10 = texture2D(u_texture, vec2(1, 0));
vec4 sample_20 = texture2D(u_texture, vec2(2, 0));
// These samples are just there for testing - I don't think
// that they should work
// choose which sample to display
vec4 sample = sample_00;
gl_FragColor = vec4(sample.x, sample.y, sample.z, 1);
}
Вопрос (ы)
Является ли использование текстуры лучшим способом сделать это? Я также слышал о способности передавать массивы векторов, но текстуры кажутся более распространенными.
Как вы должны создать текстуру? (особенно когда я указываю 'width' и 'height', я должен ссылаться на итоговые размеры texel или количество элементов gl.UNSIGNED_BYTE, которые я буду использовать для создания текстуры ?? документация texImage2D )
Как вы должны индексировать текстуру в фрагментном шейдере, если не используете «различные» типы? (т.е. я просто хочу значение одного или нескольких конкретных текселей - без интерполяции [не имеет ничего общего с вершинами])
Другие ресурсы
Я прочитал столько, сколько смог об этом пока. Вот неполный список:
Редактировать Вот еще один ресурс, который я только что нашел: Затруднения с доступом к массиву в WebGL и парой обходных путей . Вселяет надежду.
это действительно беспокоит меня.
заранее спасибо!