見出し画像

🎡コースティクスと光の包絡線

「コースティクス」と「カスプ」は、光や曲線に関連する用語であり、それぞれ異なる文脈で使われることが多いですが、以下にその特徴と違いを説明します。
コースティクス (Caustics)
コンピュータグラフィックスや光学の文脈で使われることが多い。
コースティクスは、光が透明な物体や水面などを通過する際に生じる、集中した明るいパターンや模様のことを指します。例えば、水中のプールの底に見られる太陽光の模様や、拡大鏡を使って光を焦点に集めたときの明るい部分などがこれに該当します。
これらの効果は、レンダリングでリアルなイメージを生成するためにしばしばシミュレートされます。
カスプ (Cusp)
数学や曲線の文脈で使われることが多い。
カスプは、曲線や曲面上の点で、その点だけが急激に方向を変える場所を指します。カスプの位置では、曲線の接線が存在しない、または接線が突然変わる点として表現されます。
例としては、心形の曲線(ハートの形)の下部の先端などがカスプとして考えられます。

光学学では、コースティクスまたはコースティクスネットワーク[1]とは、曲面または物体によって反射または屈折された光線の包絡線、またはその包絡線を別の面に投影したものである[2]。 カウスティックは、光線のそれぞれが接線する曲線または面であり、光線の包絡線の境界を集光の曲線として定義している[2]。 これらの形状はしばしばカスプ特異点を持つ。

数学では、カスプ(古いテキストではスピノーデと呼ばれることもあります)とは、曲線上で移動する点が方向を逆にしなければならない点のことです。

// Found this on GLSL sandbox. I really liked it, changed a few things and made it tileable.
// :)
// by David Hoskins.
// Original water turbulence effect by joltz0r


// Redefine below to see the tiling...
//#define SHOW_TILING
 #define  TAU 6.28318530718 #define  MAX_ITER 5

void mainImage( out vec4 fragColor, in vec2 fragCoord ) 
{
	float time = iTime * .5+23.0;
    // uv should be the 0-1 uv of texture...
	vec2 uv = fragCoord.xy / iResolution.xy;
     #ifdef  SHOW_TILING
	vec2 p = mod(uv*TAU*2.0, TAU)-250.0; #else 
    vec2 p = mod(uv*TAU, TAU)-250.0; #endif 
	vec2 i = vec2(p);
	float c = 1.0;
	float inten = .005;

	for (int n = 0; n < MAX_ITER; n++) 
	{
		float t = time * (1.0 - (3.5 / float(n+1)));
		i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x));
		c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten),p.y / (cos(i.y+t)/inten)));
	}
	c /= float(MAX_ITER);
	c = 1.17-pow(c, 1.4);
	vec3 colour = vec3(pow(abs(c), 8.0));
    colour = clamp(colour + vec3(0.0, 0.35, 0.5), 0.0, 1.0);

 #ifdef  SHOW_TILING
	// Flash tile borders...
	vec2 pixel = 2.0 / iResolution.xy;
	uv *= 2.0;
	float f = floor(mod(iTime*.5, 2.0)); 	// Flash value.
	vec2 first = step(pixel, uv) * f;		   	// Rule out first screen pixels and flash.
	uv  = step(fract(uv), pixel);				// Add one line of pixels per tile.
	colour = mix(colour, vec3(1.0, 1.0, 0.0), (uv.x + uv.y) * first.x * first.y); // Yellow line
 #endif 
    
	fragColor = vec4(colour, 1.0);
}

このシェーダーコードは、GLSL(OpenGL Shading Language)を使用して、動的な水の乱流エフェクトを作成しています。以下にコードの各部分の詳細な説明を行います。

定数とマクロの定義

 #define  TAU 6.28318530718 #define  MAX_ITER 5
  • `TAU` は (2\pi) の値で、円周率の倍数です。

  • `MAX_ITER` はループの最大反復回数を定義しています。

メイン関数

void mainImage( out vec4 fragColor, in vec2 fragCoord ) 
{
    float time = iTime * .5+23.0;
    vec2 uv = fragCoord.xy / iResolution.xy;
  • `mainImage` は、各ピクセルの色を計算するメイン関数です。

  • `fragCoord` は現在のフラグメント(ピクセル)の座標です。

  • `time` はアニメーションのための時間変数で、`iTime` はシステムから提供される経過時間です。

  • `uv` はテクスチャ座標(0から1の範囲)を計算しています。

タイリングのための条件分岐

 #ifdef  SHOW_TILING
    vec2 p = mod(uv*TAU*2.0, TAU)-250.0; #else 
    vec2 p = mod(uv*TAU, TAU)-250.0; #endif 
  • `SHOW_TILING` が定義されている場合、タイリングを表示するための条件分岐です。

  • `p` はモジュロ演算を使用してテクスチャ座標を TAU の範囲内に収め、視覚的なタイル効果を作成します。

乱流の計算

vec2 i = vec2(p);
float c = 1.0;
float inten = .005;

for (int n = 0; n < MAX_ITER; n++) 
{
    float t = time * (1.0 - (3.5 / float(n+1)));
    i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x));
    c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten),p.y / (cos(i.y+t)/inten)));
}
  • `i` は `p` のコピーで、乱流の計算に使用されます。

  • `c` は乱流の強度を示す変数です。

  • `inten` は乱流の強度の調整に使用される定数です。

  • ループの中で、現在の時間と座標に基づいて `i` を更新し、乱流のパターンを生成します。

色の計算

c /= float(MAX_ITER);
c = 1.17-pow(c, 1.4);
vec3 colour = vec3(pow(abs(c), 8.0));
colour = clamp(colour + vec3(0.0, 0.35, 0.5), 0.0, 1.0);
  • `c` を反復回数で割り、正規化します。

  • `c` にべき乗を適用して強度を調整し、カラー値を計算します。

  • 最終的なカラー値に追加の補正を加え、範囲を 0.0 から 1.0 にクランプします。

タイルの境界線の表示

 #ifdef  SHOW_TILING
vec2 pixel = 2.0 / iResolution.xy;
uv *= 2.0;
float f = floor(mod(iTime*.5, 2.0)); 
vec2 first = step(pixel, uv) * f;
uv = step(fract(uv), pixel);
colour = mix(colour, vec3(1.0, 1.0, 0.0), (uv.x + uv.y) * first.x * first.y); #endif 
  • `SHOW_TILING` が定義されている場合、タイルの境界線を表示します。

  • `pixel` はピクセルサイズを計算します。

  • `uv` を調整してタイルの境界線を強調します。

  • `colour` を混ぜて境界線を黄色にします。

フラグメントの色の設定

fragColor = vec4(colour, 1.0);
  • 最終的に計算されたカラー値を `fragColor` に設定し、フラグメントの色として出力します。

このシェーダーは、GLSL の基本的な機能を使用して、動的で視覚的に魅力的な水の乱流エフェクトを生成する方法を示しています。タイリングオプションを使うことで、エフェクトを無限に繰り返すことも可能です。

お願い致します