コースティクスシェーダ

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

[hlsl]
// 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.);
}
[/hlsl]

ちなみに元にしたコードは,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ともようやくサヨナラです。