Simple Water Caustic Pattern In Unity ShaderGpaph

发布时间:2023年12月18日

shadertoy上有各种神奇的效果,以我的见识根本想象不到这些是怎么弄出来的。

不过不会做至少可以先会用。

这篇文章抓取一个shadertoy的示例以制作一个测试效果。

?参考这篇shadertoy,使用自定义节点装填hlsl的noise代码

Shader - Shadertoy BETA

?首先使用世界xz坐标作为uv,添加tiling&offset调整。

表现为这样子

?具体做法是创建hlsl文件写入计算方法,shadertoy上的写法和unity hlsl中有些区别,按位置诸葛替换掉即可。

float4 mod289(float4 x)
{
    return x - floor(x / 289.0) * 289.0;
}

float4 permute(float4 x)
{
    return mod289((x * 34.0 + 1.0) * x);
}

float4 snoise(float3 v)
{
    const float2 C = float2(1.0 / 6.0, 1.0 / 3.0);

    // First corner
    float3 i  = floor(v + dot(v, C.yyy));
    float3 x0 = v   - i + dot(i, C.xxx);

    // Other corners
    float3 g = step(x0.yzx, x0.xyz);
    float3 l = 1.0 - g;
    float3 i1 = min(g.xyz, l.zxy);
    float3 i2 = max(g.xyz, l.zxy);

    float3 x1 = x0 - i1 + C.x;
    float3 x2 = x0 - i2 + C.y;
    float3 x3 = x0 - 0.5;

    // Permutations
    float4 p =
      permute(permute(permute(i.z + float4(0.0, i1.z, i2.z, 1.0))
                            + i.y + float4(0.0, i1.y, i2.y, 1.0))
                            + i.x + float4(0.0, i1.x, i2.x, 1.0));

    // Gradients: 7x7 points over a square, mapped onto an octahedron.
    // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
    float4 j = p - 49.0 * floor(p / 49.0);  // mod(p,7*7)

    float4 x_ = floor(j / 7.0);
    float4 y_ = floor(j - 7.0 * x_); 

    float4 x = (x_ * 2.0 + 0.5) / 7.0 - 1.0;
    float4 y = (y_ * 2.0 + 0.5) / 7.0 - 1.0;

    float4 h = 1.0 - abs(x) - abs(y);

    float4 b0 = float4(x.xy, y.xy);
    float4 b1 = float4(x.zw, y.zw);

    float4 s0 = floor(b0) * 2.0 + 1.0;
    float4 s1 = floor(b1) * 2.0 + 1.0;
    float4 sh = -step(h, 0);

    float4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
    float4 a1 = b1.xzyw + s1.xzyw * sh.zzww;

    float3 g0 = float3(a0.xy, h.x);
    float3 g1 = float3(a0.zw, h.y);
    float3 g2 = float3(a1.xy, h.z);
    float3 g3 = float3(a1.zw, h.w);

    // Compute noise and gradient at P
    float4 m = max(0.6 - float4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
    float4 m2 = m * m;
    float4 m3 = m2 * m;
    float4 m4 = m2 * m2;
    float3 grad =
      -6.0 * m3.x * x0 * dot(x0, g0) + m4.x * g0 +
      -6.0 * m3.y * x1 * dot(x1, g1) + m4.y * g1 +
      -6.0 * m3.z * x2 * dot(x2, g2) + m4.z * g2 +
      -6.0 * m3.w * x3 * dot(x3, g3) + m4.w * g3;
    float4 px = float4(dot(x0, g0), dot(x1, g1), dot(x2, g2), dot(x3, g3));
    return 42.0 * float4(grad.xyz, dot(m4, px));
}

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

void water_caustics_float(float3 posIn, out float noiseOut) {
    float4 n = snoise( posIn );

    posIn -= 0.07*n.xyz;
    posIn *= 1.62;
    n = snoise( posIn );

    posIn -= 0.07*n.xyz;
    n = snoise( posIn );

    posIn -= 0.07*n.xyz;
    n = snoise( posIn );

    noiseOut = exp(n.w*3 - 1.5f);
}

?但是注意,想要在unity的自定义节点中输出,必须要在调用方法中使用out关键字,有几个输出就添加几个out,并且方法名最后添加_float后缀,然后在自定义节点中引用此hlsl文件,设置传入值和输出值。

?直接输出到颜色上,然后抄一下网站中xz使用位置,y使用时间。

?这种效果就来了。

?再搞一搞颜色,这里用了浅蓝和灰色代表光照强和光照弱的位置

文章来源:https://blog.csdn.net/qq_55895529/article/details/134982976
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。