エラーが発生しています。

シェーダで描画

by K-s, at 2017年1月28日 21:50:03

powered by hsp3dish.js / OpenHSP

コメント
説明

画面を覆う板ポリにフラグメントシェーダで描画します。

シェーダについて
投稿サイト

; 2.21: fs2.frag マウスの位置で色変化するように変更。
; 2.18-19: シェーダ追加。
; 2.17: シェーダ追加。スペースキーで切替できるように変更。

#include "hgimg4.as"

#module 

; 経過時間とFPSを返す
#deffunc timer var _t, var _fps
	getreq _t, SYSREQ_TIMER ; 起動してからの経過時間(ミリ秒)
	dt += _t - pre
	pre = _t
	fcnt++
	if (dt >= 500) { ; 500ms 毎に更新
		fps = double(fcnt) / dt * 1000
		fcnt = 0
		dt = 0
	}
	_fps = fps
	return

#global 

*start

	fs = "fs.frag", "fs2.frag", "fs3.frag", "fs4.frag", "fs5.frag"
	num = length(fs)
	
	repeat num
		
		; シェーダの登録
		gpusermat mat(cnt), "vs.vert", fs(cnt), ""
		
		; キャンバス用の板ポリを用意
		; 大きさ(2,2)で画面全体を覆う(バーテックスシェーダの内容に依るかも)
		gpplate plate(cnt), 2, 2, , mat(cnt)
		
		; とりあえず非表示
		setobjmode plate(cnt), OBJ_HIDE, 0
		
	loop
	
	dispID = 0
	setobjmode plate(dispID), OBJ_HIDE, 1 ; 表示

*mainLoop

	timer t, fps
	
	stick key, 256
	
	; 切り替え
	if (key & 16) {
		dispID = (dispID + 1) \ num
		repeat num
			if (cnt == dispID) {
				setobjmode plate(cnt), OBJ_HIDE, 1 ; 表示
			} else {
				setobjmode plate(cnt), OBJ_HIDE, 0 ; 非表示
			}
		loop
	}
	
	redraw 0
	
	; シェーダのuniform変数に渡す値を設定
	; 変数の型に応じて命令を変える
	; float -> gpmatprm1
	; vec3 -> gpmatprm
	; vec4 -> gpmatprm4
	gpmatprm mat(dispID), "resolution", 640, 480, 0
	gpmatprm mat(dispID), "mouse", double(mousex) / 480, double(mousey) / 480, (key & 256) > 0
	gpmatprm1 mat(dispID), "time", double(t) / 1000
	
	gpdraw
	
	
	repeat 2
		c = 255 * cnt
		color c, c, c
		pos 10 - cnt, 10 - cnt
		mes strf("No.%2d", dispID + 1)
		pos 560 - cnt, 450 - cnt
		mes strf("fps %5.1f", fps)
	loop
	
	redraw 1
	
	await 1

	goto *mainLoop


