4

ashima/webgl-noisesimplexからのノイズを使用する太陽面のシェーダーを実装しました。しかし、特にモバイル デバイスで使用する場合は、GPU 時間がかかりすぎます。同じ効果を行う必要がありますが、ノイズ テクスチャを使用します。私のフラグメントシェーダーは以下の通りです:

#ifdef GL_ES
precision highp float;
#endif
precision mediump float;

varying vec2 v_texCoord;
varying vec3 v_normal;

uniform sampler2D u_planetDay;
uniform sampler2D u_noise; //noise texture (not used yet)
uniform float u_time;

#include simplex_noise_source from Ashima

float noise(vec3 position, int octaves, float frequency, float persistence)   {
float total = 0.0; // Total value so far
float maxAmplitude = 0.0; // Accumulates highest theoretical amplitude
float amplitude = 1.0;
for (int i = 0; i < octaves; i++) {
    // Get the noise sample
    total += ((1.0 - abs(snoise(position * frequency))) * 2.0 - 1.0) * amplitude;
    //I USE LINE BELOW FOR 2D NOISE
    total += ((1.0 - abs(snoise(position.xy * frequency))) * 2.0 - 1.0) * amplitude;
    // Make the wavelength twice as small
    frequency *= 2.0;
    // Add to our maximum possible amplitude
    maxAmplitude += amplitude;
    // Reduce amplitude according to persistence for the next octave
    amplitude *= persistence;
}
// Scale the result by the maximum amplitude
return total / maxAmplitude;
}

void main()
{   
    vec3 position = v_normal *2.5+ vec3(u_time, u_time, u_time);   
    float n1 = noise(position.xyz, 2, 7.7, 0.75) * 0.001;

    vec3 ground = texture2D(u_planetDay, v_texCoord+n1).rgb;
    gl_FragColor = vec4 (color, 1.0);
 }

このシェーダをノイズ テクスチャで動作するように修正するにはどうすればよいですか? また、テクスチャはどのように見えるべきですか?

私の知る限り、OpenGL ES 2.03D テクスチャはサポートされていません。また、3D テクスチャの作成方法がわかりません。

4

2 に答える 2

3

この 3D ノイズは 2D テクスチャ関数から書きました。x/の方向にはまだハードウェア補間を使用yし、手動で を補間しzます。方向に沿ってノイズを取得するためにz、同じテクスチャを異なるオフセットでサンプリングしました。これはおそらくいくつかの繰り返しにつながるでしょうが、私は自分のアプリケーションで何も気づいていません.素数の助けを使用していると思います.

shadertoy.comでしばらく困惑していたのは、テクスチャ ミップ マッピングが有効になっていて、関数の値の変化で継ぎ目が発生していたことfloor()です。手っ取り早い解決策は、-999バイアスをに渡すことでしたtexture2D

これは 256x256 のノイズ テクスチャ用にハード コードされているため、適宜調整してください。

float noise3D(vec3 p)
{
    p.z = fract(p.z)*256.0;
    float iz = floor(p.z);
    float fz = fract(p.z);
    vec2 a_off = vec2(23.0, 29.0)*(iz)/256.0;
    vec2 b_off = vec2(23.0, 29.0)*(iz+1.0)/256.0;
    float a = texture2D(iChannel0, p.xy + a_off, -999.0).r;
    float b = texture2D(iChannel0, p.xy + b_off, -999.0).r;
    return mix(a, b, fz);
}

更新:パーリン ノイズに拡張するには、さまざまな周波数でサンプルを合計します。

float perlinNoise3D(vec3 p)
{
    float x = 0.0;
    for (float i = 0.0; i < 6.0; i += 1.0)
        x += noise3D(p * pow(2.0, i)) * pow(0.5, i);
    return x;
}
于 2015-06-04T12:57:13.367 に答える
2

実行時にノイズを評価しようとすることは、調査作業を行うか、ノイズ関数をすばやくチェック/デバッグする (またはノイズ パラメーターが視覚的にどのように見えるかを確認する) 場合を除いて、多くの場合悪い習慣です。

これは常に処理予算を消費しすぎる (まったく価値がない) ため、実行時にノイズを評価することは忘れてください。

ノイズの結果をオフラインで保存すると、メモリへの単純なアクセスに料金が (たとえば 95% 以上) 削減されます。

これらすべてを、事前にベイクされた 2D ノイズ イメージに対するテクスチャ ルックアップに減らすことをお勧めします。これまでのところ、フラグメント パイプラインにのみ影響を与えているため、2D ノイズ テクスチャが最適です (この 2D ルックアップを頂点位置の変形に使用することもできます)。

連続性の問題なしに球にマッピングするには、2 つの 2D 円の座標を関数に供給して、4D ノイズを含むループ可能な 2D 画像を生成することができます。

それをアニメーション化することに関しては、フラグメントパイプラインで時間セマンティックを使用してルックアップ結果を変形するか、「ノイズでアニメーション化された」ノイズが本当に必要な場合に備えて画像シーケンスをベイクすることにより、さまざまなハックなトリックがあります。

3D テクスチャは 2D テクスチャのスタックにすぎないため、やりたいことを操作するには (アニメーションがなくても) 重すぎます。

于 2015-06-13T11:19:53.570 に答える