Glsl mod срещу Hlsl fmod

Внедрих спиралния GLSL шейдър, описан в този въпрос в HLSL, но резултатите не са същите. Мисля, че е заради функцията mod в GLSL, която преведох на fmod в HLSL. Подозирам, че този проблем се случва само когато имаме отрицателни числа във входа на функцията fmod.

Опитах се да заменя извикването на mod с извикване на функция, която направих и която прави това, което е описано в GLSL документация и работи:

mod връща стойността на x по модул y. Това се изчислява като x - y * floor(x/y).

Работният код, който използвам вместо fmod е:

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

За разлика от GLSL mod, MSDN казва функцията HLSL fmod прави това:

Остатъкът с плаваща запетая се изчислява така, че x = i * y + f, където i е цяло число, f има същия знак като x, а абсолютната стойност на f е по-малка от абсолютната стойност на y.

Използвал съм конвертор от HLSL към GLSL и функцията fmod се превежда като mod. Не знам обаче дали мога да приема, че mod се превежда на fmod.

Въпроси

  1. Какви са разликите между GLSL mod и HLSLfmod?
  2. Как мога да преведа загадъчното описание на 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();
    }
}

person Ivo Leitão    schedule 30.09.2011    source източник
comment
Мисля, че можете да използвате % за мод в HLSL.   -  person Robinson    schedule 30.09.2011
comment
да, опитах, но % дава абсолютно същия проблем. Спиралата не е представена правилно. 1/4 от него се нарязва   -  person Ivo Leitão    schedule 30.09.2011
comment
Би било полезно да видим и двата шейдъра, за да можем да ги сравним.   -  person kvark    schedule 30.09.2011
comment
Окей прав си. Ще ги осигуря   -  person Ivo Leitão    schedule 30.09.2011


Отговори (1)


Както забелязахте, те са различни. GLSL mod винаги ще има същия знак като y, а не x. В противен случай е същото -- стойност f такава, че x = i*y + f където i е цяло число и |f| < |y|. Ако се опитвате да направите някакъв повтарящ се модел, GLSL mod обикновено е това, което искате.

За сравнение, HLSL fmod е еквивалентен на x - y * trunc(x/y). Те са еднакви, когато x/y е положително, различни, когато x/y е отрицателно.

person Chris Dodd    schedule 30.09.2011