/* シェーダファイルの内容

vs.vert:

	attribute vec4 a_position;
	void main(void){
		gl_Position = a_position;
	}

fs.frag:

	precision mediump float;
	
	uniform vec3 resolution;
	uniform vec3 mouse;
	uniform float time;
	
	void main(void){
		vec2 m = vec2(mouse.x * 2.0 - 1.0, -mouse.y * 2.0 + 1.0);
		vec2 p = gl_FragCoord.xy / min(resolution.x, resolution.y) * 2.0 - 1.0;
		float t = (mouse.z * 0.2 + sin(time) * 0.1 + 0.2) / length(m - p);
		gl_FragColor = vec4(vec3(t), 1.0);
	}

fs2.frag:

	precision mediump float;
	
	uniform float time;
	uniform vec3 mouse;
	uniform vec3 resolution;
	
	float circles(vec2 pos, float grid, float rad, float spd){
		float a = time * spd;
		pos = mat2(cos(a), -sin(a), sin(a),  cos(a)) * pos;
		vec2 d = vec2(mod(pos * grid, 1.0) - 0.5);
		float b = pow(sin(time * rad) * 0.3 + 0.4, 2.0);
		return step(b, dot(d, d));
	}
	
	void main(void){
		vec2 p = gl_FragCoord.xy / min(resolution.x, resolution.y);
		vec3 c = vec3(0);
		float g = mouse.z * 10.0;
		vec3 d = vec3(mouse.x);
		d.y = (1.0 - d.x) * mouse.y;
		d.z = 1.0 - d.x - d.y;
		c += d.xyz * circles(p, 3.0 + g, 0.9,  0.04);
		c += d.yzx * circles(p, 4.0 + g, 0.8,  0.03);
		c += d.zxy * circles(p, 5.0 + g, 0.7, -0.02);
		gl_FragColor = vec4(c, 1.0);
	}

fs3.frag:

	precision mediump float;
	
	uniform float time;
	uniform vec3 mouse;
	uniform vec3 resolution;
	
	vec3 hsv(float h, float s, float v){
		vec4 t = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
		vec3 p = abs(fract(vec3(h) + t.xyz) * 6.0 - vec3(t.w));
		return v * mix(vec3(t.x), clamp(p - vec3(t.x), 0.0, 1.0), s);
	}
	
	vec2 rot(vec2 p, float a){
		return mat2(cos(a), sin(a), -sin(a), cos(a)) * p;
	}
	
	void main(void){
		vec2 p = (gl_FragCoord.xy * 2.0 - resolution.xy) / min(resolution.x, resolution.y);
		p = rot(p * (1.0 - mouse.z * 0.5), time * 0.03);
		int j = 0;
		vec2 x = vec2(-0.6, 0.7);
		vec2 y = vec2(mouse.x - 0.1, 0.0);
		vec2 z = p;
		for(int i = 0; i < 360; i++){
			j++;
			if(length(z) > 2.0) break;
			z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + x + y;
		}
		float h = abs(mod(mouse.y * 360.0 - float(j * 4), 360.0) / 360.0);
		gl_FragColor = vec4(hsv(h, 0.5, 1.0), 1.0);
	}

fs4.frag:

	precision mediump float;
	
	uniform float time;
	uniform vec3 mouse;
	uniform vec3 resolution;
	
	#define ITE_MAX      32
	#define DIST_MIN     0.01
	#define DIST_MAX     10.0
	
	vec2 rot(vec2 p, float a){
		return mat2(cos(a), sin(a), -sin(a), cos(a)) * p;
	}
	
	float map(vec3 p){
		float t = DIST_MAX;
		float w = 0.0;
		p.xz = mod(p.xz, 1.0) - 0.5;
		w = dot((p), vec3(0.0, 1.0, 0.0));
		t = min(t, w);
		vec3 y = vec3(0.0, 1.0 - mouse.x, 0.0);
		w = (mouse.z < 1.0) ?
			length(p - y) - 0.4:
			length(max(abs(p - y) - vec3(0.3), 0.0));
		t = min(t, w);
		return t;
	}
	
	void main(void){
		vec2 uv = (gl_FragCoord.xy / resolution.xy) * 2.0 - 1.0;
		float asp = resolution.x / resolution.y;
		vec3 dir = normalize(vec3(uv * vec2(asp, 1.0), 1.0));
		dir.yz = rot(dir.yz, sin(time * 0.4) * (0.4 + mouse.y * 0.4));
		dir.xz = rot(dir.xz, time * 0.3);
		vec3 pos = vec3(0.0, sin(time * 0.4) * 0.7 + 0.71 + mouse.y, time);
		float t = 0.0;
		for(int i = 0 ;i < ITE_MAX; i++) {
			float d = map(t * dir + pos);
			if(d < DIST_MIN) break;	
			t += d;
		}	
		vec3 c = vec3(map(t * dir + pos + 0.4));	
		gl_FragColor = vec4(c + dir * 0.5, 1.0);
	}

	// http://tokyodemofest.jp/2015/pages/common/glslsemi/index.html

fs5.frag:

	precision mediump float;

	uniform float time;
	uniform vec3 mouse;
	uniform vec3 resolution;

	#define ITE_MAX   6
	#define DIST_MIN  0.01
	#define DIST_MAX  1000.0
	#define PI        3.14159265

	float perlin(vec3 p){
		vec3 i = floor(p);
		vec4 a = dot(i, vec3(1.0, 57.0, 21.0)) + vec4(0.0, 57.0, 21.0, 78.0);
		vec3 f = cos((p - i) * PI) * (-0.5) + 0.5;
		a = mix(sin(cos(a) * a), sin(cos(1.0 + a) * (1.0 + a)), f.x);
		a.xy = mix(a.xz, a.yw, f.y);
		return mix(a.x, a.y, f.z);
	}

	float map(vec3 p){
		vec2 s = vec2(0.3 + mouse.x * 0.3, 5.0 + mouse.y * 10.0);
		return min(DIST_MAX, length(p) - s.x + perlin(p * s.y) * 0.1);
	}

	vec2 rot(vec2 p, float a){
		return mat2(cos(a), sin(a), -sin(a), cos(a)) * p;
	}

	void rotc(inout vec2 d, inout vec2 p, float a){
		d = rot(d, time * a);
		p = rot(p, time * a);
	}

	void main(void){
		vec2 uv = (gl_FragCoord.xy / resolution.xy) * 2.0 - 1.0;
		float asp = resolution.x / resolution.y;
		vec3 dir = normalize(vec3(uv * vec2(asp, 1.0), 1.0));
		vec3 pos = vec3(0.0, 0.0, -1.0);
		rotc(dir.xz, pos.xz, 0.3);
		rotc(dir.zy, pos.zy, 0.4);
		rotc(dir.xy, pos.xy, 0.5);
		vec3 p = vec3(0.0);
		float d, t = 0.0;
		for(int i = 0 ; i < ITE_MAX; i++) {
			p = t * dir + pos;
			d = map(p);
			if(d < DIST_MIN) break;
			t += d;
		}
		vec3 c = abs(vec3(mouse.z) - perlin(vec3(map(p + t))) * dir);
		gl_FragColor = vec4(c, 1.0);
	}

*/

作成者
icon

K-s

ここはユーザの紹介文

詳しく...


関連プログラム