2014-06-11 17 views
5

मेरी हाल की परियोजना में मैं हार्डवेयर साइड टेस्सेलेशन के साथ काम कर रहा हूं। जिस पाइपलाइन को मैं कार्यान्वित करना चाहता हूं उसे कम पॉली जाल लेना चाहिए, इसे छेड़छाड़ करना चाहिए और विस्थापन मानचित्र लागू करना चाहिए।जीएलएसएल टेस्सेलेशन विस्थापन मैपिंग

टेस्सेलेशन ठीक काम करता है और जैसा कि मैंने उम्मीद की थी। हालांकि, जब मैं टेस्सेलेशन मूल्यांकन शेडर में विस्थापन मानचित्र लागू करता हूं तो मुझे एक आउटपुट मिलता है जो कुछ हद तक यादृच्छिक होता है।

इस विस्थापन के बिना उत्पादन

enter image description here

यह जब मैं (मेरे विस्थापन सक्षम एक ही बनावट का उपयोग कर मैं क्या मिलता है (इस बात की पुष्टि करने के लिए कि मेरी texCoords सटीक हैं एक बनावट के रूप में heightmap थे) दोनों रंग और विस्थापन) के लिए:

enter image description here

शेडर कोड इस प्रकार है:

// शिखर shader

#version 430 

layout(location = 0) in vec4 vertex; 
layout(location = 1) in vec4 normal; 
layout(location = 2) in vec2 texCoord; 

out vec3 vPosition; 
out vec3 vNormal; 
out vec2 vTexCoord; 

void main() { 
    vPosition = vertex.xyz; 
    vNormal = normal.xyz; 
    vTexCoord = texCoord; 
} 

// TESS नियंत्रण

#version 430 

layout(vertices = 3) out; 

in vec3 vPosition[]; 
in vec3 vNormal[]; 
in vec2 vTexCoord[]; 
out vec3 tcPosition[]; 
out vec3 tcNormal[]; 
out vec2 tcTexCoord[]; 

uniform float innerTessLevel; 
uniform float outerTessLevel; 

void main(){ 

    float inTess = innerTessLevel; 
    float outTess = outerTessLevel; 

    tcPosition[gl_InvocationID] = vPosition[gl_InvocationID]; 
    tcNormal[gl_InvocationID] = vNormal[gl_InvocationID]; 
    tcTexCoord[gl_InvocationID] = vTexCoord[gl_InvocationID]; 
    if(gl_InvocationID == 0) { 
     gl_TessLevelInner[0] = inTess; 
     gl_TessLevelInner[1] = inTess; 
     gl_TessLevelOuter[0] = outTess; 
     gl_TessLevelOuter[1] = outTess; 
     gl_TessLevelOuter[2] = outTess; 
     gl_TessLevelOuter[3] = outTess; 
    } 
} 

// TESS EVAL

#version 430 

layout(triangles, equal_spacing, ccw) in; 

in vec3 tcPosition[]; 
in vec3 tcNormal[]; 
in vec2 tcTexCoord[]; 
out vec3 tePosition; 
out vec2 teTexCoord; 

uniform mat4 ModelViewProjection; 
uniform mat4 ModelView; 

uniform sampler2D texHeight; 

void main(){ 
    vec3 p0 = gl_TessCoord.x * tcPosition[0]; 
    vec3 p1 = gl_TessCoord.y * tcPosition[1]; 
    vec3 p2 = gl_TessCoord.z * tcPosition[2]; 
    vec3 pos = p0 + p1 + p2; 

    vec3 n0 = gl_TessCoord.x * tcNormal[0]; 
    vec3 n1 = gl_TessCoord.y * tcNormal[1]; 
    vec3 n2 = gl_TessCoord.z * tcNormal[2]; 
    vec3 normal = normalize(n0 + n1 + n2); 

    vec2 tc0 = gl_TessCoord.x * tcTexCoord[0]; 
    vec2 tc1 = gl_TessCoord.y * tcTexCoord[1]; 
    vec2 tc2 = gl_TessCoord.z * tcTexCoord[2]; 
    teTexCoord = tc0 + tc1 + tc2; 

    float height = texture(texHeight, teTexCoord).x; 
    pos += normal * (height * 0.2f); 

    gl_Position = ModelViewProjection * vec4(pos, 1); 
    tePosition = vec3(ModelView * vec4(pos,1.0)).xyz; 
} 

