OpenSceneGraph Forum Forum Index OpenSceneGraph Forum
Official forum which mirrors the existent OSG mailing lists. Messages posted here are forwarded to the mailing list and vice versa.
 
   FAQFAQ    SearchSearch    MemberlistMemberlist    RulesRules    UsergroupsUsergroups    RegisterRegister 
 Mail2Forum SettingsMail2Forum Settings  ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
   AlbumAlbum  OpenSceneGraph IRC ChatOpenSceneGraph IRC Chat   SmartFeedSmartFeed 

Instanced drawing

Goto page 1, 2  Next
 
Post new topic   Reply to topic    OpenSceneGraph Forum Forum Index -> General [forum]
View previous topic :: View next topic  
Author Message
mateas (Mateusz Janiak)
Newbie


Joined: 20 Jun 2013
Posts: 10
Location: Poland, Mysłowice

PostPosted: Thu Jun 20, 2013 8:49 am    Post subject:
Instanced drawing
Reply with quote

Hi,

I have a large static scene to render - it will not change in time. It can contain even 1M spheres representing atoms in a particular material. I have read a lot about instanced drawing and went through examples:
osgdrawinstanced
osgshaders

but I can not to figure out how can I pass world positions for my sphere prototype instances. I am rather not familiar with plain OpenGL and GLSL, but what I have figured out till now is that I have to follow seweral steps in general:
1. Create my geometry drawable (simple sphere in my case using VBO)
2. Create vertex shader program tha would populate my sphere prototype on GPU side with defined number of instances
3. Attach to vertex shader a buffer? texture? some data representing positions of instances of this particular sphere type in world.
4. Sample buffer, texture with respect to gl_InstanceID to obtain sphere position at VS side

I think I could perform such operation for each sphere type in scene separately as there would be about 5 different spheres (radius). Is this correct approach? Or I should avoid creating several independent programs and try to create one doing all the stuff for different spheres?

I would appriciate if anyone could guide me through process of binding sphere`s world positions to vertext. As mentioned I was trying to attach to my geometry 1D texture filled with positions of sphere instances and read it in shader according to gl_InstanceID for obtaning proper position, hovewer I am doing something wrong and I see just one sphere with strange colors on it. I think my sampling and binding fails but I have no ide how could I investigate the problem and "debug" shader if it is even posiible.

I will just attach fragments of code I think are crucial for this task:
VS code
Code:
#version 330 core
uniform sampler1D tex;
uniform int texSize;
void main(void) {
/* fetch instance position from texture buffer and add the local vertex coordinate to it ? using gl_InstanceID and texSize to properly determine position of my instance coordinates*/
vec4 ObjectSpacePosition = texture(tex, gl_InstanceID / float(texSize)) + vec4(gl_Vertex, 1.0);
ObjectSpacePosition.w = 1.0;

/* transform into view space */
vec4 ViewSpacePosition = gl_ModelViewMatrix * ObjectSpacePosition;

/* transform into clip space */
gl_Position = gl_ProjectionMatrix * ViewSpacePosition;
}


Texture with position coordinates:

Code:
unsigned int instCount = ...;

osg::Image* image = new osg::Image;

// allocate the image data, instCount x 1 x 1 with 4 rgba floats - equivalent to a Vec4!
image->allocateImage(instCount,1,1,GL_RGBA,GL_FLOAT);
image->setInternalTextureFormat(GL_RGBA);

// fill in the image data
osg::Vec4* dataPtr = (osg::Vec4*)image->data();
for( osg::Vec3 pos : InstancePositions )
{
*dataPtr++ = osg::Vec4(pos, 1.0);
}

osg::Texture1D* texture = new osg::Texture1D;
texture->setWrap(osg::Texture1D::WRAP_S,osg::Texture1D::WrapMode::REPEAT);
texture->setFilter(osg::Texture1D::MIN_FILTER,osg::Texture1D::NEAREST);
texture->setImage(image);


And finally state set for geometry:

Code:
osg::ref_ptr< osg::StateSet > s = new osg::StateSet;

// setting proper GL modes
s->setMode(GL_CULL_FACE,osg::StateAttribute::ON);
s->setMode(GL_LIGHTING, osg::StateAttribute::ON);
s->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON);
s->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
s->setMode(GL_BLEND, osg::StateAttribute::OFF);

//create shader
osg::ref_ptr< osg::Shader > nVertexShader = new osg::Shader();
nVertexShader->setType( osg::Shader::VERTEX );
nVertexShader->setShaderSource( ... );

osg::ref_ptr< osg::Program > program = new osg::Program();
program->addShader( nVertexShader.get() );

s->setAttribute( program.get(), osg::StateAttribute::ON | osg::StateAttribute::PROTECTED );

//set texture for node which I want to sample in shader for positions
s->setTextureAttribute(0,texture,osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_1D,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_3D,osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
// size of texture so I can rescale my gl_InstanceID to proper float value in shader for texture sampling
osg::Uniform* texSize = new osg::Uniform("texSize",instCount);
s->addUniform(texSize);
//sets the texture? not sure about this line
s->addUniform(new osg::Uniform("tex", 0));



I have read about uniform arrays but they have some limitations as far as I have diged about them, so I thought this would be a better way to load texture once to GPU and then use it all the time. Once again - if someone keen with VS, OpenGL, GLSL could guide me with this task I would be very gratefull. I think such example could be also a good startup for others rendering such big scenes if provided general steps are posiible at all.

Thank you!

Cheers,
Mateusz[/code]
Back to top
View user's profile Send private message Send e-mail
mateas (Mateusz Janiak)
Newbie


Joined: 20 Jun 2013
Posts: 10
Location: Poland, Mysłowice

PostPosted: Wed Jul 31, 2013 6:57 pm    Post subject:
Instanced drawing
Reply with quote

Hi,

I have a large static scene to render - it will not change in time. It can contain even 1M spheres representing atoms in a particular material. I have read a lot about instanced drawing and went through examples:
osgdrawinstanced
osgshaders

but I can not to figure out how can I pass world positions for my sphere prototype instances. I am rather not familiar with plain OpenGL and GLSL, but what I have figured out till now is that I have to follow seweral steps in general:
1. Create my geometry drawable (simple sphere in my case using VBO)
2. Create vertex shader program tha would populate my sphere prototype on GPU side with defined number of instances
3. Attach to vertex shader a buffer? texture? some data representing positions of instances of this particular sphere type in world.
4. Sample buffer, texture with respect to gl_InstanceID to obtain sphere position at VS side

I think I could perform such operation for each sphere type in scene separately as there would be about 5 different spheres (radius). Is this correct approach? Or I should avoid creating several independent programs and try to create one doing all the stuff for different spheres?

I would appriciate if anyone could guide me through process of binding sphere`s world positions to vertext. As mentioned I was trying to attach to my geometry 1D texture filled with positions of sphere instances and read it in shader according to gl_InstanceID for obtaning proper position, hovewer I am doing something wrong and I see just one sphere with strange colors on it. I think my sampling and binding fails but I have no ide how could I investigate the problem and "debug" shader if it is even posiible.

