2022年11月20日日曜日

p5jsの透過処理バグ回避のシェーダーの設定

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>

0 件のコメント:

コメントを投稿

Arduino IDE が "Downloading index: library_index.tar.bz2" で固まる問題

PCとのシリアル通信が原因の一つらしい '/home/usename/.arduino15/packages' を消すといいらしい ので消すと治った IDEの起動中にフリーズしてたのが治った Downloading index: library_ind...