Hi,
just trying to get GL instancing working in GL3 via a GR primitive Hook.
I can happily create and draw one trinagle, but am unable to instance it twice..
to setup the two instances, I create two matrices, and append them to a vector of matrices, then pass them to my RE_geometry as an instanced attribute..
on a geo->draw it willwork and draw one, but a call to drawinstanced, it will crash… any advice appreciated
these are my modifications to the HDK example GUI_Primframework to test it
——— in update() ———–
bool new_geo = false;
if (!myGeometry)
{
myGeometry = new RE_Geometry(3);
new_geo = true;
}
UT_Vector3FArray pos(3, 3);
pos(0) = UT_Vector3F(0,0,0);
pos(1) = UT_Vector3F(1,0,0);
pos(2) = UT_Vector3F(0,1,0);
myGeometry->createAttribute(r, “P”, RE_GPU_FLOAT32, 3, pos.array()->data());
GR_UtilsGL3::buildInstanceObjectMatrix(r, primh, p, myGeometry, p.instance_version);
UT_Matrix4F instance;
instance.identity();
std::vector<UT_Matrix4F> instances;
instance.translate(2,0,0);
instances.push_back(instance);
instance.translate(0,2,0);
instances.push_back(instance);
//the below works with regular draw()
//myGeometry->createConstAttribute(r, “instmat”, RE_GPU_MATRIX4, 1, instances.data());
// the below fails with a crash called via ->drawinstanced() or even a ->draw() in the render()
myGeometry->createInstancedAttribute(r, “instmat”, RE_GPU_MATRIX4, 1, 0, 2, instances.data());
if (new_geo)
{
const unsigned line_connect = { 0, 1, 1, 2, 2, 0 };
myGeometry->connectIndexedPrimsI(r, 1, RE_PRIM_LINES, 6, line_connect);
}
——- in render ——
r->pushShader();
r->bindShader(theLineShader);
myGeometry->drawInstanced(r, 1, 2); // <- this fails
// myGeometry->draw(r, 1); //<-this works
r->popShader();
————————
p.s I'm assuming that once I get this going I can pass Cd/Alpha as a another instanced attribute and also get each instance to draw a difference colour..!
[HDK] GR primitive rendering GL instances
4979 8 1-
- _milo_
- Member
- 766 posts
- Joined: Sept. 2011
- Offline
-
- _milo_
- Member
- 766 posts
- Joined: Sept. 2011
- Offline
BTW: the shader we are using to test is:
static RE_ShaderHandle theLineShader(“basic/GL32/wire_color.prog”);
which does expect instmat as a mat4: i.e:
in mat4 instmat;
unlike the example here which uses vec3 to do translates:
http://www.sidefx.com/docs/hdk13.0/_h_d_k__viewport_r_e.html#HDK_ViewportRE_Instancing [sidefx.com]
static RE_ShaderHandle theLineShader(“basic/GL32/wire_color.prog”);
which does expect instmat as a mat4: i.e:
in mat4 instmat;
unlike the example here which uses vec3 to do translates:
http://www.sidefx.com/docs/hdk13.0/_h_d_k__viewport_r_e.html#HDK_ViewportRE_Instancing [sidefx.com]
Miles Green, Supervising TD, Netflix Animation Studios
-
- malexander
- Staff
- 5287 posts
- Joined: July 2005
- Offline
The easiest way to do this is to let buildObjectInstanceMatrix() do the work for you. Create a new GR_UpdateParms based on update()'s GR_UpdateParms parameter and assign a UT_Matrix4DArray containing your matrices to GR_UpdateParms::instances (or multiply it with the instance list, if it exists). You'll also want to substitute GR_UpdateParms::geo_version for GR_UpdateParms::instance_version so that the instance matrix array updates when the geometry changes, rather than when the object instancing parms change:
UT_Matrix4DArray inst;
inst.append(UT_Matrix4D::getIdentityTransform());
inst.last().translate(2,0,0);
inst.append(UT_Matrix4D::getIdentityTransform());
inst.last().translate(0,2,0);
GR_UpdateParms ip(p);
ip.instances = &inst;
GR_UtilsGL3::buildInstanceObjectMatrix(r, primh, ip, myGeometry, ip.geo_version);
This is just for the case where p.instances == NULL. For the non-null case, you'd basically convolve the two lists together and combine the geo_version and inst_version into a single version - RE_CacheVersion v(p); v.setElement(0, p.instance_version.getElement(0) + p.geo_version); .
UT_Matrix4DArray inst;
inst.append(UT_Matrix4D::getIdentityTransform());
inst.last().translate(2,0,0);
inst.append(UT_Matrix4D::getIdentityTransform());
inst.last().translate(0,2,0);
GR_UpdateParms ip(p);
ip.instances = &inst;
GR_UtilsGL3::buildInstanceObjectMatrix(r, primh, ip, myGeometry, ip.geo_version);
This is just for the case where p.instances == NULL. For the non-null case, you'd basically convolve the two lists together and combine the geo_version and inst_version into a single version - RE_CacheVersion v(p); v.setElement(0, p.instance_version.getElement(0) + p.geo_version); .
-
- _milo_
- Member
- 766 posts
- Joined: Sept. 2011
- Offline
great thanks twod, that helps a bunch… now we're able to do some basic GL instancing… essentially we're mirroring the obj instance node, but at sop level..
Plus we will try to get the instances to inherit Cd/Alpha something we've never been able to do with houdini's default fast point instancing.
Plus we will try to get the instances to inherit Cd/Alpha something we've never been able to do with houdini's default fast point instancing.
Miles Green, Supervising TD, Netflix Animation Studios
-
- _milo_
- Member
- 766 posts
- Joined: Sept. 2011
- Offline
just a quick query, all is going well but the alpha is doing something funny.
we find that the alpha value we insert gets evaluated as a binary on or off unless we insert a pushUniformData(RE_UNIFORM_ALPHA_PASS , alphavalue) around our draw instanced calls i.e:
fpreal32 tempalpha = {1.0,1.0,1.0,1};
ren.pushUniformData(RE_UNIFORM_ALPHA_PASS , tempalpha);
data.m_geo->drawInstanced(&ren, RE_GEO_SHADED_IDX, instancelist.capacity());
ren.popUniformData(RE_UNIFORM_ALPHA_PASS);
if we do this then we get floating point alpha values but the polys render in the style of hidden line invisible. i.e you can see the background grid though them but not other polys (see pic)
we are assuming we are missing a vital step to get the alpha working properly.. any suggestions
we find that the alpha value we insert gets evaluated as a binary on or off unless we insert a pushUniformData(RE_UNIFORM_ALPHA_PASS , alphavalue) around our draw instanced calls i.e:
fpreal32 tempalpha = {1.0,1.0,1.0,1};
ren.pushUniformData(RE_UNIFORM_ALPHA_PASS , tempalpha);
data.m_geo->drawInstanced(&ren, RE_GEO_SHADED_IDX, instancelist.capacity());
ren.popUniformData(RE_UNIFORM_ALPHA_PASS);
if we do this then we get floating point alpha values but the polys render in the style of hidden line invisible. i.e you can see the background grid though them but not other polys (see pic)
we are assuming we are missing a vital step to get the alpha working properly.. any suggestions
Miles Green, Supervising TD, Netflix Animation Studios
-
- malexander
- Staff
- 5287 posts
- Joined: July 2005
- Offline
In your GR primitive, override:
virtual bool requiresAlphaPass() const { return true; }
virtual bool renderInAlphaPass(GR_AlphaPass a) { return true; }
You can also conditionally request an alpha pass based on your geometry (if Alpha is present or not, for example).
The second virtual specifies the exact passes to participate in, which will be unnecessary in the next major release. For now just have it return true.
virtual bool requiresAlphaPass() const { return true; }
virtual bool renderInAlphaPass(GR_AlphaPass a) { return true; }
You can also conditionally request an alpha pass based on your geometry (if Alpha is present or not, for example).
The second virtual specifies the exact passes to participate in, which will be unnecessary in the next major release. For now just have it return true.
-
- _milo_
- Member
- 766 posts
- Joined: Sept. 2011
- Offline
-
- _milo_
- Member
- 766 posts
- Joined: Sept. 2011
- Offline
one last question..
can the RE hooks be added to points without a primitive, we currently create a particle system primitive with an add sop to get our hook get a register/draw via
GA_PrimitiveTypeId type(GA_PRIMPART);
dm_table->registerGEOHook(new GUI_PrimFrameworkHook(), type, priority, GUI_HOOK_FLAG_NONE);
we tried switching GA_PRIMPART to GA_PRIMNONE but then nothing renders
can the RE hooks be added to points without a primitive, we currently create a particle system primitive with an add sop to get our hook get a register/draw via
GA_PrimitiveTypeId type(GA_PRIMPART);
dm_table->registerGEOHook(new GUI_PrimFrameworkHook(), type, priority, GUI_HOOK_FLAG_NONE);
we tried switching GA_PRIMPART to GA_PRIMNONE but then nothing renders
Miles Green, Supervising TD, Netflix Animation Studios
-
- malexander
- Staff
- 5287 posts
- Joined: July 2005
- Offline
-
- Quick Links

