View Full Version : How to force tesselation in a material shader
remia
April 24th, 2008, 17:28
Hi,
In an init phase of a material shader, I would like to scan the renderable geometry (triangle boxes) of a given object having it's DAG tag.
I know how to scan a triangle box when the source object is already tessellated, but sometimes, as no rays has hits the bounding box of the source object at shader init time, the leaf instance and so the tessellated geometry (renderable geometry) are not yet present.
Finally, my question is : how to force tessellation of the source geometry having a dag TAG to obtain the renderable geometry ?
Thank you
bart
April 24th, 2008, 18:02
The material shader could apply to several different objects. Do you want all of them tessellated?
What are you trying to accomplish in general?
dlanier
April 24th, 2008, 20:00
Hello,
The function is mi_geoshader_tesselate but only works in a geometry shader. But tesselation is done before eye rays are casted so no way to do that in a material shader I suppose...
Regards,
remia
April 25th, 2008, 11:23
Hi David, hi Bart,
Tell me if I'am wrong, but I thought that source objects was not tessalated until that their bounding box was hit by a ray. If I'am wrong this thread become meaningless.
But let's suppose I'am right, In that material shader, I have a instance DAG tag of a source object coming from the UI (not the tag of the material shader I mean, this object it's not supposed to have that material shader applied on it). This object is a simple object present in the scene, and as this object is not inevitably hit by a ray *before* that material shader is initiated, it's leaf instance (and so his leaf instance tag) doesn't exist in all configurations (it depends of the tile order and object's positions). Perhaps that you could see this thread : http://forum.lamrug.org/viewtopic.php?f=9&t=1403
What I want to do is rather simple : Read the renderable geometry of that object (like in a lightmap shader), and then use it to do some stuff with in that material shader. So how to force the tesselation of that object ?
I know that a mi_trace_probe in the bbox of the object could do the trick but it's not realy nice. Must I inevitably use a complex set of couple of lightmap / material shader on differents objects ?
Thank you for your help.
bart
April 25th, 2008, 15:58
Often tessellation happens after scene pre-processing and then must be a job that is done on demand when a ray hits its bounding box. But not always.
However, all leaf instances are created as a result of scene pre-processing before rays are shot, and possibly before a tessellation job. You can get a scene DAG instance from a leaf instance using mi_query(miQ_INST_PARENT, ...), but I'd have to think about how to do it in reverse.
remia
April 25th, 2008, 21:12
For the moment, I do the reverse job by traversing the leaf instances list (which is doublely linked). So it's enough to have only one leaf instance to get the others, I use the one present in state->instance on shader init. Then for each instance in the list, using mi_query(miQ_INST_PARENT, ...), I find the right leaf instance tag by finding the one which has it's parent tag equal to the instance object tag (the one given by the UI). It's working, but sometimes it's seems that some of the leaf instances are not created on the material shader init time, probably the ones which have not been hit by any ray...
bart
April 26th, 2008, 01:49
All leaf instances, except those inside assemblies, are created at scene pre-processing.
remia
April 28th, 2008, 15:08
Firstly, Thank you Bart for your help.
Ok, I have done more tests. Indeed, the leaf instance list has the same size at shader init time, and for every one of them. But there is still something that I don't understand when I'm traversing recusively the source DAG (yes, I have to).
Here is the context :
The UI gives to the shader an instance tag. Generaly this instance tag have an instanced element of type group, this group has only one child instance, and this instance instantiate an element of type miSCENE_OBJECT. ( This pattern seems to be XSI specific, isn't it ?)
When the DAG is flattened, the leaf instances list is created, and I want to find in this list the leaf instance generated by that miSCENE_OBJECT. As there is no built in link(s) beetween a source DAG instance to the generated leaf instance(s), I do the following :
1/ I create a list containing all leaf instances present in the scene by following the leaf instance doubled linked list. Using this code :
// Giving a proper state (containing a state->instance, which is a
// leafInstanceTag in material shader, this is not working in geometry shaders).
// this method gives a list of the leaf instances object in the scene
static void LeafInstanceList(vector<miTag> &leafInstList, miState *state) {
leafInstList.clear();
miTag leafInstTag = state->instance;
while (leafInstTag != miNULLTAG) {
leafInstList.push_back(leafInstTag);
miTag nextLeafInstTag = ( (miInstance*) mi_db_access(leafInstTag) )->next ;
mi_db_unpin(leafInstTag);
leafInstTag = nextLeafInstTag;
}
leafInstTag = state->instance;
while (leafInstTag != miNULLTAG) {
if (leafInstTag != state->instance) // we dont want input tag to be twicely inserted;
leafInstList.push_back(leafInstTag);
miTag prevLeafInstTag = ( (miInstance*) mi_db_access(leafInstTag) )->prev ;
mi_db_unpin(leafInstTag);
leafInstTag = prevLeafInstTag;
}
//mi_warning("Leaf instance count %i", leafInstList.size());
}
2/ Starting from the source instance DAG tag, I'm traversing recusively the source DAG, to find all child elements of type miSCENE_OBJECT, using this code called with tagTypeWanted = miSCENE_OBJECT, the output is a list containing all tag of type miSCENE_OBJECT.
// Giving any tag in the source DAG and a tagType, this method returns a vector of tag of type tagTypeWanted
// by walking down the source DAG hierarchy starting from element of tag tag.
static void SourceDAGWalker(vector<miTag> &tagDAGList, const miTag tag, const int tagTypeWanted, const unsigned int level = 0) {
if (tag == miNULLTAG)
throw CEx(__FILE__,__LINE__,__FUNCSIG__);
int tagType;
tagType = mi_db_type(tag);
// unrelated display code
string space;
space.insert(0, 4*level, ' ');
mi_warning("%stag %i tagType %s ", space.c_str(), tag, miTextTypes[tagType]);
// End of display code
if (tagType == tagTypeWanted || tagType == 1<<31)
tagDAGList.push_back(tag);
// only miSCENE_GROUP and miSCENE_INSTANCE can lead to other miSCENE_X elements
if (tagType == miSCENE_GROUP) {
unsigned int kidsNum;
mi_query(miQ_GROUP_NKIDS, NULL, tag, &kidsNum);
mi_warning("n kids %i ", kidsNum);
for (unsigned int k = 0; k < kidsNum; k++) {
miTag childInstanceTag;
mi_query( miQ_GROUP_KID, NULL, tag, &childInstanceTag, k );
SourceDAGWalker(tagDAGList, childInstanceTag, tagTypeWanted, level+1);
}
}
else if (tagType == miSCENE_INSTANCE) {
miTag itemTag;
mi_query(miQ_INST_ITEM, NULL, tag, &itemTag);
SourceDAGWalker(tagDAGList, itemTag, tagTypeWanted, level+1);
}
}
3/ Combining the two previous lists, I find the right leaf instance(s) by looking for the leaf instance which have his instanced scene element contained in the miSCENE_OBJECT list (the list created in 2/). Using this code :
// Giving a clean state (containing a state->instance, which is a
// leafInstanceTag in material shader this is not working in geometry shaders) and
// giving a tag of the source DAG, this method returns all leaf instances generated by tag and their chidren
static void LeafInstancesFinder(vector<miTag> &leafInstList, const miTag tag, miState *state) {
vector<miTag> leafInstList0;
LeafInstanceList(leafInstList0, state);
mi_warning("leafInstList0.size() %i",leafInstList0.size());
vector<miTag> itemTagDAGList;
SourceDAGWalker(itemTagDAGList, tag, miSCENE_OBJECT);
mi_warning("itemTagDAGList.size() %i",itemTagDAGList.size());
// Looking for leafInstList0 element having for parent item one of the miSCENE_OBJECT contained in tagDAGList
for (unsigned int i=0; i < leafInstList0.size(); i++) {
miTag itemTag;
mi_query(miQ_INST_ITEM, NULL, leafInstList0[i], &itemTag);
for (unsigned int j=0; j < itemTagDAGList.size(); j++) {
if (itemTag == itemTagDAGList[j] )
leafInstList.push_back(leafInstList0[i]);
}
}
}
The thing I cannot understand problem appears in step 2/. Sometimes, the process works, sometimes not, depending of the camera point of view.
Here is an output when it works :
' INFO : PHEN 0.5 info : GetColor shader request leaf tag for object DAG tag RefObjects[0]=1255
' WARNING : PHEN 0.5 warn : leafInstList0.size() 13
' WARNING : PHEN 0.5 warn : tag 1255 tagType miSCENE_INSTANCE
' WARNING : PHEN 0.5 warn : tag 1252 tagType miSCENE_GROUP
' WARNING : PHEN 0.5 warn : n kids 1 <===== OK
' WARNING : PHEN 0.5 warn : tag 1254 tagType miSCENE_INSTANCE
' WARNING : PHEN 0.5 warn : tag 1253 tagType miSCENE_OBJECT
' WARNING : PHEN 0.5 warn : itemTagDAGList.size() 1
Here is an output when it don't works :
' INFO : PHEN 0.6 info : GetColor shader request leaf tag for object DAG tag RefObjects[0]=1198
' WARNING : PHEN 0.6 warn : leafInstList0.size() 13
' WARNING : PHEN 0.6 warn : tag 1198 tagType miSCENE_INSTANCE
' WARNING : PHEN 0.6 warn : tag 1057 tagType miSCENE_GROUP
' WARNING : PHEN 0.6 warn : n kids 0 <===== ???
' WARNING : PHEN 0.6 warn : itemTagDAGList.size() 0
So it seems that the group haven't any child... Is it a Bug or something ? Any ideas ?
remia
May 5th, 2008, 15:08
Hi,
I think I have found but I'am not sure. I have made an output of the scene in a .mi file, and there is something strange with the scene definition. On some object (not all), there is writted this :
Object number 7 (cause problem) :
instance "ref7"
"__DummyGroup__" <========== ?????
visible off
shadow off
trace off
transparency 12
caustic 6
globillum 3
finalgather 3
transform
-0.013066177 0 0.11913557 0
0 0.12947442 0 0
0.12881343 -0 0.012084505 -0
22.39525 -4.5217023 -0.15765968 1
motion off
material ["ref7/DefaultLib/Ref"]
light "exclusive" [ ]
()
end instance
Object number 1 (no problem with it)
instance "ref1"
"ref1/Polygon Mesh" <===================== OK
visible off
shadow off
trace off
transparency 12
caustic 6
globillum 3
finalgather 3
transform
-0.013066178 0 0.11913557 0
0 0.12947442 0 0
0.12881343 -7.4595996e-011 0.012084505 0
0.086973332 -4.5217023 -11.572691 1
motion off
material ["ref1/DefaultLib/Ref"]
light "exclusive" [ ]
()
end instance
I dont understand why XSI writtes this "__DummyGroup__" instead of including the geometry of the object because there is no difference beetween the two objects inside the XSI UI scene explorer.
Thank you all
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.