[osg-users] Reflection cube map with shader

207 views
Skip to first unread message

Andrea Martini

unread,
Mar 27, 2013, 10:40:36 AM3/27/13
to osg-...@lists.openscenegraph.org
Hi,
i'm trying to apply a reflection effect on a sphere, using a cube map.
I'm using as vertex shader dthe following :



Code:

#version 400 compatibility
// Orange Book Opengl Shading Language, 2 edition pag. 257

varying vec3 ReflectDir;
varying float LightIntensity;
uniform vec3 LightPos;

void main()
{
gl_Position = ftransform();
vec3 normal = normalize(gl_NormalMatrix * gl_Normal);
vec4 pos = gl_ModelViewMatrix * gl_Vertex;
vec3 eyeDir = pos.xyz;
ReflectDir = reflect(eyeDir, normal);
LightIntensity = max(dot(normalize(LightPos - eyeDir), normal),0.0);
}




and the following fragment:



Code:

#version 400 compatibility
// Orange Book Opengl Shading Language, 2 edition pag. 257

uniform vec3 BaseColor;
uniform float MixRatio;

uniform samplerCube EnvMap;

varying vec3 ReflectDir;
varying float LightIntensity;

void main()
{
// Look up environment map value in cube map

vec3 envColor = vec3(textureCube(EnvMap, ReflectDir));

// Add lighting to base color and mix

vec3 base = LightIntensity * BaseColor;
envColor = mix(envColor, base, MixRatio);

gl_FragColor = vec4(envColor, 1.0);
}




To pass the samplerCube, i use the following osg code :


Code:


osg::Shader* vertexShader = osgDB::readShaderFile(osg::Shader::VERTEX, "\\shaders\\\shaders\\ReflectionCubeMaps\\ReflectionCubeMaps4.vert");
osg::Program* program=new osg::Program();
if (!vertexShader)
{
std::cout << " No vertex Shader Loaded." << std::endl;
return;
}
osg::Shader* fragShader = osgDB::readShaderFile(osg::Shader::FRAGMENT, "\\shaders\\\shaders\\ReflectionCubeMaps\\ReflectionCubeMaps4.frag");
if (!fragShader)
{
std::cout << " No fragment Shader Loaded." << std::endl;
return;
}
program->addShader(vertexShader);
program->addShader(fragShader);
osg::StateSet* stateset=myModel->getOrCreateStateSet(); // My model is the SPHERE


osg::ref_ptr<osg::TextureCubeMap> cubemap = new osg::TextureCubeMap;

/**/

osg::Image* imagePosX = osgDB::readImageFile("\\Cubemap_snow\\posx.jpg");
osg::Image* imageNegX = osgDB::readImageFile("\\Cubemap_snow\\negx.jpg");
osg::Image* imagePosY = osgDB::readImageFile("\\Cubemap_snow\\posy.jpg");
osg::Image* imageNegY = osgDB::readImageFile("\\Cubemap_snow\\negy.jpg");
osg::Image* imagePosZ = osgDB::readImageFile("\\Cubemap_snow\\posz.jpg");
osg::Image* imageNegZ = osgDB::readImageFile("\\Cubemap_snow\\negz.jpg");

if (imagePosX && imageNegX && imagePosY && imageNegY && imagePosZ && imageNegZ)
{
cubemap->setImage(osg::TextureCubeMap::POSITIVE_X, imagePosX);
cubemap->setImage(osg::TextureCubeMap::NEGATIVE_X, imageNegX);
cubemap->setImage(osg::TextureCubeMap::POSITIVE_Y, imagePosY);
cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Y, imageNegY);
cubemap->setImage(osg::TextureCubeMap::POSITIVE_Z, imagePosZ);
cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Z, imageNegZ);

cubemap->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
cubemap->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
cubemap->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_EDGE);

cubemap->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
cubemap->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);

cubemap->setResizeNonPowerOfTwoHint( false );
}

stateset->setAttributeAndModes( program, osg::StateAttribute::ON );
stateset->setTextureAttributeAndModes( unit, cubemap.get() );

osg::Uniform* environment = new osg::Uniform(osg::Uniform::SAMPLER_CUBE, "EnvMap");
environment->set(cubemap.get());
stateset->addUniform( environment );
stateset->addUniform(new osg::Uniform("LightPos",osg::Vec3(0.0, 0.0, 4.0)));
stateset->addUniform(new osg::Uniform("BaseColor",osg::Vec3(0.8, 0.2, 1.0)));
stateset->addUniform(new osg::Uniform("MixRatio",0.8f));





What i get, is the cubemap and a violet sphere : the sphere doesn't reflect the environment.

In the file attached, i report a snapshot of the result.

Please, could you suggest me where i can find the error?

Thank you!

Cheers,
Andrea

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=53341#53341



ReflectionMapOnSphere.jpg

Sergey Polischuk

unread,
Mar 27, 2013, 12:07:33 PM3/27/13
to osg-...@lists.openscenegraph.org
Hi

>>>> environment->set(cubemap.get());

should be

>>>> environment->set(int(unit));

Cheers

27.03.2013, 18:45, "Andrea Martini" <martini...@gmail.com>:

> ,
> _______________________________________________
> osg-users mailing list
> osg-...@lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Andrea Martini

unread,
Mar 27, 2013, 12:22:31 PM3/27/13
to osg-...@lists.openscenegraph.org
Hi hybr(),
thank you. Now it works!

I have to change something to update the reflected image on camera moving ... i have to check.


Thank you again.

Cheers,
Andrea

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=53349#53349

Sergey Polischuk

unread,
Mar 27, 2013, 12:36:30 PM3/27/13
to osg-...@lists.openscenegraph.org
in vertex shader add line

ReflectDir = (osg_ViewMatrixInverse * vec4(ReflectDir,0)).xyz;

after

ReflectDir = reflect(eyeDir, normal);


27.03.2013, 20:27, "Andrea Martini" <martini...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages