2011-09-30 13 views
11

मैंने एचएलएसएल में स्टैक ओवरफ्लो थ्रेड How to implement this rotating spiral in WebGL? में वर्णित सर्पिल जीएलएसएल शेडर को लागू किया है लेकिन परिणाम समान नहीं हैं और मुझे लगता है कि यह जीएलएसएल में मॉड फ़ंक्शन की वजह से है जिसे मैंने एफएमओडी में अनुवादित किया है एचएलएसएल में मैंने जीएसएलएस दस्तावेज (http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml) में वर्णित एक फ़ंक्शन में कस्टम कॉल द्वारा कॉल को प्रतिस्थापित करने का प्रयास किया है और यह काम करता है:ग्लस्ल मॉड बनाम एचएलएसएल एफएमओडी

mod x modulo y का मान देता है । यह एक्स - वाई * मंजिल (एक्स/वाई) के रूप में गणना की जाती है।

fmod समारोह MSDN प्रलेखन http://msdn.microsoft.com/en-us/library/windows/desktop/bb509601(v=vs.85).aspx के अनुसार, कहते हैं निम्नलिखित:

फ्लोटिंग प्वाइंट शेष ऐसी गणना की जाती है कि एक्स = मैं * y + च, जहां मैं एक पूर्णांक है, च एक ही संकेत के रूप में है एक्स, और एफ का पूर्ण मूल्य वाई के पूर्ण मूल्य से कम है।

मैंने एचएलएसएल का उपयोग http://sourceforge.net/projects/hlsl2glsl में होस्ट किए गए जीएलएसएल कनवर्टर में किया है और एफएमओडी फ़ंक्शन को मॉड के रूप में अनुवादित किया गया है, हालांकि मुझे नहीं पता कि मैं मान सकता हूं कि यह मोड एफएमओडी में अनुवाद करता है या नहीं।

मेरा प्रश्न यह है कि, दो कार्यों के बीच अंतर क्या है और मैं एक छद्म कोड कार्यान्वयन के लिए 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 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(); 
    } 
} 

मैंने एफएमओडी के बजाए कोई समस्या नहीं है, मैं निम्नलिखित फ़ंक्शन (जीएलएसएल मोड की प्रति परिभाषा) को कॉल करता हूं

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

मुझे लगता है कि आप एचएलएसएल में मोड के लिए% का उपयोग कर सकते हैं। – Robinson

+0

हाँ मैंने कोशिश की लेकिन% बिल्कुल वही समस्या देता है। सर्पिल सही ढंग से प्रतिनिधित्व नहीं किया जाता है। इसमें से 1/4 काट दिया गया है –

+0

दोनों शेडर्स को देखना उपयोगी होगा ताकि हम उनकी तुलना कर सकें। – kvark

उत्तर

13

जैसा कि आपने देखा है, वे अलग हैं। जीएलएसएल मोड हमेशा एक्स के बजाए वाई के समान संकेत होगा। अन्यथा यह वही है - एक मान एफ जैसे x = i * y + f जहां मैं एक पूर्णांक और | f | है < | वाई | यदि आप किसी प्रकार का दोहराव पैटर्न बनाने की कोशिश कर रहे हैं, तो जीएलएसएल मोड आम तौर पर आप चाहते हैं।

तुलना के लिए, एचएलएसएल एफएमओडी एक्स - वाई * ट्रंक (एक्स/वाई) के बराबर है। वे वही होते हैं जब एक्स/वाई सकारात्मक होता है, जब एक्स/वाई नकारात्मक होता है तो अलग होता है।

+0

प्रदान करने जा रहा हूं धन्यवाद यह बिल्कुल ठीक था। धन्यवाद –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^