![見出し画像](https://assets.st-note.com/production/uploads/images/23759618/rectangle_large_type_2_838ad99cfd5c7e67ebeea6b52cb4f588.png?width=1200)
「つぶやき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(x)
x-floor(x)を返す
参考:
GLSLについてのメモ
リアルタイムグラフィックスの数学―GLSLではじめるシェーダプログラミング
fract - fractionalは日本語で分数で。では分数とは。
分数(ぶんすう、英: fraction)とは 2 つの数の比を用いた数の表現方法のひとつである。
参考: Wikipedia 分数
The Book of Shaders の図解
The Book of Shaders - fract
https://thebookofshaders.com/glossary/?search=fract
実際の数値を入れた時の返ってくる値
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);
}
もっと単純にしてみる
![スクリーンショット 2020-04-24 4.16.31](https://assets.st-note.com/production/uploads/images/23759273/picture_pc_7f6897f7ccdbd60e9cd321a41df484cf.png?width=1200)
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
fract(x)を使った時に、分数のxを返しますよね。
これは 0から0.99999999を無限に返します、これはあっていますか?
中のソースで試してみる。
#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);
}
ズームブラーフィルタ - wgld.org
https://wgld.org/d/webgl/w067.html
Soundとfract
#つぶやきGLSL#define n(n) fract(sin(n)*4.)
— テル・豊田 / TERU Inc. (@teruhito_toyoda) April 19, 2020
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));
} pic.twitter.com/sj3LT25HcM
#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));
}
分からないことだらけやで。