2011-09-30 11 views
11

Tôi đã triển khai trình đổ bóng GLSL xoắn ốc được mô tả trong luồng stackoverflow How to implement this rotating spiral in WebGL? trong HLSL nhưng kết quả không giống nhau và tôi nghĩ đó là do hàm mod trong GLSL mà tôi đã dịch sang fmod trong HLSL. Tôi đã cố gắng thay thế cuộc gọi thành mod bằng một cuộc gọi tùy chỉnh thành chức năng mà tôi đã thực hiện để thực hiện những gì được mô tả trong tài liệu GSLS (http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml) và hoạt động:Glsl mod vs Hlsl fmod

mod trả về giá trị của x modulo y . Điều này được tính là x - y * sàn (x/y).

Chức năng fmod theo MSDN tài liệu http://msdn.microsoft.com/en-us/library/windows/desktop/bb509601(v=vs.85).aspx, nói như sau:

Các dấu chấm động còn lại được tính toán như vậy x = i * y + f, trong đó i là một số nguyên, e có dấu hiệu tương tự như x, và giá trị tuyệt đối của f nhỏ hơn giá trị tuyệt đối của y.

Tôi đã sử dụng bộ chuyển đổi HLSL sang GLSL được lưu trữ trong http://sourceforge.net/projects/hlsl2glsl và chức năng fmod được dịch là mod, tuy nhiên tôi không biết liệu tôi có thể giả định rằng mod dịch sang fmod hay không.

Câu hỏi của tôi là, sự khác nhau giữa hai hàm là gì và làm cách nào để dịch mô tả cryptic msm của fmod sang triển khai mã giả.

tôi nghi ngờ rằng vấn đề này chỉ xảy ra khi chúng ta có số âm trong đầu vào của hàm fmod

GLSL Shader:

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 Shader:

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(); 
    } 
} 

Tôi đã không có vấn đề gì nếu thay vì fmod tôi gọi hàm sau (theo định nghĩa của mod GLSL)

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

Tôi nghĩ bạn có thể sử dụng% cho mod trong HLSL. – Robinson

+0

vâng tôi đã thử nhưng% cho chính xác cùng một vấn đề. Đường xoắn ốc không được biểu diễn chính xác. 1/4 của nó được cắt –

+0

Nó sẽ rất hữu ích để xem cả hai shaders để chúng ta có thể so sánh chúng. – kvark

Trả lời

13

Như bạn đã lưu ý, chúng khác nhau. Mod GLSL sẽ luôn có cùng dấu như y chứ không phải x. Nếu không thì nó giống nhau - một giá trị f sao cho x = i * y + f trong đó i là một số nguyên và | f | < | y |. Nếu bạn đang cố gắng tạo ra một mẫu lặp lại của một số loại, mod GLSL thường là thứ bạn muốn.

Để so sánh, fmod HLSL tương đương với x - y * trunc (x/y). Chúng giống nhau khi x/y là dương, khác nhau khi x/y là âm.

+0

Cảm ơn chính xác điều đó. Cảm ơn bạn –