2011-09-30 22 views
11

HLSLのstackoverflowスレッドHow to implement this rotating spiral in WebGL?に記載されているスパイラルGLSLシェーダを実装しましたが、結果は同じではありません.FModに変換したGLSLのmod関数のためだと思いますHLSLで私はmodへの呼び出しを、GSLSドキュメント(http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml)に記述されていることを行う関数へのカスタム呼び出しで置き換えようとしました。それは動作します:Glsl mod vs Hlsl fmod

modはxの値を返しますy 。これはx - y * floor(x/y)として計算されます。

FMOD機能MSDNのドキュメントhttp://msdn.microsoft.com/en-us/library/windows/desktop/bb509601(v=vs.85).aspxによれば、次の言葉:

浮動小数点剰余をx = iは整数であるY + Fを、*、fは同じ符号を有するように計算されます。 xの絶対値よりも小さく、fの絶対値はyの絶対値よりも小さい。

http://sourceforge.net/projects/hlsl2glslでホストされているHLSLからGLSLへのコンバータを使用しましたが、fmod関数がmodとして変換されていますが、modがfmodに変換されると仮定できるかどうかはわかりません。

私の質問は、2つの機能の違いは何ですか?また、fmodのmsdnの暗黙の記述を擬似コードの実装にどのように変換できますか。

は、私たちはFMOD関数の入力

GLSLシェーダに負の数を持っている場合、この問題が発生したことを疑う:

uniform float time; 
uniform vec2 resolution; 
uniform vec2 aspect; 

void main(void) { 
    vec2 position = -aspect.xy + 2.0 * gl_FragCoord.xy/resolution.xy * aspect.xy; 
    float angle = 0.0 ; 
    float radius = length(position) ; 
    if (position.x != 0.0 && position.y != 0.0){ 
    angle = degrees(atan(position.y,position.x)) ; 
    } 
    float amod = mod(angle+30.0*time-120.0*log(radius), 30.0) ; 
    if (amod<15.0){ 
    gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); 
    } else{ 
    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);      
    } 
} 

HLSLシェーダ:私はしました

struct Psl_VertexShaderInput 
{ 
    float3 pos : POSITION; 
}; 

struct Psl_VertexShaderOutput 
{ 
    float4 pos : POSITION; 

}; 

struct Psl_PixelShaderOutput 
{ 
    float4 Output0 : COLOR0; 
}; 

float3 psl_positionOffset; 
float2 psl_dimension; 

Psl_VertexShaderOutput Psl_VertexShaderFunction(Psl_VertexShaderInput psl_input) 
{ 
    Psl_VertexShaderOutput psl_output = (Psl_VertexShaderOutput)0; 

    psl_output.pos = float4(psl_input.pos + psl_positionOffset, 1); 


    return psl_output; 
} 

float time : TIME; 
float2 resolution : DIMENSION; 


Psl_PixelShaderOutput Psl_PixelShaderFunction(float2 pos : VPOS) 
{ 
    Psl_PixelShaderOutput psl_output = (Psl_PixelShaderOutput)0; 

    float2 aspect = float2(resolution.x/resolution.y, 1.0); 
    float2 position = -aspect.xy + 2.0 * pos.xy/resolution.xy * aspect.xy; 
    float angle = 0.0; 
    float radius = length(position); 
    if (position.x != 0.0 && position.y != 0.0) 
    { 
     angle = degrees(atan2(position.y, position.x)); 
    } 
    float amod = fmod((angle + 30.0 * time - 120.0 * log(radius)), 30.0); 
    if (amod < 15.0) 
    { 
     psl_output.Output0 = float4(0.0, 0.0, 0.0, 1.0); 
     return psl_output; 
    } 

    else 
    { 
     psl_output.Output0 = float4(1.0, 1.0, 1.0, 1.0); 
     return psl_output; 
    } 

} 

technique Default 
{ 
    pass P0 
    { 
     VertexShader = compile vs_3_0 Psl_VertexShaderFunction(); 
     PixelShader = compile ps_3_0 Psl_PixelShaderFunction(); 
    } 
} 

fmodの代わりに次の関数を呼び出すと問題はありません(GLSL modの定義ごと)

float mod(float x, float y) 
{ 
    return x - y * floor(x/y) 
} 
+0

私はHLSLでmodに%を使うことができると思います。 – Robinson

+0

はい私は試みましたが、%は全く同じ問題をもたらします。らせんは正しく表現されていません。 1/4がカットされます –

+0

両方のシェーダーを見て比較できるようにすると便利です。 – kvark

答えて

13

あなたが指摘したように、それらは異なっています。 GLSLのmodは常にxではなくyと同じ符号を持ちます。そうでなければ、同じこと - x = i * y + fのような値fここで、iは整数であり、| f | < | y |。あなたが何らかの種類の繰り返しパターンを作ろうとしているのであれば、GLSL modは一般的にあなたが望むものです。

比較のため、HLSLのfmodはx - y * trunc(x/y)と等価です。 x/yが正の場合は同じですが、x/yが負の場合は異なります。

+0

それは正確にありがとう。ありがとうございました –