// ज्यामिति

#version 430 

layout(triangles) in; 
layout(triangle_strip, max_vertices = 3) out; 

uniform mat4 ModelView; 

in vec3 tePosition[3]; 
in vec3 tePatchDistance[3]; 
in vec2 teTexCoord[3]; 
out vec3 gFacetNormal; 
out vec2 gTexCoord; 

void main() { 
    vec3 A = tePosition[2] - tePosition[0]; 
    vec3 B = tePosition[1] - tePosition[0]; 
    vec4 N = vec4(normalize(cross(A, B)) , 0.0); 
    gFacetNormal = N.xyz; 

    gTexCoord = teTexCoord[0]; 
    gl_Position = gl_in[0].gl_Position; EmitVertex(); 

    gTexCoord = teTexCoord[1]; 
    gl_Position = gl_in[1].gl_Position; EmitVertex(); 

    gTexCoord = teTexCoord[2]; 
    gl_Position = gl_in[2].gl_Position; EmitVertex(); 

    EndPrimitive(); 
} 

// FRAGMENT

#version 430 

layout(location = 0) out vec4 fragColor; 

in vec3 gFacetNormal; 
in vec2 gTexCoord; 

uniform float lit; 
uniform vec3 light; 
uniform sampler2D texHeight; 

void main() { 
    #ifndef ORANGE_PURPLE 
     vec3 color = gl_FrontFacing ? vec3(1.0,0.0,0.0) : vec3(0.0,0.0,1.0); 
    #else 
     vec3 color = gl_FrontFacing ? vec3(1.0,0.6,0.0) : vec3(0.6,0.0,1.0); 
    #endif 
    if (lit > 0.5) { 
     color = texture(texHeight, gTexCoord).xyz; 
     vec3 N = normalize(gFacetNormal); 
     vec3 L = light; 
     float df = abs(dot(N,L)); 
     color = df * color; 

     fragColor = vec4(color,1.0); 
    } 
    else { 
     fragColor = vec4(color,1.0); 
    } 
} 

यह अच्छा होगा अगर कोई उस पर मेरी सहायता कर सके।

+0

विस्थापन हमेशा सतह एक unorm बनावट को देखते हुए (अभी आप जहां विस्थापन स्थानांतरित करने के लिए प्रकट होता है कुछ क्षेत्रों है से बाहर की ओर का सामना करना पड़ नहीं होना चाहिए *** सिलेंडर *** के अंदर शिखर)? मुझे दृढ़ता से संदेह है कि टीईएस में आपकी सामान्य गणना के साथ कुछ गड़बड़ है। शायद आप सामान्य रूप से टीईएस में ज्यामिति/खंड के माध्यम से गणना कर सकते हैं और यह देखने के लिए कल्पना कर सकते हैं कि यह सही दिखता है या नहीं? –

+1

वास्तव में: आउटपुट 'gFacetNormal' केवल ज्यामिति शेडर में आपके पहले चरम के लिए परिभाषित किया गया है। जीएलएसएल विनिर्देश के अनुसार प्रत्येक 'एमिटवटेक्स (...) 'के बाद आउटपुट सेट किए जाने चाहिए, या वे अनिर्धारित होंगे। कई कार्यान्वयन अंतिम मूल्य सेट का पुन: उपयोग करते हैं, लेकिन यदि आप इसे पोर्टेबल रूप से काम करना चाहते हैं तो आप उस व्यवहार पर भरोसा नहीं कर सकते हैं। आपको प्रत्येक 'EmitVertex' से पहले एक बार' gFacetNormal' सेट करने की आवश्यकता है। * शून्य emitVertex() '-" आउटपुट चर के वर्तमान मानों को वर्तमान आउटपुट आदिम में उत्सर्जित करता है। इस कॉल से वापस आने पर, आउटपुट चर के मान अपरिभाषित होते हैं। "* –

