These forums are CLOSED. Please visit the new forums HERE
RGB displacement map from Blender? |
|
|
Sylvia Trilling
Flying Tribe
Join date: 2 Oct 2006
Posts: 1,117
|
04-28-2007 12:24
OOO! OOOO! The sculpted prim video is so thrilling. Organic shapes. Rounded corners without need a million prims. I was inspired to download Blender and I am working my way through the tutorials now. Can anyone tell me how to create the displacement map from Blender?
|
|
Sylvia Trilling
Flying Tribe
Join date: 2 Oct 2006
Posts: 1,117
|
04-28-2007 13:18
I think I found the answer in the wiki faq http://wiki.secondlife.com/wiki/Sculpted_Prims
"We provide an exporter for Maya, and hopefully exporters for 3ds Max, Blender, and ZBrush will be available soon. We also have plans to provide a sculpt editor within the Second Life viewer." So I have to wait until an exporter for Blender is available? |
|
Brenham Beale
Registered User
Join date: 26 Aug 2006
Posts: 65
|
04-28-2007 17:40
Or you can try your hand at translating the MEL script into Python for Blender3D's consumption before Linden Labs creates one.
|
|
RobbyRacoon Olmstead
Red warrior is hungry!
Join date: 20 Sep 2006
Posts: 1,821
|
04-28-2007 18:16
I am curious about this. I haven't played with this kind of stuff much (in RL), though my son is happily reading everything he can about it.
This seems to be somewhat similar in concept to normal mapping. Could a tutorial like this one on how to create a normal map in Blender be modified to suit this purpose? That is, use a similar technique but obviously modified in whatever way necessary to generate the correct output? Or would it necessarily have to be done by an exporter? . _____________________
|
|
Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671
|
04-28-2007 22:49
This would be similar to normal mapping, but I'm going to guess the the 0 - 255 range of each RGB channel pixel would map to the -0.5 - +0.5 range along each XYZ axis, instead of the 0.0 - 1.0 range of a normalized vector component. e.g. The color value < 255, 0, 0 > would represent a spacial coordinate of < 0.5, -0.5, -0.5 >. Then, each pixel in a 32x32 texture would correspond to a vertex in a 32x32 poly mesh, which is, topologically, at least cylindrical (right edge wraps back around to left) if not spherical (uppermost and lowermost rows of points are unified). [EDIT: After reading the Discussion page on that Wiki entry, the initial generation of sculpted prims will have a spherical topology]
The FAQ mentions QuickTime anims made of sculpture maps to animate sculptured prims, but I'd think something more useful for SL would be a variant of llSetTextureAnim for the sculpture map "channel". Something like this could probably be approximated by successive llSetPrimitiveParams( [ PRIM_TYPE, PRIM_TYPE_SCULPTED, tex_frame ]); calls, but would be laggy and uneven. |
|
Fox Absolute
Registered User
Join date: 30 May 2005
Posts: 75
|
04-29-2007 07:56
The FAQ mentions QuickTime anims made of sculpture maps to animate sculptured prims, but I'd think something more useful for SL would be a variant of llSetTextureAnim for the sculpture map "channel". Something like this could probably be approximated by successive llSetPrimitiveParams( [ PRIM_TYPE, PRIM_TYPE_SCULPTED, tex_frame ]); calls, but would be laggy and uneven. I thought about this last night and had to wonder; since the shape of a sculpty prim is determined by the texture, does that mean the shape doesn't actually render correctly until the texture loads completely? If so, constantly switching between textures that all have to load independently would be quite ugly. |
|
Infiniview Merit
The 100 Trillionth Cell
Join date: 27 Apr 2006
Posts: 845
|
04-29-2007 08:43
The texture used for the sculpt effect will be independent of the usual main surface texture
so that should not pose a problem. ![]() Oh I didnt read the entire above quote, oops, never mind, hehe. _____________________
|
|
Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671
|
04-29-2007 08:43
since the shape of a sculpty prim is determined by the texture, does that mean the shape doesn't actually render correctly until the texture loads completely? If so, constantly switching between textures that all have to load independently would be quite ugly. |
|
Infiniview Merit
The 100 Trillionth Cell
Join date: 27 Apr 2006
Posts: 845
|
04-29-2007 08:48
Ok so LL is to this point still being fairly unclear on what needs to be done to apply the final maps unless...
And I hope this is the case, that the exporter creates the map from the model For you. That would super simplify the entire process! _____________________
|
|
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
|
04-29-2007 12:02
I am curious about this. I haven't played with this kind of stuff much (in RL), though my son is happily reading everything he can about it. Tell him to get my son on the ball ![]() Is Blender not Open Source? If someone has the algorithm, or better yet, a library for these new export map thingies, there are a lot of people who can splice it in. Someone shuld be promoting this idea to the Blender people. |
|
Infiniview Merit
The 100 Trillionth Cell
Join date: 27 Apr 2006
Posts: 845
|
04-29-2007 12:57
// * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
// * $License$ global proc string llFirst(string $list[]) { return $list[0]; } global proc llSculptExport(string $object, string $file_name, string $file_format, int $resolution_x, int $resolution_y, int $maximize_scale, int $fix_orientation) { // copy it, because we're going to mutilate it. MUHAHAHAAAaa... string $object_copy = llFirst(duplicate($object)); // disentangle from groups string $parents[] = listRelatives("-parent", $object_copy); if (size($parents) != 0) $object_copy = llFirst(parent("-world", $object_copy)); // scale it to unit cube float $bounding_min[3]; float $bounding_max[3]; $bounding_min = getAttr($object_copy + ".boundingBoxMin" ;$bounding_max = getAttr($object_copy + ".boundingBoxMax" ;float $scale[3]; int $i; for ($i = 0; $i < 3; $i++) $scale[$i] = $bounding_max[$i] - $bounding_min[$i]; float $scale_max = 0; for ($i = 0; $i < 3; $i++) if ($scale[$i] > $scale_max) $scale_max = $scale[$i]; if ($maximize_scale) { print($object + " scale normalized - scale by " + $scale[0] + " " + $scale[1] + " " + $scale[2] + " inside SL to get original shape\n" ;} else { for ($i = 0; $i < 3; $i++) $scale[$i] = $scale_max; } scale("-relative", 1/$scale[0], 1/$scale[1], 1/$scale[2], $object_copy); // position it in unit cube $bounding_min = getAttr($object_copy + ".boundingBoxMin" ;$bounding_max = getAttr($object_copy + ".boundingBoxMax" ;float $center[3]; for ($i = 0; $i < 3; $i++) $center[$i] = ($bounding_min[$i] + $bounding_max[$i]) / 2.0; move("-relative", 0.5 - $center[0], 0.5 - $center[1], 0.5 - $center[2], $object_copy); // // nurbs surfaces can be adjusted to ensure correct orientation // if ($fix_orientation) { string $shape = llFirst(listRelatives("-shapes", $object_copy)); if ((nodeType($object_copy) == "nurbsSurface" ||(($shape != "" && (nodeType($shape) == "nurbsSurface" )){ // try to determine the "north pole"; float $pole[] = pointOnSurface("-turnOnPercentage", 1, "-parameterU", 0.5, "-parameterV", 0, $object_copy); float $total_distance = 0; float $v; for ($v = 0; $v <= 1; $v += 0.1) { float $point[] = pointOnSurface("-turnOnPercentage", 1, "-parameterU", $v, "-parameterV", 0, $object_copy); float $distance = 0; int $i; for ($i = 0; $i < 3; $i++) $distance += pow($pole[$i] - $point[$i], 2); $distance = sqrt($distance); $total_distance += $distance; } if ($total_distance > 0.1) // the points don't converge on the pole - swap { print("swapping UVs to orient poles for " + $object + "\n" ;reverseSurface("-direction", 3, $object_copy); } // now try to ensure the normal points "out" // note: this could easily fail - but there's no better way (i think.) float $total_orientation = 0; float $u; for ($u = 0; $u <= 1; $u += 0.1) for ($v = 0; $v <= 1; $v += 0.1) { float $point[] = pointOnSurface("-turnOnPercentage", 1, "-parameterU", $u, "-parameterV", $v, $object_copy); float $normal[] = pointOnSurface("-normal", "-turnOnPercentage", 1, "-parameterU", $u, "-parameterV", $v, $object_copy); // check the orientation of the normal w/r/t the direction from center float $center_dir[]; for ($i = 0; $i < 3; $i++) $center_dir[$i] = $point[$i] - 0.5; float $orientation = 0; // dot product for ($i = 0; $i < 3; $i++) $orientation += $center_dir[$i] * $normal[$i]; $total_orientation += $orientation; } if ($total_orientation > 0) // need to invert { print("reversing V for " + $object + "\n" ;reverseSurface("-direction", 1, $object_copy); } } else { warning("cannot fix orientation on non-nurbs object: " + $object); } } // create temporary shading network string $sampler_info = createNode("samplerInfo" ;print("exporting sculpt map for " + $object + " into file " + $file_name + "\n" ;// bake sculpt texture string $fileNodes[] = convertSolidTx("-fileImageName", $file_name, "-fileFormat", $file_format, "-force", 1, "-resolutionX", $resolution_x, "-resolutionY", $resolution_y, $sampler_info + ".pointWorld", $object_copy); delete($fileNodes); // we don't want 'em. why do you make 'em? delete($sampler_info); delete($object_copy); } global proc int llSculptEditorCallback() { string $objects[] = ls("-sl" ;if (size($objects) == 0) { warning("please select objects to export" ;return 0; } string $filename = textFieldButtonGrp("-query", "-fileName", "llSculptEditorFilename" ;int $resolution_x = intSliderGrp("-query", "-value", "llSculptEditorResolutionX" ;int $resolution_y = intSliderGrp("-query", "-value", "llSculptEditorResolutionY" ;int $fix_orientation = checkBoxGrp("-query", "-value1", "llSculptEditorFixOrientation" ;int $maximize_scale = checkBoxGrp("-query", "-value1", "llSculptEditorMaximizeScale" ;// get filetype string $file_type; string $file_base; string $file_extension; string $tokens[]; tokenize($filename, ".", $tokens); if (size($tokens) == 1) // no extension, default to bmp { $file_base = $filename; $file_type = "bmp"; $file_extension = "bmp"; } else { $file_extension = $tokens[size($tokens) - 1]; int $i; for ($i = 0; $i < size($tokens) - 1; $i++) { $file_base += $tokens[$i]; if ($i != size($tokens) - 2) $file_base += "."; } if ($file_extension == "bmp" ![]() $file_type = "bmp"; else if (($file_extension == "jpg" || ($file_extension == "jpeg" )$file_type = "jpg"; else if (($file_extension == "tif" || ($file_extension == "tiff" )$file_type = "tif"; else if ($file_extension == "tga" ![]() $file_type = "tga"; else { warning("unknown image type (" + $file_extension + " . switching to bmp" ;$file_type = "bmp"; $file_extension = "bmp"; } } string $object; for ($object in $objects) { string $this_filename = $file_base; if (size($objects) > 1) $this_filename += "-" + $object; $this_filename += "." + $file_extension; llSculptExport($object, $this_filename, $file_type, $resolution_x, $resolution_y, $maximize_scale, $fix_orientation); } select($objects); return 1; } global proc llSculptEditorSetFilenameCallback(string $filename, string $filetype) { textFieldButtonGrp("-edit", "-fileName", $filename, "llSculptEditorFilename" ;} global proc llSculptEditorBrowseCallback() { fileBrowser("llSculptEditorSetFilenameCallback", "Export", "image", 1); } global proc llSculptEditor() { string $commandName = "llSculptExport"; string $layout = getOptionBox(); setParent $layout; setOptionBoxCommandName($commandName); setUITemplate -pushTemplate DefaultTemplate; scrollLayout; tabLayout -tabsVisible 0 -scrollable 1; string $parent = `columnLayout -adjustableColumn 1`; separator -height 10 -style "none"; textFieldButtonGrp -label "Filename" -fileName "sculpt.bmp" -buttonLabel "Browse" -buttonCommand "llSculptEditorBrowseCallback" llSculptEditorFilename; intSliderGrp -field on -label "X Resolution" -minValue 1 -maxValue 512 -fieldMinValue 1 -fieldMaxValue 4096 -value 64 llSculptEditorResolutionX; intSliderGrp -field on -label "Y Resolution" -minValue 1 -maxValue 512 -fieldMinValue 1 -fieldMaxValue 4096 -value 64 llSculptEditorResolutionY; checkBoxGrp -label "" -label1 "Maximize scale" -numberOfCheckBoxes 1 -value1 off llSculptEditorMaximizeScale; checkBoxGrp -label "" -label1 "Correct orientation" -numberOfCheckBoxes 1 -value1 on llSculptEditorFixOrientation; setUITemplate -popTemplate; string $applyBtn = getOptionBoxApplyBtn(); button -edit -label "Export" -command "llSculptEditorCallback" $applyBtn; string $applyAndCloseBtn = getOptionBoxApplyAndCloseBtn(); button -edit -label "Export and Close" -command "llSculptEditorCallback" $applyAndCloseBtn; setOptionBoxTitle("Export Sculpt Texture" ;setOptionBoxHelpTag( "ConvertFileText" ); showOptionBox(); } // llSculptEditor; This is the one posted on the blog for Maya so far _____________________
|
|
Max Duesenburg
Registered User
Join date: 13 Sep 2006
Posts: 33
|
05-11-2007 17:44
Is Blender not Open Source? If someone has the algorithm, or better yet, a library for these new export map thingies, there are a lot of people who can splice it in. Someone shuld be promoting this idea to the Blender people. I have a working script now to export from Blender - Needs more work before I release it but it will export any mesh that resolves to 32 x 32 network of vertices - i.e. you can create it in ANY way you wish. Subsurf, NURBS, SPIN, Extrude etc. so long as you end up with a 32x32 mesh. After trying a sculptie on the Beta grid I also created an importer to take a sculpt texture and create a mesgh in Blender, to check that I'd got it right. At present using a 64x64 pixel image as suggested just doesn't cut it. The compression screws the co-ordinates really badly. Trying a 256x256 image makes a much better attempt. What would be nice would be to have 32x32 pixel images stored uncompressed for this purpose. Anyhow, watch this space - Once I have the thing user friendly enough to let other people use it I'll release it Max |
|
Max Duesenburg
Registered User
Join date: 13 Sep 2006
Posts: 33
|
05-11-2007 17:52
However, since there's no advantage to using textures larger than 64x64, they should load relatively quickly. Actually because of image compression there is a huge advantage to using larger textures than 64x64. At a size of 64x64 I get major inaccuracies in vertex positions - Bump it to 256x256 and it's a lot more accurate. Seems that in this case compressing the data is counter productive - it just encourages people to use larger textures to improve accuracy. A better solution would be for SL to store 32x32 images uncompressed. That way a 3k file would provide 100% accuracy (within the 8 bit limitation per co-ordinate of course) Max |
|
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
|
05-11-2007 18:22
In fact 64 is actually necessary, for a rather annoying reason: the position of the south pole. If there are 32 line segments between the north and south poles (and we want this so that LOD changes nicely, currently when it switches from 16 to 32 edges, none of the old vertices move, we only add new ones), then we actually need 33 vertex positions. A 64x64 texture is sampled at y positions of 0, 2, 4, 6, ..., 60, 62, and 63. There is no pixel 64, which you would otherwise want to use.
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG |
|
RobbyRacoon Olmstead
Red warrior is hungry!
Join date: 20 Sep 2006
Posts: 1,821
|
05-11-2007 18:30
I have a working script now to export from Blender - Needs more work before I release it but it will export any mesh that resolves to 32 x 32 network of vertices - i.e. you can create it in ANY way you wish. Subsurf, NURBS, SPIN, Extrude etc. so long as you end up with a 32x32 mesh. After trying a sculptie on the Beta grid I also created an importer to take a sculpt texture and create a mesgh in Blender, to check that I'd got it right. At present using a 64x64 pixel image as suggested just doesn't cut it. The compression screws the co-ordinates really badly. Trying a 256x256 image makes a much better attempt. What would be nice would be to have 32x32 pixel images stored uncompressed for this purpose. Anyhow, watch this space - Once I have the thing user friendly enough to let other people use it I'll release it Max Where is this famous script? You are gonna be several people's bestest bestest buddy if it works as advertised ![]() . _____________________
|
|
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
|
05-11-2007 20:12
A good question.. I did quite a few Experiments, too...
What kind of UV coords does the Blender Exporter need ? Or does it a straightforward Conversion of Vertices only ? (that was the first thing i tried) At the Moment, i export as .obj and run it trough a quite complicated Program, still needing crazy UV Maps like the Attached one. ... but the Vertices get resampled ... ![]() |
|
Max Duesenburg
Registered User
Join date: 13 Sep 2006
Posts: 33
|
05-11-2007 22:00
Where is this famous script? You are gonna be several people's bestest bestest buddy if it works as advertised ![]() . As I said, it's not ready for release as yet ![]() It needs a front end and I'd like to create a UV map in there as well as the co-ordinate map, but as a proof of concept it works pretty well so far. I'll be testing and adding to it (and neatening up the code) over the next few days so hopefully I'll have something for public consumption soon. Max |
|
Max Duesenburg
Registered User
Join date: 13 Sep 2006
Posts: 33
|
05-11-2007 22:02
In fact 64 is actually necessary, for a rather annoying reason: the position of the south pole. If there are 32 line segments between the north and south poles (and we want this so that LOD changes nicely, currently when it switches from 16 to 32 edges, none of the old vertices move, we only add new ones), then we actually need 33 vertex positions. A 64x64 texture is sampled at y positions of 0, 2, 4, 6, ..., 60, 62, and 63. There is no pixel 64, which you would otherwise want to use. If there were 32 line segments then this would be true - However, according to the FAQ it's 32 vertices (i.e. 31 line segments/edges/faces) - I'm assuming the Wiki has it right on this ? Max |
|
Max Duesenburg
Registered User
Join date: 13 Sep 2006
Posts: 33
|
05-11-2007 22:06
A good question.. I did quite a few Experiments, too... What kind of UV coords does the Blender Exporter need ? Or does it a straightforward Conversion of Vertices only ? (that was the first thing i tried) At the Moment, i export as .obj and run it trough a quite complicated Program, still needing crazy UV Maps like the Attached one. ... but the Vertices get resampled ... ![]() Well, the way I went about it was to derive the topology of the object from the vertex and face data (sorta like how you find edge loops) and create an image directly within Blender from the vertices (once I had them in the right order) I haven't as yet created a UV map (so you can texture within blender in a way that will match SL) but I'm looking into it. Max |
|
Wilhelm Neumann
Runs with Crayons
Join date: 20 Apr 2006
Posts: 2,204
|
05-12-2007 15:40
As I said, it's not ready for release as yet ![]() It needs a front end and I'd like to create a UV map in there as well as the co-ordinate map, but as a proof of concept it works pretty well so far. I'll be testing and adding to it (and neatening up the code) over the next few days so hopefully I'll have something for public consumption soon. Max OO this is very exciting Max I have not used 3d programs and wanted to use blender to learn it all and play on the beta grid etc before I decide what I am gonna do with all this sculptie stuff. Its kinda hard to buy software and/or know what people are even speaking about without knowing anything ^^ Thanks for the hard work ![]() |
|
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
|
05-12-2007 17:24
If there were 32 line segments then this would be true - However, according to the FAQ it's 32 vertices (i.e. 31 line segments/edges/faces) - I'm assuming the Wiki has it right on this ? _____________________
-Seifert Surface
2G!tGLf 2nLt9cG |
|
Max Duesenburg
Registered User
Join date: 13 Sep 2006
Posts: 33
|
05-12-2007 20:20
I count 32 segments. You can tell with a wireframe view (ctrl-shift-R) and some careful counting. Around the equator of course, both the number of vertices and the number of line segments is 32. On a closed shape, yes. If it's closed it's 32 verts, 32 edges. However, the announcement of the different closed and open options for sculpties have thrown a rather large spanner in my works More a UI problem than anything.In order to know the direction the user wants the script to unwrap the mesh in I need to know a vertex and a direction - and as yet I haven't figured out a good way to do this in Blender. At preset I'm rewriting to take into account the possibility of different open/closed combinations and I'll probably release an alpha test copy of the script. The major problem will be that I have no way of ensuring that the texture will be the right way around, so it may need to be flipped/mirrored to get the right effect. Watch this space. Max |
|
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
|
05-12-2007 20:55
... Watch this space. Max You can bet on it, i will watch If your Program works like this, it will be a lot easier to use than mine. You must have really 1337 Math Skillz. Well, we have a few Days left until our beloved Sculpties are on the Main Grid, so there is no need to rush. ![]() |
|
BamBam Sachertorte
floral engineer
Join date: 12 Jul 2005
Posts: 228
|
05-12-2007 22:59
I thought about this last night and had to wonder; since the shape of a sculpty prim is determined by the texture, does that mean the shape doesn't actually render correctly until the texture loads completely? If so, constantly switching between textures that all have to load independently would be quite ugly. |
|
BamBam Sachertorte
floral engineer
Join date: 12 Jul 2005
Posts: 228
|
05-12-2007 23:16
Actually because of image compression there is a huge advantage to using larger textures than 64x64. At a size of 64x64 I get major inaccuracies in vertex positions - Bump it to 256x256 and it's a lot more accurate. Seems that in this case compressing the data is counter productive - it just encourages people to use larger textures to improve accuracy. A better solution would be for SL to store 32x32 images uncompressed. That way a 3k file would provide 100% accuracy (within the 8 bit limitation per co-ordinate of course) Max |