I will just attach fragments of code I think are crucial for this task:
VS code

Code:
#version 330 core
uniform sampler1D tex;
uniform int texSize;
void main(void) {
/* fetch instance position from texture buffer and add the local vertex coordinate to it ? using gl_InstanceID and texSize to properly determine position of my instance coordinates*/
vec4 ObjectSpacePosition = texture(tex, gl_InstanceID / float(texSize)) + vec4(gl_Vertex, 1.0);
ObjectSpacePosition.w = 1.0;

/* transform into view space */
vec4 ViewSpacePosition = gl_ModelViewMatrix * ObjectSpacePosition;

/* transform into clip space */
gl_Position = gl_ProjectionMatrix * ViewSpacePosition;
}



Texture with position coordinates:


Code:
unsigned int instCount = ...;

osg::Image* image = new osg::Image;

// allocate the image data, instCount x 1 x 1 with 4 rgba floats - equivalent to a Vec4!
image->allocateImage(instCount,1,1,GL_RGBA,GL_FLOAT);
image->setInternalTextureFormat(GL_RGBA);

// fill in the image data
osg::Vec4* dataPtr = (osg::Vec4*)image->data();
for( osg::Vec3 pos : InstancePositions )
{
*dataPtr++ = osg::Vec4(pos, 1.0);
}

osg::Texture1D* texture = new osg::Texture1D;
texture->setWrap(osg::Texture1D::WRAP_S,osg::Texture1D::WrapMode::REPEAT);
texture->setFilter(osg::Texture1D::MIN_FILTER,osg::Texture1D::NEAREST);
texture->setImage(image);



And finally state set for geometry:


Code:
osg::ref_ptr< osg::StateSet > s = new osg::StateSet;

// setting proper GL modes
s->setMode(GL_CULL_FACE,osg::StateAttribute:ShockedN);
s->setMode(GL_LIGHTING, osg::StateAttribute:ShockedN);
s->setMode(GL_RESCALE_NORMAL, osg::StateAttribute:ShockedN);
s->setMode(GL_DEPTH_TEST, osg::StateAttribute:ShockedN);
s->setMode(GL_BLEND, osg::StateAttribute::OFF);

//create shader
osg::ref_ptr< osg::Shader > nVertexShader = new osg::Shader();
nVertexShader->setType( osg::Shader::VERTEX );
nVertexShader->setShaderSource( ... );

osg::ref_ptr< osg::Program > program = new osg::Program();
program->addShader( nVertexShader.get() );

s->setAttribute( program.get(), osg::StateAttribute:ShockedN | osg::StateAttribute::PROTECTED );

