コースティクスシェーダ

ShaderToyにいい実装があったので,自分なりにパラメータ調整したやつ。

// Based on: https://www.shadertoy.com/view/3d3yRj
// See also: KdotJPG's https://www.shadertoy.com/view/wlc3zr

float water_caustics(vec3 pos, float thickness) {
    vec4 n = snoise( pos );

    pos -= thickness*n.xyz;
    n = snoise( pos );

    pos -= thickness*n.xyz;
    n = snoise( pos );

    pos -= thickness*n.xyz;
    n = snoise( pos );
    return n.w;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 p = (-iResolution.xy + 2.0*fragCoord) / iResolution.y;

    // camera matrix
    vec3 ww = normalize(-vec3(0., 1., 0.8));
    vec3 uu = normalize(cross(ww, vec3(0., 1., 0.)));
    vec3 vv = normalize(cross(uu,ww));

    vec3 rd = p.x*uu + p.y*vv + 1.5*ww;	// view ray
    vec3 pos = -ww + rd*(ww.y/rd.y);	// raytrace plane
    
    pos.y = iTime*0.25;	// animate noise slice
    pos *= 3.;		// tiling frequency

    float w = mix(water_caustics(pos, 0.085), water_caustics(pos + 1.0, 0.085), 0.5);

    // noise [-1..+1] -> color
    float intensity = exp(w*2.5 - 1.);
    fragColor = vec4(vec3(intensity), 1.);
}

ちなみに元にしたコードは,https://www.shadertoy.com/view/ssfBDfにあります。

サヨナラGLSL…

こんにちわ,Pocolです。
久しぶりにa3dの更新作業をやっています。
今日は,ついにGLSLから脱却する対応を入れました。

…といっても大したことはしていなくて,DXCからSpir-Vを生成するようにしただけです。
ただ,普通のHLSLの記述だと対応できないそうなので,マクロをかまして対応するという感じにしました。
マクロの定義は下記の通り。

#ifdef __spirv__
#define A3D_LOCATION(index)              [[vk::location(index)]]
#define A3D_RESOURCE(var, reg, index)    [[vk::binding(index)]] var
#define A3D_FLIP_Y(var)                  var.y = -var.y
#else
#define A3D_LOCATION(index)
#define A3D_RESOURCE(var, reg, index)    var : register(reg)
#define A3D_FLIP_Y(var)
#endif

Vulkanの座標系はDirectXと比べて上下逆になる座標系なので,フリップ用のマクロも定義してあります。
実際のシェーダは下記のように書きます。

///////////////////////////////////////////////////////////////////////////////////////////////////
// VSOutput structure
///////////////////////////////////////////////////////////////////////////////////////////////////
struct VSOutput
{
    A3D_LOCATION(0) float4 Position : SV_POSITION;
    A3D_LOCATION(1) float2 TexCoord : TEXCOORD;
};

///////////////////////////////////////////////////////////////////////////////////////////////////
// PSOutput structure
///////////////////////////////////////////////////////////////////////////////////////////////////
struct PSOutput
{
    A3D_LOCATION(0) float4 Color : SV_TARGET0;
};

//-------------------------------------------------------------------------------------------------
// Samplers and Textures
//-------------------------------------------------------------------------------------------------
A3D_RESOURCE(SamplerState ColorSmp, s0, 1);
A3D_RESOURCE(Texture2D    ColorMap, t0, 2);

//-------------------------------------------------------------------------------------------------
//      ピクセルシェーダメインエントリーポイントです.
//-------------------------------------------------------------------------------------------------
PSOutput main(VSOutput input)
{
    PSOutput output = (PSOutput)0;

    output.Color = ColorMap.Sample( ColorSmp, input.TexCoord );

    return output;
}

あとは,dxc.exeで -spirv のオプションを付けてコンパイルするだけです。
DirectX用とVulkan用のシェーダバイナリの両方が1つのシェーダコードから生成できます。

これで,GLSLともようやくサヨナラです。