2022 11/20の時点でこのバグはまだ健在
https://discourse.processing.org/t/webgl-alpha-cant-be-used-as-a-texture/35981
の解決案のソースを参考にシェーダーの今回使わないライト設定を削り
createShader()したらバグが消えたようなので残しておく
シェーダーの必要な部分も消えてるかもしれないので挙動が怪しい場合は
上記記事から加工前のシェーダーを引っ張って来て使おう
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
<div id="p5canvas"></div>
<script>
//Reference site
//https://discourse.processing.org/t/webgl-alpha-cant-be-used-as-a-texture/35981
let img;
let buf;
let shdr;
let spritedata = '00101032323255bb30b27134f8300d0000400000014000000140000001500000105000005d55000115410000d51d4011415444055d5c5405455510011555400002800000028000000a8000002aa800';
let camerax = 0;
let cameray = 90;
let cameraz = -300;
let lookatx = 0;
let lookatz = 0;
let trees = [
[0, 0, 200],
[-200, 0, 200],
[200, 0, 20]
]
//makeimage from hex strings with magnifi (1,2,4,8,16)
function makeimage(hexstrings, magni) {
let ix = hexstrings;
//read header "transparent num","imagew","imageh" [0~6] (3byte)
let tpc = parseInt(ix.slice(0, 2), 16);
let imgw = parseInt(ix.slice(2, 4), 16);
let imgh = parseInt(ix.slice(4, 6), 16);
let imagemap = [];
//read color palet "palet rgb(3yite)"x3 [6~30] (24 = 12byte = 4x3)
let colorpalet = [];
for (let i = 0; i < 4; i++) {
let rgba = [];
for (let j = 0; j < 3; j++) {
rgba.push(parseInt(
//head + rgb(3byte)+r(1byte)+g(1byte)+b(1byte) (1byte=2char)
ix.slice(6 + i * 6 + j * 2, 8 + i * 6 + j * 2), 16));
}
if (tpc == i) {
rgba.push(0);
} else {
rgba.push(255);
}
colorpalet.push(rgba);
}
//read pixels color one pixel 4 bit [30~EOF] (4bit *2 =1byte=2pixels)
for (let i = 30; i < ix.length; i++) {
let onebyte = parseInt(ix[i], 16);
let upper = parseInt(onebyte / 4);
let lower = onebyte % 4;
imagemap.push(upper);
imagemap.push(lower);
}
let himg = createImage(imgw * magni, imgh * magni);
himg.loadPixels();
for (let y = 0; y < himg.height; y++) { ///magnifi; y++) {
for (let x = 0; x < himg.width; x++) { ///magnifi; x++) {
let index = (x + y * himg.width) * 4;
let cnum = imagemap[
parseInt(x / magni) +
parseInt(y / magni) * imgw];
himg.pixels[index] = colorpalet[cnum][0];
himg.pixels[index + 1] = colorpalet[cnum][1];
himg.pixels[index + 2] = colorpalet[cnum][2];
himg.pixels[index + 3] = colorpalet[cnum][3];
}
}
himg.updatePixels();
return himg;
}
//camera turn
function mouseDragged() {
lookatx += (pmouseX - mouseX) * 0.01;
lookatz += (pmouseY - mouseY) * 0.01;
if (lookatx > TWO_PI) lookatx -= TWO_PI; //loop
if (lookatx < 0) lookatx += TWO_PI;
if (lookatz > PI + QUARTER_PI) lookatz = PI + QUARTER_PI; //no loop
if (lookatz < PI - QUARTER_PI) lookatz = PI - QUARTER_PI;
}
// camera move
function keyinput() {
let zx = cos(lookatx) * 5;
let zz = sin(lookatx) * 5;
if (keyIsDown(87)) { //w
camerax += zx;
cameraz += zz;
} else
if (keyIsDown(83)) { //s
camerax -= zx;
cameraz -= zz;
}
zx = cos(lookatx + HALF_PI) * 5;
zz = sin(lookatx + HALF_PI) * 5;
if (keyIsDown(65)) { //a
camerax -= zx;
cameraz -= zz;
} else
if (keyIsDown(68)) { //d
camerax += zx;
cameraz += zz;
}
}
function setup() {
img = makeimage(spritedata, 16);
lookatz = 3.5; // PI;
lookatx = 1.6; // HALF_PI;
createCanvas(700, 400, WEBGL).parent("p5canvas");
shdr = createShader(vert, frag);
shader(shdr);
noStroke();
}
function draw() {
background(150, 150, 255);
keyinput();
shdr.setUniform('mydiffuse', sin(frameCount * 0.01));
camera(camerax, cameray, cameraz,
(cos(lookatx) * -cos(lookatz)) + camerax,
sin(lookatz) + cameray,
sin(lookatx) + cameraz, 0.0, 1.0, 0.0);
for (let [x, y, z] of trees) {
push();
translate(x, y, z);
rotateY(QUARTER_PI);
texture(img);
plane(255);
rotateY(HALF_PI);
plane(255);
pop();
}
push();
fill(0, 255, 0);
translate(0, 127, 0);
rotateX(HALF_PI);
plane(1000);
pop();
push();
translate(0, 0, 0);
rotateY(frameCount * 0.01);
texture(img);
plane(255);
rotateY(HALF_PI);
plane(255);
pop();
}
let vert = `
precision highp float;
precision highp int;
uniform bool uUseLighting;
uniform float mydiffuse;
void totalLight(
vec3 modelPosition,
vec3 normal,
out vec3 totalDiffuse,
out vec3 totalSpecular
) {
totalSpecular = vec3(0.0);
if (!uUseLighting) {
totalDiffuse = vec3(mydiffuse);
return;
}
totalDiffuse = vec3(0.0);
vec3 viewDirection = normalize(-modelPosition);
}
attribute vec3 aPosition;
attribute vec3 aNormal;
attribute vec2 aTexCoord;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
uniform mat3 uNormalMatrix;
varying highp vec2 vVertTexCoord;
varying vec3 vDiffuseColor;
varying vec3 vSpecularColor;
void main(void) {
vec4 viewModelPosition = uModelViewMatrix * vec4(aPosition, 1.0);
gl_Position = uProjectionMatrix * viewModelPosition;
vec3 vertexNormal = normalize(uNormalMatrix * aNormal);
vVertTexCoord = aTexCoord;
totalLight(viewModelPosition.xyz, vertexNormal, vDiffuseColor, vSpecularColor);
}`;
let frag = `
precision highp float;
uniform vec4 uMaterialColor;
uniform vec4 uTint;
uniform sampler2D uSampler;
uniform bool isTexture;
uniform bool uEmissive;
varying highp vec2 vVertTexCoord;
varying vec3 vDiffuseColor;
varying vec3 vSpecularColor;
void main(void) {
if(uEmissive && !isTexture) {
gl_FragColor = uMaterialColor;
}
else {
gl_FragColor = isTexture ? texture2D(uSampler, vVertTexCoord) * (uTint / vec4(255, 255, 255, 255)) : uMaterialColor;
gl_FragColor.rgb = gl_FragColor.rgb * vDiffuseColor + vSpecularColor;
}
if (gl_FragColor.a == 0.0) {
discard;
}
}`;
</script>