0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

plunkerでshadertoy sandbox その 8

Last updated at Posted at 2024-12-06

概要

plunkerでshadertoyのglsl動かしてみた。
textureとtextureLodを実装してみた。

写真

image.png

投入したソース

#extension GL_EXT_shader_texture_lod : enable
precision mediump float;
uniform vec2 iResolution;
uniform float iGlobalTime;
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
uniform sampler2D iChannel2;
uniform vec4 iMouse;
uniform vec3 iChannelResolution[3];
uniform float iChannelTime[4];
#define iTime iGlobalTime
vec4 textureLod(sampler2D s, vec2 c, float b) {
	return texture2DLodEXT(s, c, b);
}
vec4 texture(sampler2D s, vec2 c) {
	return texture2D(s, c);
}

void mainImage2(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord / iResolution.xy;
    fragColor = texture(iChannel0, uv);
}
void mainImage0(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord / iResolution.xy;
    vec3 col = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0, 2, 4));
    fragColor = vec4(col, 1.0);
}
void mainImage1(out vec4 fragColor, in vec2 fragCoord) {
	vec2 uv = fragCoord / iResolution.xy;
	vec3 col = vec3(uv, 0);
	fragColor = vec4(col, 1.0);
}
void mainImage3(out vec4 fragColor, in vec2 fragCoord) {
	vec2 uv = fragCoord / iResolution.xy;
	uv.x *= 3.0;
	uv *= 0.1 + sin(iTime) * 0.5 + 0.5;
	vec4 t = texture(iChannel0, uv);
	vec4 t2 = textureLod(iChannel0, uv, 0.0);
	fragColor = t2;
	if (fragCoord.x / iResolution.x < 0.33)
	{
		fragColor = t;
	}
	if (fragCoord.x / iResolution.x > 0.66)
	{
		fragColor = abs(t - t2) * 10.0;
	}
}
mat2 rot(float a) {
	return mat2(sin(a), cos(a), -cos(a), sin(a));
}

void mainImage4(out vec4 fragColor, vec2 fragCoord) {
	vec2 p = (fragCoord - .5 * iResolution.xy ) / iResolution.y;
	float lod = log2(iChannelResolution[0].y / iResolution.y),
	d = 55. / 6.283,
	l = d * length(p) - 5.,
	s = - (iTime + 30.) * .01,
	l0 = s * floor(l - .5) ,
	l1 = s * floor (l + .5) ;
	if (fragCoord.x < 0.5 * iResolution.x) 
	{
		if (fragCoord.y < 0.5 * iResolution.y) 
		{
			fragColor = texture(iChannel0, p * rot(l0));
		} 
		else 
			fragColor = textureLod(iChannel0, p * rot(l0), lod);
		} 
	else 
	{
		float k = smoothstep(-.8, .8, iResolution.y / d * (fract(l - .5) - .5)); 
		if (fragCoord.y < 0.5 * iResolution.y) 
		{
			fragColor = mix(texture(iChannel0, p * rot(l0)), texture(iChannel0, p * rot(l1)), k);
		} 
		else 
		{
			fragColor = mix(textureLod(iChannel0, p * rot(l0), lod), textureLod(iChannel0, p * rot(l1), lod), k);
		}
	}
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
	vec2 uv = fragCoord.xy / iResolution.xy;
	vec3 col = textureLod(iChannel0, uv, (sin(iTime) + 1.) * 2.).xyz;
	fragColor = vec4(col, 1.0);
}

void main() {
	vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
	mainImage(color, gl_FragCoord.xy);
	color.w = 1.0;
	gl_FragColor = color;
}

サンプルコード


var gl;
var sc;
var AudioPlayer = function() {
	"use strict";
	this.audio = new Audio();
	this.audio.volume = 0.5;
	this.audio.loop = true;
	this.sound = new AudioContext();
	this.source = this.sound.createMediaElementSource(this.audio);
	this.node = this.sound.createScriptProcessor(2048, 1, 1);
	this.analyser = this.sound.createAnalyser();
	this.data = new Uint8Array(this.analyser.frequencyBinCount);
	this.analyser.smoothingTimeConstant = 0.8;
	this.analyser.fftSize = 128;
	this.source.connect(this.analyser);
	this.analyser.connect(this.node);
	this.node.connect(this.sound.destination);
	this.source.connect(this.sound.destination);
	this.loadMusic = function(url) {
		this.audio.src = url;
		this.audio.play();
	};
	this.getWave = function() {
		this.analyser.getByteFrequencyData(this.data);
		return this.data;
	};
	this.getTime = function() {
		return this.audio.currentTime;
	};
};
var repeat = (times, arr) => {
	let result = [];
	for (let i = 0; i < times; i++) 
	{
		result = [...result, ...arr];
	}
	return result;
}
var	audioPlayer;
var mx,
	my,
	cw,
	ch;
