It is problematic to make dynamic reflect\refract rendering with a single node, 
because you need rtt cameras with scene surronding your object.
If you add cameras into object with reflections itself, you need surronding 
scene in separate graph (to avoid creating cycled graph).
If you have multiple objects with reflections\refractions in scene and they 
need to reflect\refract each other it's easier to keep one graph, but to place 
cameras on top of scene which means you should put rtt cameras somewhere 
outside of your nodes with reflections.

02.09.2011, 18:29, "Christian Buchner" <[email protected]>:
>>  Use of glsl in osg is pretty straitforward.
>
> Thanks for the hints so far.
>
> I condensed osgshaders into this short piece of code. It is self
> contained and nearly minimal, apart from
>    -animating the Uniform variable for show effect
>    -shaders doing a little more than the necessary minimum (lighting,
> animation, procedural texture)
>    -relying on osg::Box, osg::ShapeDrawable for geometry (some user
> defined geometry with custom vertex attributes would be nice)
>
> This code sample seems less confusing for GLSL newbies like myself,
> when compared to the full osgshaders demo.
>
> Next I will go shopping in the osgreflect demo, as suggested by Robert 
> Osfield.
>
> The goal would be to implement some reflecting and refracting object
> as a single osg Node, which fits into any scene graph with minimal
> fuss.
>
> ///////////////////////////////////////////////////////////////////////////
> // in-line GLSL source code
>
> static const char *blockyVertSource = {
>     "// blocky.vert - an GLSL vertex shader with animation\n"
>     "uniform float Sine;\n"
>     "const vec3 LightPosition = vec3(0.0, 0.0, 4.0);\n"
>     "const float BlockScale = 0.30;\n"
>     "// varyings are written by vert shader, interpolated, and read by
> frag shader.\n"
>     "varying float LightIntensity;\n"
>     "varying vec2  BlockPosition;\n"
>     "void main(void)\n"
>     "{\n"
>     "    // per-vertex diffuse lighting\n"
>     "    vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;\n"
>     "    vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);\n"
>     "    vec3 lightVec = normalize(LightPosition - vec3 (ecPosition));\n"
>     "    LightIntensity = max(dot(lightVec, tnorm), 0.0);\n"
>     "    // blocks will be determined by fragment's position on the XZ 
> plane.\n"
>     "    BlockPosition = gl_Vertex.xz / BlockScale;\n"
>     "    // scale the geometry based on an animation variable.\n"
>     "    vec4 vertex = gl_Vertex;\n"
>     "    vertex.w = 1.0 + 0.4 * (Sine + 1.0);\n"
>     "    gl_Position = gl_ModelViewProjectionMatrix * vertex;\n"
>     "}\n"
> };
>
> static const char *blockyFragSource = {
>     "// blocky.frag - an GLSL fragment shader with animation\n"
>     "uniform float Sine;\n"
>     "const vec3 Color1 = vec3(1.0, 1.0, 1.0);\n"
>     "const vec3 Color2 = vec3(0.0, 0.0, 0.0);\n"
>     "// varyings are written by vert shader, interpolated, and read by
> frag shader.\n"
>     "varying vec2  BlockPosition;\n"
>     "varying float LightIntensity;\n"
>     "void main(void)\n"
>     "{\n"
>     "    vec3 color;\n"
>     "    float ss, tt, w, h;\n"
>     "    ss = BlockPosition.x;\n"
>     "    tt = BlockPosition.y;\n"
>     "    if (fract(tt * 0.5) > 0.5)\n"
>     "        ss += 0.5;\n"
>     "    ss = fract(ss);\n"
>     "    tt = fract(tt);\n"
>     "    // animate the proportion of block to mortar\n"
>     "    float blockFract = (Sine + 1.1) * 0.4;\n"
>     "    w = step(ss, blockFract);\n"
>     "    h = step(tt, blockFract);\n"
>     "    color = mix(Color2, Color1, w * h) * LightIntensity;\n"
>     "    gl_FragColor = vec4 (color, 1.0);\n"
>     "}\n"
> };
>
> ///////////////////////////////////////////////////////////////////////////
> // callback for animating various Uniforms (currently only the SIN uniform)
>
> class AnimateCallback: public osg::Uniform::Callback
> {
>     public:
>         enum Operation { SIN };
>         AnimateCallback(Operation op) : _operation(op) {}
>         virtual void operator() ( osg::Uniform* uniform, osg::NodeVisitor* nv 
> )
>         {
>             float angle = 2.0 * nv->getFrameStamp()->getSimulationTime();
>             float sine = sinf( angle );            // -1 -> 1
>             switch(_operation) {
>                 case SIN : uniform->set( sine ); break;
>             }
>         }
>     private:
>         Operation _operation;
> };
>
> int main(int, char **)
> {
>     // construct the viewer.
>     osgViewer::Viewer viewer;
>
>     // use a geode with a Box ShapeDrawable
>     osg::Geode* basicModel = new osg::Geode();
>     basicModel->addDrawable(new osg::ShapeDrawable(new
> osg::Box(osg::Vec3(0.0f,0.0f,0.0f),1.0f)));
>
>     // create the "blocky" shader, a simple animation test
>     osg::StateSet *ss = basicModel->getOrCreateStateSet();
>     osg::Program* program = new osg::Program;
>     program->setName( "blocky" );
>     program->addShader( new osg::Shader( osg::Shader::VERTEX,
> blockyVertSource ) );
>     program->addShader( new osg::Shader( osg::Shader::FRAGMENT,
> blockyFragSource ) );
>     ss->setAttributeAndModes(program, osg::StateAttribute::ON);
>
>     // attach some animated Uniform variable to the state set
>     osg::Uniform* SineUniform   = new osg::Uniform( "Sine", 0.0f );
>     ss->addUniform( SineUniform );
>     SineUniform->setUpdateCallback(new AnimateCallback(AnimateCallback::SIN));
>
>     // run the osg::Viewer using our model
>     viewer.setSceneData( basicModel );
>     return viewer.run();
> }
>
> /*EOF*/
> _______________________________________________
> osg-users mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to