+0

सलाह के लिए धन्यवाद !!! मैंने सोचा नहीं होगा कि यह चाल करेगा, लेकिन वास्तव में यह वास्तव में 'gfacetNormal' था जो सबकुछ दबा देता था। मैं नियमित रूप से लागू करने में रुचि रखने वाले सभी के लिए कोड संपादित करूंगा। –

उत्तर

2

@ AndonM.Coleman के लिए धन्यवाद मैं बात

हल वास्तव में: उत्पादन gFacetNormal केवल ज्यामिति शेडर में अपना पहला शिखर के लिए परिभाषित किया गया है। जीएलएसएल विनिर्देश के अनुसार प्रत्येक एमिटवटेक्स (...) के बाद आउटपुट सेट किए जाने चाहिए, या वे अनिर्धारित होंगे। कई कार्यान्वयन अंतिम मूल्य सेट का पुन: उपयोग करते हैं, लेकिन यदि आप इसे पोर्टेबल रूप से काम करना चाहते हैं तो आप उस व्यवहार पर भरोसा नहीं कर सकते हैं। आपको प्रत्येक EmitVertex से पहले एक बार gFacetNormal सेट करने की आवश्यकता है। शून्य EmitVertex() - "वर्तमान आउटपुट आदिम के आउटपुट चर के वर्तमान मानों को उत्सर्जित करता है। इस कॉल से वापस आने पर, आउटपुट चर के मान अपरिभाषित होते हैं।"

मुझे बेवकूफ है कि सूचना के लिए नहीं है, लेकिन यहां काम कर कोड है:

// VERTEX

#version 430 

layout(location = 0) in vec4 vertex; 
layout(location = 1) in vec4 normal; 
layout(location = 2) in vec2 texCoord; 

out vec3 vPosition; 
out vec3 vNormal; 
out vec2 vTexCoord; 

void main() { 
    vPosition = vertex.xyz; 
    vNormal = normal.xyz; 
    vTexCoord = texCoord; 
} 

// चौकोर नियंत्रण

#version 430 

layout(vertices = 3) out; 

in vec3 vPosition[]; 
in vec3 vNormal[]; 
in vec2 vTexCoord[]; 
out vec3 tcPosition[]; 
out vec3 tcNormal[]; 
out vec2 tcTexCoord[]; 

uniform float innerTessLevel; 
uniform float outerTessLevel; 

void main(){ 

    float inTess = innerTessLevel; 
    float outTess = outerTessLevel; 

    tcPosition[gl_InvocationID] = vPosition[gl_InvocationID]; 
    tcNormal[gl_InvocationID] = vNormal[gl_InvocationID]; 
    tcTexCoord[gl_InvocationID] = vTexCoord[gl_InvocationID]; 
    if(gl_InvocationID == 0) { 
     gl_TessLevelInner[0] = inTess; 
     gl_TessLevelInner[1] = inTess; 
     gl_TessLevelOuter[0] = outTess; 
     gl_TessLevelOuter[1] = outTess; 
     gl_TessLevelOuter[2] = outTess; 
     gl_TessLevelOuter[3] = outTess; 
    } 
} 

// चौकोर मूल्यांकन

#version 430 

layout(triangles, equal_spacing, ccw) in; 

in vec3 tcPosition[]; 
in vec3 tcNormal[]; 
in vec2 tcTexCoord[]; 
out vec3 tePosition; 
out vec2 teTexCoord; 
out vec3 teNormal; 

uniform mat4 ModelViewProjection; 
uniform mat4 ModelView; 

uniform sampler2D texHeight; 