cw = window.innerWidth;
ch = window.innerHeigh;
var mouseOriX = 0;
var mouseOriY = 0;
var mousePosX = 0;
var mousePosY = 0;
var mouseIsDown = false;
function piGetCoords(obj) {
	var x = 0;
	var y = 0;
	do
	{
		 x += obj.offsetLeft;
		 y += obj.offsetTop;
	} while (obj = obj.offsetParent);
	return {
		mX: x,
		mY: y
	};
}
function onmousedown(ev) {
	var c = document.getElementById('canvas');
	var pos = piGetCoords(c);
	mouseOriX = (ev.pageX - pos.mX) * c.width / c.offsetWidth;
	mouseOriY = c.height - (ev.pageY - pos.mY) * c.height / c.offsetHeight;
	mousePosX = mouseOriX;
	mousePosY = mouseOriY;
	mouseIsDown = true;
}
function onmousemove(ev) {
	var c = document.getElementById('canvas');
	if (mouseIsDown)
	{
		var pos = piGetCoords(c);
		mousePosX = (ev.pageX - pos.mX) * c.width / c.offsetWidth;
		mousePosY = c.height - (ev.pageY - pos.mY) * c.height / c.offsetHeight;
	}
}
function onmouseup(ev) {
	var c = document.getElementById('canvas');
	mouseIsDown = false;
	mouseOriX = -Math.abs(mouseOriX);
	mouseOriY = -Math.abs(mouseOriY);
}
var ShaderDrawer = function(shader) {
	'use strict';
	var fs = gl.createShader(gl.FRAGMENT_SHADER);
	var	vs = gl.createShader(gl.VERTEX_SHADER);
	var	pr;
	gl.getExtension("EXT_shader_texture_lod");
	gl.shaderSource(vs, "attribute vec4 p;void main(){gl_Position = p;}");
	gl.shaderSource(fs, shader);
	gl.compileShader(vs);
	if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS))
	{
		alert("ng0");
		return null;
	}
	gl.compileShader(fs);
	if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS))
	{
		alert(gl.getShaderInfoLog(fs));
		return null;
	}
	pr = gl.createProgram();
	gl.attachShader(pr, vs);
	gl.attachShader(pr, fs);
	gl.linkProgram(pr);
	gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 1, 1, -3, -3, 1]), gl.STATIC_DRAW);
	this.prg = pr;
	this.create_texture = function(source) {
		var img = new Image();
		img.onload = function() {
			var tex = gl.createTexture();
			console.log(tex);
			gl.bindTexture(gl.TEXTURE_2D, tex);
			gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
		  gl.generateMipmap(gl.TEXTURE_2D);
		};
		img.src = source;
	}
	this.draw = function(tm, w, h, wave) {
		var iChannelResolutions = new Float32Array(repeat(4, [w, h, 0]));
		var mouse = [mousePosX, mousePosY, mouseOriX, mouseOriY];
		gl.viewport(0, 0, w, h);
		gl.useProgram(this.prg);
		gl.uniform1i(gl.getUniformLocation(this.prg, "iChannel0"), 0);
		gl.uniform1i(gl.getUniformLocation(this.prg, "iChannel1"), 0);
		gl.uniform1i(gl.getUniformLocation(this.prg, "iChannel2"), 0);
		gl.uniform2fv(gl.getUniformLocation(this.prg, "iResolution"), [w, h]);
		gl.uniform3fv(gl.getUniformLocation(this.prg, "iChannelResolution"), iChannelResolutions);
		gl.uniform4fv(gl.getUniformLocation(this.prg, "iMouse"), mouse);
		gl.uniform1f(gl.getUniformLocation(this.prg, "iGlobalTime"), tm);
		gl.enableVertexAttribArray(0);
		gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
		gl.drawArrays(gl.TRIANGLES, 0, 3);
	};
};
var Scene0 = function() {
	'use strict';
	this.init = function() {
		var shader = document.getElementById('src').value;
		this.sd = new ShaderDrawer(shader);
		this.sd.create_texture('lib/noise.png');
		this.sd.create_texture('lib/green.png');
		this.sd.create_texture('lib/mfu.png');
	};
	this.draw = function(scenetime, wave) {
		gl.clearColor(0, 0, 0, 1.0);
		gl.clear(gl.COLOR_BUFFER_BIT);
		this.sd.draw(scenetime, window.innerWidth, window.innerHeight, wave);
	};
	this.init();
	return this;
};
var	render = function() {
	'use strict';
	var wave = audioPlayer.getWave();
	var	timeCode = document.getElementById('timecode');
	var	demotime = audioPlayer.getTime();
	if (timeCode)
	{
		timeCode.innerHTML = demotime.toFixed(3);
  }
	sc.draw(demotime, wave);
	requestAnimationFrame(render);
};
var	init = function() {
	'use strict';
	var	timeOffset = 0;
	var	canvas = document.getElementById('canvas');
	gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
	gl.clearColor(0.0, 0.0, 0.0, 1.0);
	gl.clear(gl.COLOR_BUFFER_BIT);
	audioPlayer.loadMusic('lib/svg_girl_theme.mp3');
	canvas.addEventListener('mousemove', onmousemove, true);
	canvas.addEventListener('mousedown', onmousedown, true);
	canvas.addEventListener('mouseup', onmouseup, true);
	sc = new Scene0();
 	requestAnimationFrame(render);
};
var	resizeFunc = function() {
	'use strict';
	var canvas = document.getElementById('canvas');
	canvas.setAttribute('width', 665);
	canvas.setAttribute('height', 465);
};
var run = function() {
	'use strict';
	audioPlayer = new AudioPlayer();
	resizeFunc();
	var timecode = document.getElementById("timecode");
	if (timecode)
	{
		timecode.style.display = "";
	}
	init();
};
window.onresize = resizeFunc;




成果物

以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?