//set texture for node which I want to sample in shader for positions
s->setTextureAttribute(0,texture,osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_1D,osg::StateAttribute:ShockedN|osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_3D,osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
// size of texture so I can rescale my gl_InstanceID to proper float value in shader for texture sampling
osg::Uniform* texSize = new osg::Uniform("texSize",instCount);
s->addUniform(texSize);
//sets the texture? not sure about this line
s->addUniform(new osg::Uniform("tex", 0));




I have read about uniform arrays but they have some limitations as far as I have diged about them, so I thought this would be a better way to load texture once to GPU and then use it all the time. Once again - if someone keen with VS, OpenGL, GLSL could guide me with this task I would be very gratefull. I think such example could be also a good startup for others rendering such big scenes if provided general steps are posiible at all.

Thank you!

Cheers,
Mateusz[/code]

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







------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message Send e-mail
Jordi Torres
Guest





PostPosted: Thu Aug 01, 2013 7:40 am    Post subject:
Instanced drawing
Reply with quote

Hi Mateusz,


Take in mind that 1D textures are limited to 8192 texels, if you need more you should use a TextureBufferObject. I've attached a simple example getting postions from a texture 1D. The TransferFunction used is not necessary.


Hope it helps.



2013/6/20 Mateusz Janiak < (
Only registered users can see emails on this board!
Get registred or enter the forums!
)>
Quote:
Hi,

I have a large static scene to render - it will not change in time. It can contain even 1M spheres representing atoms in a particular material. I have read a lot about instanced drawing and went through examples:
osgdrawinstanced
osgshaders

but I can not to figure out how can I pass world positions for my sphere prototype instances. I am rather not familiar with plain OpenGL and GLSL, but what I have figured out till now is that I have to follow seweral steps in general:
1. Create my geometry drawable (simple sphere in my case using VBO)
2. Create vertex shader program tha would populate my sphere prototype on GPU side with defined number of instances
3. Attach to vertex shader a buffer? texture? some data representing positions of instances of this particular sphere type in world.
4. Sample buffer, texture with respect to gl_InstanceID to obtain sphere position at VS side

I think I could perform such operation for each sphere type in scene separately as there would be about 5 different spheres (radius). Is this correct approach? Or I should avoid creating several independent programs and try to create one doing all the stuff for different spheres?

I would appriciate if anyone could guide me through process of binding sphere`s world positions to vertext. As mentioned I was trying to attach to my geometry 1D texture filled with positions of sphere instances and read it in shader according to gl_InstanceID for obtaning proper position, hovewer I am doing something wrong and I see just one sphere with strange colors on it. I think my sampling and binding fails but I have no ide how could I investigate the problem and "debug" shader if it is even posiible.

I will just attach fragments of code I think are crucial for this task:
VS code

Code:
#version 330 core
uniform sampler1D tex;
uniform int texSize;
void main(void) {
/* fetch instance position from texture buffer and add the local vertex coordinate to it ? using gl_InstanceID and texSize to properly determine position of my instance coordinates*/
vec4 ObjectSpacePosition = texture(tex, gl_InstanceID / float(texSize)) + vec4(gl_Vertex, 1.0);
ObjectSpacePosition.w = 1.0;

/* transform into view space */
vec4 ViewSpacePosition = gl_ModelViewMatrix * ObjectSpacePosition;

/* transform into clip space */
gl_Position = gl_ProjectionMatrix * ViewSpacePosition;
}



Texture with position coordinates:


Code:
unsigned int instCount = ...;

osg::Image* image = new osg::Image;

// allocate the image data, instCount x 1 x 1 with 4 rgba floats - equivalent to a Vec4!
image->allocateImage(instCount,1,1,GL_RGBA,GL_FLOAT);
image->setInternalTextureFormat(GL_RGBA);

// fill in the image data
osg::Vec4* dataPtr = (osg::Vec4*)image->data();
for( osg::Vec3 pos : InstancePositions )
{
*dataPtr++ = osg::Vec4(pos, 1.0);
}

osg::Texture1D* texture = new osg::Texture1D;
texture->setWrap(osg::Texture1D::WRAP_S,osg::Texture1D::WrapMode::REPEAT);
texture->setFilter(osg::Texture1D::MIN_FILTER,osg::Texture1D::NEAREST);
texture->setImage(image);



And finally state set for geometry:


Code:
osg::ref_ptr< osg::StateSet > s = new osg::StateSet;

// setting proper GL modes
s->setMode(GL_CULL_FACE,osg::StateAttribute:ShockedN);
s->setMode(GL_LIGHTING, osg::StateAttribute:ShockedN);
s->setMode(GL_RESCALE_NORMAL, osg::StateAttribute:ShockedN);
s->setMode(GL_DEPTH_TEST, osg::StateAttribute:ShockedN);
s->setMode(GL_BLEND, osg::StateAttribute::OFF);

//create shader
osg::ref_ptr< osg::Shader > nVertexShader = new osg::Shader();
nVertexShader->setType( osg::Shader::VERTEX );
nVertexShader->setShaderSource( ... );

osg::ref_ptr< osg::Program > program = new osg::Program();
program->addShader( nVertexShader.get() );

s->setAttribute( program.get(), osg::StateAttribute:ShockedN | osg::StateAttribute::PROTECTED );

//set texture for node which I want to sample in shader for positions
s->setTextureAttribute(0,texture,osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_1D,osg::StateAttribute:ShockedN|osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_3D,osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
// size of texture so I can rescale my gl_InstanceID to proper float value in shader for texture sampling
osg::Uniform* texSize = new osg::Uniform("texSize",instCount);
s->addUniform(texSize);
//sets the texture? not sure about this line
s->addUniform(new osg::Uniform("tex", 0));




I have read about uniform arrays but they have some limitations as far as I have diged about them, so I thought this would be a better way to load texture once to GPU and then use it all the time. Once again - if someone keen with VS, OpenGL, GLSL could guide me with this task I would be very gratefull. I think such example could be also a good startup for others rendering such big scenes if provided general steps are posiible at all.

Thank you!

Cheers,
Mateusz[/code]

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





_______________________________________________
osg-users mailing list
(
Only registered users can see emails on this board!
Get registred or enter the forums!
)
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org



--
Jordi Torres

------------------
Post generated by Mail2Forum
Back to top
mateas (Mateusz Janiak)
Newbie


Joined: 20 Jun 2013
Posts: 10
Location: Poland, Mysłowice

PostPosted: Tue Aug 06, 2013 7:29 pm    Post subject:
Re: Instanced drawing
Reply with quote

Hi Jordi,

Thank You very much for an example. I will give it a try by the end of the week, as now I have lot of work to do with my PhD. If there would be any problems I will ask further questions:)

Jordi Torres wrote:
Hi Mateusz,


Take in mind that 1D textures are limited to 8192 texels, if you need more you should use a TextureBufferObject. I've attached a simple example getting postions from a texture 1D. The TransferFunction used is not necessary.


Hope it helps.



2013/6/20 Mateusz Janiak < (
Only registered users can see emails on this board!
Get registred or enter the forums!
)>
Quote:
Hi,

I have a large static scene to render - it will not change in time. It can contain even 1M spheres representing atoms in a particular material. I have read a lot about instanced drawing and went through examples:
osgdrawinstanced
osgshaders

but I can not to figure out how can I pass world positions for my sphere prototype instances. I am rather not familiar with plain OpenGL and GLSL, but what I have figured out till now is that I have to follow seweral steps in general:
1. Create my geometry drawable (simple sphere in my case using VBO)
2. Create vertex shader program tha would populate my sphere prototype on GPU side with defined number of instances
3. Attach to vertex shader a buffer? texture? some data representing positions of instances of this particular sphere type in world.
4. Sample buffer, texture with respect to gl_InstanceID to obtain sphere position at VS side

I think I could perform such operation for each sphere type in scene separately as there would be about 5 different spheres (radius). Is this correct approach? Or I should avoid creating several independent programs and try to create one doing all the stuff for different spheres?

I would appriciate if anyone could guide me through process of binding sphere`s world positions to vertext. As mentioned I was trying to attach to my geometry 1D texture filled with positions of sphere instances and read it in shader according to gl_InstanceID for obtaning proper position, hovewer I am doing something wrong and I see just one sphere with strange colors on it. I think my sampling and binding fails but I have no ide how could I investigate the problem and "debug" shader if it is even posiible.

I will just attach fragments of code I think are crucial for this task:
VS code

Code:
#version 330 core
uniform sampler1D tex;
uniform int texSize;
void main(void) {
/* fetch instance position from texture buffer and add the local vertex coordinate to it ? using gl_InstanceID and texSize to properly determine position of my instance coordinates*/
vec4 ObjectSpacePosition = texture(tex, gl_InstanceID / float(texSize)) + vec4(gl_Vertex, 1.0);
ObjectSpacePosition.w = 1.0;

/* transform into view space */
vec4 ViewSpacePosition = gl_ModelViewMatrix * ObjectSpacePosition;

/* transform into clip space */
gl_Position = gl_ProjectionMatrix * ViewSpacePosition;
}



Texture with position coordinates:


Code:
unsigned int instCount = ...;

osg::Image* image = new osg::Image;

// allocate the image data, instCount x 1 x 1 with 4 rgba floats - equivalent to a Vec4!
image->allocateImage(instCount,1,1,GL_RGBA,GL_FLOAT);
image->setInternalTextureFormat(GL_RGBA);

// fill in the image data
osg::Vec4* dataPtr = (osg::Vec4*)image->data();
for( osg::Vec3 pos : InstancePositions )
{
*dataPtr++ = osg::Vec4(pos, 1.0);
}

osg::Texture1D* texture = new osg::Texture1D;
texture->setWrap(osg::Texture1D::WRAP_S,osg::Texture1D::WrapMode::REPEAT);
texture->setFilter(osg::Texture1D::MIN_FILTER,osg::Texture1D::NEAREST);
texture->setImage(image);



And finally state set for geometry:


Code:
osg::ref_ptr< osg::StateSet > s = new osg::StateSet;

// setting proper GL modes
s->setMode(GL_CULL_FACE,osg::StateAttribute:ShockedN);
s->setMode(GL_LIGHTING, osg::StateAttribute:ShockedN);
s->setMode(GL_RESCALE_NORMAL, osg::StateAttribute:ShockedN);
s->setMode(GL_DEPTH_TEST, osg::StateAttribute:ShockedN);
s->setMode(GL_BLEND, osg::StateAttribute::OFF);

//create shader
osg::ref_ptr< osg::Shader > nVertexShader = new osg::Shader();
nVertexShader->setType( osg::Shader::VERTEX );
nVertexShader->setShaderSource( ... );

osg::ref_ptr< osg::Program > program = new osg::Program();
program->addShader( nVertexShader.get() );

s->setAttribute( program.get(), osg::StateAttribute:ShockedN | osg::StateAttribute::PROTECTED );

//set texture for node which I want to sample in shader for positions
s->setTextureAttribute(0,texture,osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_1D,osg::StateAttribute:ShockedN|osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_3D,osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
// size of texture so I can rescale my gl_InstanceID to proper float value in shader for texture sampling
osg::Uniform* texSize = new osg::Uniform("texSize",instCount);
s->addUniform(texSize);
//sets the texture? not sure about this line
s->addUniform(new osg::Uniform("tex", 0));




I have read about uniform arrays but they have some limitations as far as I have diged about them, so I thought this would be a better way to load texture once to GPU and then use it all the time. Once again - if someone keen with VS, OpenGL, GLSL could guide me with this task I would be very gratefull. I think such example could be also a good startup for others rendering such big scenes if provided general steps are posiible at all.

Thank you!

Cheers,
Mateusz[/code]

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





_______________________________________________
osg-users mailing list
(
Only registered users can see emails on this board!
Get registred or enter the forums!
)
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org



--
Jordi Torres

------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message Send e-mail
Trajce Nikolov NICK
Guest





PostPosted: Tue Aug 06, 2013 8:45 pm    Post subject:
Instanced drawing
Reply with quote

Hi Mateusz,

I went fast thru your email. I have faced similar challenge in the past and was able to resolve it with geometry shader. You pass only vertices (the centers of the spheres) and you create the actual geometry on the GPU. Just a fast hint from different perspective


Nick



On Tue, Aug 6, 2013 at 9:29 PM, Mateusz Janiak < (
Only registered users can see emails on this board!
Get registred or enter the forums!
)> wrote:
Quote:
Hi Jordi,

Thank You very much for an example. I will give it a try by the end of the week, as now I have lot of work to do with my PhD. If there would be any problems I will ask further questions:)


Jordi Torres wrote:
Quote:
Hi Mateusz,


Take in mind that 1D textures are limited to 8192 texels, if you need more you should use a TextureBufferObject. I've attached a simple example getting postions from a texture 1D. The TransferFunction used is not necessary.


Hope it helps.




Quote:
2013/6/20 Mateusz Janiak < ()>

Quote:
Hi,

I have a large static scene to render - it will not change in time. It can contain even 1M spheres representing atoms in a particular material. I have read a lot about instanced drawing and went through examples:
osgdrawinstanced
osgshaders

but I can not to figure out how can I pass world positions for my sphere prototype instances. I am rather not familiar with plain OpenGL and GLSL, but what I have figured out till now is that I have to follow seweral steps in general:
1. Create my geometry drawable (simple sphere in my case using VBO)
2. Create vertex shader program tha would populate my sphere prototype on GPU side with defined number of instances
3. Attach to vertex shader a buffer? texture? some data representing positions of instances of this particular sphere type in world.
4. Sample buffer, texture with respect to gl_InstanceID to obtain sphere position at VS side

I think I could perform such operation for each sphere type in scene separately as there would be about 5 different spheres (radius). Is this correct approach? Or I should avoid creating several independent programs and try to create one doing all the stuff for different spheres?

I would appriciate if anyone could guide me through process of binding sphere`s world positions to vertext. As mentioned I was trying to attach to my geometry 1D texture filled with positions of sphere instances and read it in shader according to gl_InstanceID for obtaning proper position, hovewer I am doing something wrong and I see just one sphere with strange colors on it. I think my sampling and binding fails but I have no ide how could I investigate the problem and "debug" shader if it is even posiible.

I will just attach fragments of code I think are crucial for this task:
VS code

Code:
#version 330 core
uniform sampler1D tex;
uniform int texSize;
void main(void) {
/* fetch instance position from texture buffer and add the local vertex coordinate to it ? using gl_InstanceID and texSize to properly determine position of my instance coordinates*/
vec4 ObjectSpacePosition = texture(tex, gl_InstanceID / float(texSize)) + vec4(gl_Vertex, 1.0);
ObjectSpacePosition.w = 1.0;

/* transform into view space */
vec4 ViewSpacePosition = gl_ModelViewMatrix * ObjectSpacePosition;

/* transform into clip space */
gl_Position = gl_ProjectionMatrix * ViewSpacePosition;
}



Texture with position coordinates:


Code:
unsigned int instCount = ...;

osg::Image* image = new osg::Image;

// allocate the image data, instCount x 1 x 1 with 4 rgba floats - equivalent to a Vec4!
image->allocateImage(instCount,1,1,GL_RGBA,GL_FLOAT);
image->setInternalTextureFormat(GL_RGBA);

// fill in the image data
osg::Vec4* dataPtr = (osg::Vec4*)image->data();
for( osg::Vec3 pos : InstancePositions )
{
*dataPtr++ = osg::Vec4(pos, 1.0);
}

osg::Texture1D* texture = new osg::Texture1D;
texture->setWrap(osg::Texture1D::WRAP_S,osg::Texture1D::WrapMode::REPEAT);
texture->setFilter(osg::Texture1D::MIN_FILTER,osg::Texture1D::NEAREST);
texture->setImage(image);



And finally state set for geometry:


Code:
osg::ref_ptr< osg::StateSet > s = new osg::StateSet;

// setting proper GL modes
s->setMode(GL_CULL_FACE,osg::StateAttribute:ShockedN);
s->setMode(GL_LIGHTING, osg::StateAttribute:ShockedN);
s->setMode(GL_RESCALE_NORMAL, osg::StateAttribute:ShockedN);
s->setMode(GL_DEPTH_TEST, osg::StateAttribute:ShockedN);
s->setMode(GL_BLEND, osg::StateAttribute::OFF);

//create shader
osg::ref_ptr< osg::Shader > nVertexShader = new osg::Shader();
nVertexShader->setType( osg::Shader::VERTEX );
nVertexShader->setShaderSource( ... );

osg::ref_ptr< osg::Program > program = new osg::Program();
program->addShader( nVertexShader.get() );

s->setAttribute( program.get(), osg::StateAttribute:ShockedN | osg::StateAttribute::PROTECTED );

//set texture for node which I want to sample in shader for positions
s->setTextureAttribute(0,texture,osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_1D,osg::StateAttribute:ShockedN|osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
s->setTextureMode(0,GL_TEXTURE_3D,osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
// size of texture so I can rescale my gl_InstanceID to proper float value in shader for texture sampling
osg::Uniform* texSize = new osg::Uniform("texSize",instCount);
s->addUniform(texSize);
//sets the texture? not sure about this line
s->addUniform(new osg::Uniform("tex", 0));




I have read about uniform arrays but they have some limitations as far as I have diged about them, so I thought this would be a better way to load texture once to GPU and then use it all the time. Once again - if someone keen with VS, OpenGL, GLSL could guide me with this task I would be very gratefull. I think such example could be also a good startup for others rendering such big scenes if provided general steps are posiible at all.

Thank you!

Cheers,
Mateusz[/code]

------------------
Read this topic online here:


Quote:
Quote:
http://forum.openscenegraph.org/viewtopic.php?p=54715#54715 (http://forum.openscenegraph.org/viewtopic.php?p=54715#54715)





_______________________________________________
osg-users mailing list
 ()
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org (http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org)




--
Jordi Torres

 ------------------
Post generated by Mail2Forum


------------------
Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=55787#55787





_______________________________________________
osg-users mailing list
(
Only registered users can see emails on this board!
Get registred or enter the forums!
)
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org






--
trajce nikolov nick

------------------
Post generated by Mail2Forum
Back to top
mateas (Mateusz Janiak)
Newbie


Joined: 20 Jun 2013
Posts: 10
Location: Poland, Mysłowice

PostPosted: Sun Aug 11, 2013 6:28 pm    Post subject:
Reply with quote

Ok, Jordi solution wokrs like a charm, I had only to disable culling on drawable, so that its all hardware instanced objects are not culled when original is not visible. I have another problem now - how to apply Material and Light to such a drawable so that it is populated with hardware instancing with shader? I can apply simple color, but despite applied light to the scene there is no light effect on drawable.

...


Thank you!

Cheers,
Mateusz
Back to top
View user's profile Send private message Send e-mail
Jordi Torres
Guest





PostPosted: Mon Aug 12, 2013 8:34 am    Post subject:
Instanced drawing
Reply with quote

Hi Mateusz,


2013/8/11 Mateusz Janiak < (
Only registered users can see emails on this board!
Get registred or enter the forums!
)>
Quote:
Ok, Jordi solution wokrs like a charm, I had only to disable culling on drawable, so that its all hardware instanced objects are not culled when original is not visible.


You must provide the BoundingBox yourself (i.e. using a computeBoundingBox callback) because OSG will only calculates the original instance bounding box. 


 
Quote:
I have another problem now - how to apply Material and Light to such a drawable so that it is populated with hardware instancing with shader? I can apply simple color, but despite applied light to the scene there is no light effect on drawable.



Did you tried to add normals to the instaced geometry?



Cheers.



Quote:
...


Thank you!

Cheers,
Mateusz

------------------
Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=55820#55820





_______________________________________________
osg-users mailing list
(
Only registered users can see emails on this board!
Get registred or enter the forums!
)
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org





--
Jordi Torres

------------------
Post generated by Mail2Forum
Back to top
mateas (Mateusz Janiak)
Newbie


Joined: 20 Jun 2013
Posts: 10
Location: Poland, Mysłowice

PostPosted: Mon Aug 12, 2013 10:32 am    Post subject:
Re: Instanced drawing
Reply with quote

Jordi Torres wrote:


Did you tried to add normals to the instaced geometry?



Yes, I add normals. Do You think I should modify fragment shader to calculate light there? If I skip fragment shader at all then speheres are always black independently how would I try to apply some color to them.


Thank you!

Cheers,
Mateusz

------------------
Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=55820#55820





_______________________________________________
osg-users mailing list
(
Only registered users can see emails on this board!
Get registred or enter the forums!
)
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


[/quote]


--
Jordi Torres

------------------
Post generated by Mail2Forum[/quote]
Back to top
View user's profile Send private message Send e-mail
Jordi Torres
Guest





PostPosted: Mon Aug 12, 2013 11:30 am    Post subject:
Instanced drawing
Reply with quote

Hi,

2013/8/12 Mateusz Janiak < (
Only registered users can see emails on this board!
Get registred or enter the forums!
)>
Quote:

Jordi Torres wrote:
Quote:


Did you tried to add normals to the instaced geometry?



Quote:
Quote:
Yes, I add normals. Do You think I should modify fragment shader to calculate light there?


Yes, I think so.





 
Quote:
> >
Quote:
Quote:

Thank you!

Cheers,
Mateusz

------------------
Read this topic online here:


Quote:
Quote:
http://forum.openscenegraph.org/viewtopic.php?p=55820#55820 (http://forum.openscenegraph.org/viewtopic.php?p=55820#55820)





_______________________________________________
osg-users mailing list
 ()
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org (http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org)






--
Jordi Torres

 ------------------
Post generated by Mail2Forum



------------------
Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=55823#55823





_______________________________________________
osg-users mailing list
(
Only registered users can see emails on this board!
Get registred or enter the forums!
)
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org





--
Jordi Torres

------------------
Post generated by Mail2Forum
Back to top
mateas (Mateusz Janiak)
Newbie


Joined: 20 Jun 2013
Posts: 10
Location: Poland, Mysłowice

PostPosted: Mon Sep 16, 2013 9:31 am    Post subject:
Reply with quote

Hi,

I have implemented the simplest fragment shader applying only particular color to my primitives as this was sufficient. However now I want to create a composition of a simple osg::ShapeDrawable for a osg::Box and my instanced material (spheres), where Box should be semitransparent and so should be the instanced material. But what I get You can see in the attached photos. In the first one Box is theoretically transparent, but I can`t see the material inside it. In the second photo, if I am inside the Box I can see both semi transparent: box and material. Does anyone know how to fix it also for viewing box from outside to be transparent and material inside would be visible? Probabbly some neaty StateSet configuration or more complex fragment shader? Additionally - does osg support Material for instanced objects or I have to implement it with whole light manualy in fragment shader? I was thinking about some default osg fragment shader providing complete light and material handling but I think such thing does not exist. Am I wrong?


Thank you!

Cheers,
Mateusz
Back to top
View user's profile Send private message Send e-mail
SMesserschmidt (Sebastian Messerschmidt)
Forum Moderator


Joined: 10 Sep 2013
Posts: 767

PostPosted: Mon Sep 16, 2013 9:39 am    Post subject:
Instanced drawing
Reply with quote

Hello Mateusz,

When you use instanced drawing you cannot have correct semi-transparent objects, as there is no sorting involved.
One option is to sort your instanced obejcts in every frame or to use some order independent transparency approach.
Also concerning your Material and stateset problems:
When using instancing you will somehow have to pass per instance data to your shaders and evaluate them there. So if you need per instance colors you need to pass an array which hold the instance color.
It will not work using osg::Material out of the box.
cheers
Sebastian

Quote:
Quote:
Hi,

I have implemented the simplest fragment shader applying only particular color to my primitives as this was sufficient. However now I want to create a composition of a simple osg::ShapeDrawable for a osg::Box and my instanced material (spheres), where Box should be semitransparent and so should be the instanced material. But what I get You can see in the attached photos. In the first one Box is theoretically transparent, but I can`t see the material inside it. In the second photo, if I am inside the Box I can see both semi transparent: box and material. Does anyone know how to fix it also for viewing box from outside to be transparent and material inside would be visible? Probabbly some neaty StateSet configuration or more complex fragment shader? Additionally - does osg support Material for instanced objects or I have to implement it with whole light manualy in fragment shader? I was thinking about some default osg fragment shader providing complete light and material handli
ng but I think such thing does not exist. Am I wrong?


Thank you!

Cheers,
Mateusz

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





Quote:
_______________________________________________
osg-users mailing list
(
Only registered users can see emails on this board!
Get registred or enter the forums!
)
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message
mateas (Mateusz Janiak)
Newbie


Joined: 20 Jun 2013
Posts: 10
Location: Poland, Mysłowice

PostPosted: Mon Sep 16, 2013 10:22 am    Post subject:
Re: Instanced drawing
Reply with quote

SMesserschmidt wrote:

When you use instanced drawing you cannot have correct semi-transparent objects, as there is no sorting involved.
One option is to sort your instanced obejcts in every frame or to use some order independent transparency approach.



Could You provide me avaiable techniques in OSG that allow me to introduce objects sorting for native OSG objects and instanced ones?

Thank you!

Cheers,
Mateusz
Back to top
View user's profile Send private message Send e-mail
SMesserschmidt (Sebastian Messerschmidt)
Forum Moderator


Joined: 10 Sep 2013
Posts: 767

PostPosted: Mon Sep 16, 2013 10:46 am    Post subject:
Instanced drawing
Reply with quote

Hi Mateusz,
Quote:
[quote="SMesserschmidt"]
When you use instanced drawing you cannot have correct semi-transparent objects, as there is no sorting involved.
One option is to sort your instanced obejcts in every frame or to use some order independent transparency approach.

Quote:


Could You provide me avaiable techniques in OSG that allow me to introduce objects sorting for native OSG objects and instanced ones?
Sorting per object will be done by the scene graph automatically if the
stateset contains blending ( @All please correct me here, but I'm not
sure about all the details).
Usually this is done with DepthSortedBin Renderbin implementation, which
you can override and even write your own Renderbin implementation.
For starters just rely on the automatic sorting, but beware that is per
drawable not per face. So having a semitransparent box will not always
result in the desired behavior.
This is a complicated topic and there is no general solution to this. If
you want to dive deeper into order independent blending look into the
examples (osgoit) and look in the mailing list archives/forum. The
topic was touch not long ago.

In case of instanced drawing (in case you are using real GPU instancing)
there is no ready-to-use implementation, at least non that i know off.
I'd start with adding a (cull-)callback to the part which defines your
texture/buffer object and implement a kind of sorting based on distance
to the camera.
It might very well be that there is flaw in my idea, but since I didn't
have to solve such problem I leave the experimenting to you.

In general I would say that sorting/semitransparent objects and
instancing simply doesn't play well, so maybe you should step back and
check if you really need instancing here at all.

cheers
Sebastian
Quote:

Thank you!

Cheers,
Mateusz

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









------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message
mateas (Mateusz Janiak)
Newbie


Joined: 20 Jun 2013
Posts: 10
Location: Poland, Mysłowice

PostPosted: Mon Sep 16, 2013 11:06 am    Post subject:
Reply with quote

Hi Sebastian ,

Well, I need instancing as I render about 1M spehers presenting material atoms structure. The Box I want to add is just a marker for a part of the whole material, so user can focus easier on it. Moreover, box will always contain instanced spheres inside, so the order is somehow fixed here or it is not enough? If I would introduce also box as a custom shader program will this help?

...


Thank you!

Cheers,
Mateusz
Back to top
View user's profile Send private message Send e-mail
SMesserschmidt (Sebastian Messerschmidt)
Forum Moderator


Joined: 10 Sep 2013
Posts: 767

PostPosted: Mon Sep 16, 2013 11:43 am    Post subject:
Instanced drawing
Reply with quote

Hi Mateusz,

From reading your message I'd say you don't really need semitransparent
geometries at all. Try to stick to a wireframe box or coloring the
selction set.
Regarding the order: yes. If you draw your instanced spheres first, you
can safely render the sides of your box in perfect ordering. But this
applies only if the spheres itself are not transparent.
Ordering has to be done w.r.t. the camera/viewpoint, so even fixed order
won't help if the spheres are transparent.
I'd really suggest going with the opaque spheres and rendering the
selection afterwards.

cheers
Sebastian
Quote:
Hi Sebastian ,

Well, I need instancing as I render about 1M spehers presenting material atoms structure. The Box I want to add is just a marker for a part of the whole material, so user can focus easier on it. Moreover, box will always contain instanced spheres inside, so the order is somehow fixed here or it is not enough? If I would introduce also box as a custom shader program will this help?

...


Thank you!

Cheers,
Mateusz

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









------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    OpenSceneGraph Forum Forum Index -> General [forum] All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum

Similar Topics
Topic Author Forum Replies Posted
No new posts Drawing large number of labels loopy General 5 Fri Mar 31, 2017 12:12 am View latest post
No new posts Draw Instanced intersections Bruno Oliveira General 4 Tue Jan 03, 2017 8:59 am View latest post
No new posts Trouble Drawing Text in Arabic ehensens General 5 Tue Nov 01, 2016 8:35 pm View latest post
No new posts LOD for drawing lines of a co-ordinat... Andreas Goebel General 1 Thu Oct 13, 2016 2:28 pm View latest post
No new posts Controlling drawing order kragnfroll General 1 Fri Jul 01, 2016 2:59 pm View latest post


Board Security Anti Bot Question MOD - phpBB MOD against Spam Bots
Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP