2017-07-02 39 views
1

目前我有處理GLSL着色器制服的問題。如果我在場景中只有一個物體,制服就如我所料。但是,對於多個對象,均勻性不是針對每個對象設置的,換句話說,最後一個均勻度用於表示所有場景對象。GLSL爲每個對象統一

我該如何處理這個問題?如下我的C++代碼:

void addSimpleObject(osg::ref_ptr<osg::Group> root, osg::Vec3 position, float radius, float myUniform) { 

    osg::ref_ptr<osg::Geode> geode = new osg::Geode(); 
    geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(position, radius))); 
    root->addChild(geode); 
    root->getChild(0)->asGeode()->addDrawable(geode->getDrawable(0)); 

    osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet(); 
    stateset->addUniform(new osg::Uniform("myUniform", myUniform)); 
    root->setStateSet(stateset); 
} 


osg::ref_ptr<osg::Group> root = new osg::Group(); 
addSimpleObject(root, osg::Vec3(-3.0, 2.5, -10), 2, 0.5); 
addSimpleObject(root, osg::Vec3(3.0, 2.5, -10), 2, 1.5); 
addSimpleObject(root, osg::Vec3(0.0, -2.5, -10), 2, 1.0); 

頂點着色器:

#version 130 

out vec3 pos; 
out vec3 normal; 

void main() { 
    pos = (gl_ModelViewMatrix * gl_Vertex).xyz; 
    normal = gl_NormalMatrix * gl_Normal; 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
} 

和片段着色器:

#version 130 

in vec3 pos; 
in vec3 normal; 

uniform float myUniform; 

void main() { 
    vec3 normNormal; 

    normNormal = normalize(normal); 

    if (myUniform > 0) 
     normNormal = min(normNormal * myUniform, 1.0); 

    ... 
} 

image output

+1

一個統一綁定到一個着色器程序不是一個「對象」。如果對所有對象使用相同的程序,yoa必須在繪製對象之前設置制服。 – Rabbid76

+0

Hi @ Rabbid76,謝謝你的回答。你能舉個例子嗎?我如何解決我的計劃以解決您的建議? –

回答

2

均勻結合到着色器程序不一個東西」。 如果對所有對象使用相同的程序,則必須在繪製對象之前設置制服。

您將osg::StateSet綁定到場景圖的根節點。 如果統一變量的值爲每個drawable更改,則必須將 分隔osg::StateSet添加到每個osg::Drawable節點。

適應你的方法addSimpleObject這樣的:

void addSimpleObject(osg::ref_ptr<osg::Group> root, osg::Vec3 position, float radius, float myUniform) { 

    // create the drawable 
    osg::ref_ptr<osg::Drawable> drawable = new osg::ShapeDrawable(new osg::Sphere(position, radius)) 

    // crate the stateset and add the uniform 
    osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet(); 
    stateset->addUniform(new osg::Uniform("myUniform", myUniform)); 

    // add the stateset tor the drawable 
    drawable->setStateSet(stateset); 

    if (root->getNumChildren() == 0) { 
     osg::ref_ptr<osg::Geode> geode = new osg::Geode(); 
     root->addChild(geode); 
    } 
    root->getChild(0)->asGeode()->addDrawable(drawable); 
} 
+0

Hi @ Rabbid76,我測試了你的解決方案,它工作正常!非常感謝! –