void main(){ 
    vec3 p0 = gl_TessCoord.x * tcPosition[0]; 
    vec3 p1 = gl_TessCoord.y * tcPosition[1]; 
    vec3 p2 = gl_TessCoord.z * tcPosition[2]; 
    vec3 pos = p0 + p1 + p2; 

    vec3 n0 = gl_TessCoord.x * tcNormal[0]; 
    vec3 n1 = gl_TessCoord.y * tcNormal[1]; 
    vec3 n2 = gl_TessCoord.z * tcNormal[2]; 
    vec3 normal = normalize(n0 + n1 + n2); 

    vec2 tc0 = gl_TessCoord.x * tcTexCoord[0]; 
    vec2 tc1 = gl_TessCoord.y * tcTexCoord[1]; 
    vec2 tc2 = gl_TessCoord.z * tcTexCoord[2]; 
    teTexCoord = tc0 + tc1 + tc2; 

    float height = texture(texHeight, teTexCoord).x; 
    pos += normal * (height * 0.5f); 

    gl_Position = ModelViewProjection * vec4(pos, 1); 
    teNormal = vec3(ModelView * vec4(normal,0.0)).xyz; 
    tePosition = vec3(ModelView * vec4(pos,1.0)).xyz; 
} 

// ज्यामिति

#version 430 

layout(triangles) in; 
layout(triangle_strip, max_vertices = 3) out; 

uniform mat4 ModelView; 

in vec3 tePosition[3]; 
in vec2 teTexCoord[3]; 
in vec3 teNormal[3]; 
out vec3 gFacetNormal; 
out vec2 gTexCoord; 

void main() { 

    gFacetNormal = teNormal[0]; 
    gTexCoord = teTexCoord[0]; 
    gl_Position = gl_in[0].gl_Position; EmitVertex(); 

    gFacetNormal = teNormal[1]; 
    gTexCoord = teTexCoord[1]; 
    gl_Position = gl_in[1].gl_Position; EmitVertex(); 

    gFacetNormal = teNormal[2]; 
    gTexCoord = teTexCoord[2]; 
    gl_Position = gl_in[2].gl_Position; EmitVertex(); 

    EndPrimitive(); 
} 

// FRAGMENT

#version 430 

layout(location = 0) out vec4 fragColor; 

in vec3 gFacetNormal; 
in vec2 gTexCoord; 

uniform float lit; 
uniform vec3 light; 
uniform sampler2D texHeight; 

void main() { 
    #ifndef ORANGE_PURPLE 
    vec3 color = gl_FrontFacing ? vec3(1.0,0.0,0.0) : vec3(0.0,0.0,1.0); 
    #else 
     vec3 color = gl_FrontFacing ? vec3(1.0,0.6,0.0) : vec3(0.6,0.0,1.0); 
    #endif 
    if (lit > 0.5) { 
     color = texture(texHeight, gTexCoord).xyz; 
     vec3 N = normalize(gFacetNormal); 
     vec3 L = light; 
     float df = abs(dot(N,L)); 
     color = df * color; 
     fragColor = vec4(color,1.0); 
    } 
    else { 
     fragColor = vec4(color,1.0); 
    } 
} 
+0

ईमानदार होने के लिए, मैं थोड़ी उलझन में हूं। क्या यह *** *** *** चीज है जिसे आपने बदल दिया है? ज्यामिति शेडर * टेसेलेशन के बाद * चलाता है, इसलिए वास्तव में अजीब विस्थापन को जीएस में संशोधन करके हल नहीं किया जाना चाहिए। यद्यपि यह हल हो सकता है हालांकि प्रकाश के साथ समस्याएं हैं। –

+1

ठीक है जैसे मैंने आपकी सलाह पर टिप्पणी की, मैं भी बहुत उलझन में था। लेकिन शेडर कोड एकमात्र चीज है जिसे मैंने संपादित किया है। इन परिवर्तनों के बारे में मैंने केवल प्रति चरम आउटपुट को संशोधित किया है और चूंकि मैं सभी चरणों के माध्यम से मानदंडों को पार कर रहा हूं, फिर भी मैंने ज्यामिति शेडर में मानदंडों की गणना हटा दी है। –

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