「つぶやきGLSLと形で覚えるfract」 - テルメモ
はじめに
GLSL初学者のfract関数のメモです。
関数の情報を集めて勉強しています、書きかけのメモです。
(調べたらアップデートします: 20230402 updated)
fractの基本
GLSLの組み込み関数を読む時に
いつも参考にさせていただいている記事のfractと「リアルタイムグラフィックスの数学」を参考にしました。
fractの引数に値を入れると、xからx以下の最大の整数を引いた値を返してくれる。
fractに正の値を入れた時は、整数と小数に分け、少数だけを返す。負の値を入れた場合は、整数と小数に分け、fract(x) = x - [x]で計算した値を返す。
fract関数に正の値を入れた場合は、整数部分と小数部分に分けて小数部分だけを返します。
負の値を入れた場合は、整数部分と小数部分に分けて、fract(x) = x - [x]の式を使って計算した値を返します。ここで、[x]はxの床値(floor value)を表しています。
例:
fract(2.3) = 2.3 - ⌊2.3⌋ = 2.3 - 2 = 0.3
fract(-2.3) = -2.3 - ⌊-2.3⌋ = -2.3 - (-3) = 0.7
fract - fractionalは日本語で分数で。では分数とは。
The Book of Shaders の図解
実際の数値を入れた時の返ってくる値
fract(x)関数は、数値xの小数部分を返す関数です。整数部分を取り除いた値が結果となります。
fract(2.3)の場合、2.3は、整数部分2と小数部分0.3に分けられます。fract関数は小数部分のみを取り出すため、0.3が取り出されます。
従って、fract(2.3)の結果は0.3となります。
fract(-2.3)の場合、-2.3は、整数部分-2と小数部分-0.3に分けられます。fract関数は小数部分のみを取り出すため、-0.3が取り出されます。
ただし、fract関数の結果は常に正の値であるべきです。そのため、-0.3を正の値に変換する必要があります。これは、1に-0.3を加えることで実現できます。
1 + (-0.3) = 0.7
従って、fract(-2.3)の結果は0.7となります。
つぶやきGLSLで試す
つぶやきGLSLのデフォルト表示のループ内、最初のabs箇所をfractに変えると分割されて表示される。(geekerモードです)
void main(){
vec2 p=(gl_FragCoord.xy*2.-r)/min(r.y,r.x);
for(int i=0;i<8;++i){
p.xy=fract(p)/abs(dot(p,p))-vec2(.9+cos(t*.2)*.4);
}
gl_FragColor=vec4(p.xxy,1);
}
もっと単純にしてみる
void main(){
vec2 p=(gl_FragCoord.xy*2.-r)/min(r.y,r.x);
gl_FragColor=vec4(fract(p.x),fract(p.y),1,1);
}
単純にしたものにTimeを掛けてみる
void main(){
vec2 p=(gl_FragCoord.xy*2.-r)/min(r.y,r.x);
gl_FragColor=vec4(fract(p.x*t),fract(p.y*t),1,1);
}
その他メモ
すぐの発展はないけど、ここから発見がありそうなのでメモ。
Question about Frac() in GLSL shader
中のソースで試してみる。
#define F(x) floor(x) - ceil(x) + min(ceil(x),1.) + fract(x)
void main(){
vec2 p=(gl_FragCoord.xy*2.)/min(r.y,r.x);
gl_FragColor=vec4(F(p.x*t),F(p.y*t),1,1);
}
ズームブラーフィルタ
ランダム内でも使われていたりする。
precision mediump float;
uniform sampler2D texture;
uniform float strength;
varying vec2 vTexCoord;
const float tFrag = 1.0 / 512.0;
const float nFrag = 1.0 / 30.0;
const vec2 centerOffset = vec2(256.0, 256.0);
float rnd(vec3 scale, float seed){
return fract(sin(dot(gl_FragCoord.stp + seed, scale)) * 43758.5453 + seed);
}
void main(void){
vec3 destColor = vec3(0.0);
float random = rnd(vec3(12.9898, 78.233, 151.7182), 0.0);
vec2 fc = vec2(gl_FragCoord.s, 512.0 - gl_FragCoord.t);
vec2 fcc = fc - centerOffset;
float totalWeight = 0.0;
for(float i = 0.0; i <= 30.0; i++){
float percent = (i + random) * nFrag;
float weight = percent - percent * percent;
vec2 t = fc - fcc * percent * strength * nFrag;
destColor += texture2D(texture, t * tFrag).rgb * weight;
totalWeight += weight;
}
gl_FragColor = vec4(destColor / totalWeight, 1.0);
}
Soundとfract
#define n(n) fract(sin(n)*4.)
void main(){
vec2 p=(gl_FragCoord.xy*2.-r)/max(r.y,r.x);
gl_FragColor=vec4(1.-fract(n(s)+p.x*p.x), 1.-fract(n(s)+p.y*p.y), 1., 1.);
}
vec2 mainSound(float t){
return vec2(sin(.2831*256.*t*3.)+pow(fract(5.2831*2.*t*.5),.4));
}
分からないことだらけやで。
この記事が気に入ったらサポートをしてみませんか?