Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

RGB displacement map from Blender?

BamBam Sachertorte
floral engineer
Join date: 12 Jul 2005
Posts: 228
05-13-2007 14:03
From: BamBam Sachertorte
I did some experiments with lossless compression of a 32x32 sculptie map and got much less than 3k file size, more like 1.2k to 1.4k. LL should just automatically use lossless JPEG-2000 compression on all images that are 32x32 or smaller.
Actually, a JPEG-2000 80% quality, lossy compressed 256x256 sculptie map is about the same size as a 32x32 lossless compressed sculptie map (umm, with a pretty small data set). So rather than concern ourselves with lossless sculptie maps maybe we should all use 256x256 instead of 64x64. I guess displacement maps compress well under JPEG-2000.
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
05-13-2007 16:31
It's not bad, but still not perfect. I did some experiments, trying to get a perfect cube as a sculpty. Even with a 1024x1024 texture it isn't quite perfect, you can see some errors on the edges. 64x64 lossless, or near lossless would do it though.
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Max Duesenburg
Registered User
Join date: 13 Sep 2006
Posts: 33
For the brave amongst you...
05-14-2007 02:49
OK, I finally figured out a rather kludgy way to get this thing working. It's far from perfect but ready to see how it works outside my own computer :)

OK, a few basic guidelines...

Model in any way you want, so long as you end up with a 32x32 grid of quads, closed or open, it shouldn't matter

Before you run the script...

Make sure all your normals are facing outward

Go into edit mode and select three vertices while viewing from the outside of your object.

The first is the bottom left hand corner of your 32x32 grid
The second is the bottom right corner of the same face
The third is the top right corner of the same face
(You should end up with a backwards L shape)

Go into object mode.

Make sure your object is selected

Run the script.

Troubleshooting

If the script crashes first check if you have a 32x32 grid of vertices (1024 points)
Try flipping the normals

When the script finishes open a UV Editor window and pick the 'SL Sculpt Texture' image from the pop up menu at the bottom. You can then save it in a format of your choosing.

Note that the image is 32x32 - You can scale it to whatver size you want in a paint program such as the Gimp (don't use interpolation for best results)

Any problems, post them in this thread so we can all see them :)

Remember this is a very early version so expect problems.

Also note that SL will at present close the left and right sides of your texture and cap the top and bottom, which can lead to some strange behaviour, and makes texturing a complete mess in many cases. G2 Sculpties should help that a lot.

BTW - SL seems to rotate the object once it comes in - Again that might change with G2

And finally, your object will be distorted in SL - It gets normalized to increase accuracy - Hopefully you can scale it to the right dimensions by eye for the moment. - Once I put a GUI on this thing i should be able to at least tell you the scaling factors ;)

Max

CODE

import Blender

# Globals

imageName = 'SL Sculpt Texture'
gridSize = 32
imageSize = 32

# Given a vertex and a face, return the next vertex of the face
def nextVert(f,v):
fVerts=list(f.verts)
n = fVerts.index(v)
n=n+1
if n==4:n=0
return fVerts[n]

# Given a vertex and a face, return the previous vertex of the face
def prevVert(f,v):
fVerts=list(f.verts)
n = fVerts.index(v)
n=n-1
if n==-1:n=3
return fVerts[n]

# Given a vertex and a face, return the next two vertices of the face
def next2Verts(f,v):
v1 = nextVert(f,v)
v2 = nextVert(f,v1)
return (v1,v2)

# Given a vertex and a face, return the previous two vertices of the face
def prev2Verts(f,v):
v1 = prevVert(f,v)
v2 = prevVert(f,v1)
return (v1,v2)

# Given a vertex and an edge, return the face which shares that edge or return False
def nextFace(f,e):
for face in faces:
if face != f and e[0] in face.verts and e[1] in face.verts:
return face
return False

scn = Blender.Scene.GetCurrent()
obj = scn.getActiveObject()
data = obj.getData(mesh = True)
verts = data.verts
faces = data.faces

# Set up a dictionary with key = vert and data = faces including vert
vDict = dict([(vert,[]) for vert in verts])
for face in faces:
for vert in face.verts:
vDict[vert].append(face)

# Grab the selected vertices - Should be three of them
start = []
for vert in verts:
if vert.sel:
start.append(vert)

# Find all faces that contains at least one of the selected vertices
fList = []
for i in range(3):
fList.extend(vDict[start])

# Find which one contains all three
for face in fList:
if start[0] in face.verts and start[1] in face.verts and start [2] in face.verts:
f = face
break

# Need to get the first vertex in order now
for v0 in f.verts:
if not (v0 in start):
v=nextVert(f,v0)
break

# Grab the vertex data in order
grid = []

# Need to deal with open edges here

for y in range (gridSize): # Number of vertices we're looking for in Y direction
g = []
g.append(v.co)

# Grab the next face in Y direction - If none need to grab bottom line
e0 = prev2Verts(f,v)
v0 = e0[0]
f0 = nextFace(f,e0)
for x in range(gridSize-1): # Number of vertices we're looking for in X direction
if f:
e = next2Verts(f,v)
v=e[0]
f = nextFace(f,e)
g.append(v.co)
grid.append(g)
if f0:
f = f0
v = v0
else:
# Grab the bottom line
v = v0
# Need to get the right face here!
f = nextFace(False,e0)
g = []
g.append(v.co)
for x in range(gridSize):
if f:
e = prev2Verts(f,v)
v=e[0]
f = nextFace(f,e)
g.append(v.co)
grid.append(g)
break

# Find the max and min values of all co-ords in grid
vMin = [grid[0][0][0], grid[0][0][1], grid[0][0][2]]
vMax = [grid[0][0][0], grid[0][0][1], grid[0][0][2]]

for line in grid:
for vert in line:
for i in range (3):
if vert > vMax:
vMax = vert
if vert < vMin:
vMin = vert

# Find the mid-points for normalisation
vMid = [(vMin[0]+vMax[0])/2,(vMin[1]+vMax[1])/2,(vMin[2]+vMax[2])/2]

# Create an image to work with
try:
sculptImage = Blender.Image.Get(imageName)
except NameError:
sculptImage = Blender.Image.New(imageName, imageSize, imageSize, 24)

# Normalize the data and put it into the image
for i in range (gridSize):
for j in range (gridSize):
parm = []
for k in range(3):
if vMax[k] == 0 and vMin[k] == 0:
parm.append(0.5)
else:
parm.append(0.5+(grid[j][k]-vMid[k])/((vMax[k]-vMid[k])*2))
parm.append(1)
sculptImage.setPixelF(imageSize - 1 - j, i,tuple(parm))



And finally a little taster for what you can do - A very simple one prim boat, created using subsurfaces in Blender
Domino Marama
Domino Designs
Join date: 22 Sep 2006
Posts: 1,126
05-15-2007 02:26
From: Max Duesenburg
Hopefully you can scale it to the right dimensions by eye for the moment.


Or go to object mode in Blender and press "n" to display the numeric transform dialog. This shows the current size of the object.
Max Duesenburg
Registered User
Join date: 13 Sep 2006
Posts: 33
05-15-2007 02:32
From: Domino Marama
Or go to object mode in Blender and press "n" to display the numeric transform dialog. This shows the current size of the object.


Sadly that won't work with the script. It uses the mesh co-ordinates (which are independent of object size) and modifies them before outputting to the texture (normalizes them to a 1x1 Blender Unit object with its origin at [0,0,0].

Max
Hikaru Yamamoto
Oldbie
Join date: 10 Mar 2003
Posts: 895
05-17-2007 14:52
:confused: as someone who really has no idea how to use blender or any 3d program, or how to run a script. could you plz help explain to me how to do this?
_____________________
http://slurl.com/secondlife/Europa/152/33/69/

Its hippos all the way down...
Shack Dougall
self become: Object new
Join date: 9 Aug 2004
Posts: 1,028
We need lossless 64x64
05-17-2007 21:41
From: Seifert Surface
I did some experiments, trying to get a perfect cube as a sculpty. Even with a 1024x1024 texture it isn't quite perfect, you can see some errors on the edges. 64x64 lossless, or near lossless would do it though.


I've been struggling with this issue too. For a while now, I've been using 64x64 textures and getting very disappointing results. I just started trying larger textures and the difference is amazing for the kinds of things I want to build.

256x256 seems a decent compromise. It gives me pretty good results, but not perfect. Still, it seems like a lossless solution at a lower resolution would be preferable.

I understand the Linden argument that this is meant to make organic shapes, but the fact is that organic shapes need precision too, especially when you're faced with the 10m limit on prim size.

If you want to make something organic that is larger than 10m, then you need precision on the edges so that two or more prims will match cleanly when you put them together. This is especially problematic with lighting which tends to highlight any differences, making a huge ugly seam. I've tried making them fullbright and that helps, but this isn't an acceptable solution.

I think maybe we should make lossless 64x64 a formal proposal for voting. Maybe that is one way that we could raise the issue in a constructive way and bring more Linden attention to it.
Al Sonic
Builder Furiend
Join date: 13 Jun 2006
Posts: 162
Qarl knows.
05-18-2007 09:22
From: Shack Dougall
I think maybe we should make lossless 64x64 a formal proposal for voting. Maybe that is one way that we could raise the issue in a constructive way and bring more Linden attention to it.

Do so if you feel you still must, but Qarl has already said multiple times that he's thinking over the matter. In fact, just search that page for all the times he's said "16bit"; he's already a step ahead of ya on trying to figure out how to get them just right.

Rather than start posting around about what you need, I think you should start building to demonstrate that need, and then discuss your results at Sculpted_Prims_Beta_Discussion.
Shack Dougall
self become: Object new
Join date: 9 Aug 2004
Posts: 1,028
05-18-2007 09:38
From: Al Sonic
Do so if you feel you still must, but Qarl has already said multiple times that he's thinking over the matter.


Yes, I know. I guess I just don't believe it. LL doesn't have a good track record of following through on issues like this. Qarl has a golden opportunity to prove us old timers wrong.
Qarl Linden
Linden Lab Employee
Join date: 13 Feb 2007
Posts: 24
05-18-2007 17:48
ye of little faith...
Shack Dougall
self become: Object new
Join date: 9 Aug 2004
Posts: 1,028
05-18-2007 19:50
From: Qarl Linden
ye of little faith...


Yep, guilty as charged, LOL :D

But I do appreciate what you're doing Qarl!

Just anxious to see it come together before priorities shift and resources get thrown in a different direction.

:)
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
05-18-2007 23:23
If you really care about compression... well, AFAIK its done client side.
So you can try to hack the Open Source Client for perfect Sculpty upload or
(much simpler) modify the IA_ImageTool (comes with LibSL).
_____________________
2k Suisei
Registered User
Join date: 9 Nov 2006
Posts: 2,150
05-18-2007 23:50
From: Cindy Crabgrass
If you really care about compression... well, AFAIK its done client side.
So you can try to hack the Open Source Client for perfect Sculpty upload or
(much simpler) modify the IA_ImageTool (comes with LibSL).


:rolleyes:

Trust you. Always making things complicated.

;)
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
05-19-2007 00:40
From: 2k Suisei
:rolleyes:

Trust you. Always making things complicated.

;)


If you want a job done right, you have to do it yourself. :D
_____________________
2k Suisei
Registered User
Join date: 9 Nov 2006
Posts: 2,150
05-19-2007 02:38
From: Cindy Crabgrass
If you want a job done right, you have to do it yourself. :D


Pfft!

:D
Max Duesenburg
Registered User
Join date: 13 Sep 2006
Posts: 33
05-19-2007 03:00
My two pennorth...

Forget about 16 bit - its unnecessary. On a 10m prim 8 bit gives an accuracy of 4cm. In the vast majority of cases details that small are far better done in the texturing, especially with a smooth shaded model (bump mapping anyone ?)

You also have the problem of finding software that will cope with it. Blender certainly doesn't (24 bit only at the moment, 32 bit on the way). If you really need more accuracy, why not use the alpha channel to add 2 bits to each channel giving an accuracy of 1cm on a 10m prim and leaving room for a couple of flags for future expansion ?

Really the problem is in the compression. There's really no need that I can see for a texture larger than 32x32 to hold the necessary data and either uncompressed or lossless compression should give the 100% accuracy necessary to build objects with multiple 'seamless' sculpties without making any major difference to the load on the servers or clients.

Max
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
05-19-2007 03:15
My biggest Problem is the Topology of the Sculpty.
Its impossible to convert random Meshes.
I imagine it like 2 D Shapes, extruded along a Path between 2 Poles.
We can do a lot with this, but not everything.
I would prefer uploading .obj Files of limited Size.

Dont tell me this is impossible in SL, this Nonsense
doesnt get true only because its repeated many times.
_____________________
Max Duesenburg
Registered User
Join date: 13 Sep 2006
Posts: 33
05-19-2007 04:44
From: Cindy Crabgrass
My biggest Problem is the Topology of the Sculpty.
Its impossible to convert random Meshes.
I imagine it like 2 D Shapes, extruded along a Path between 2 Poles.
We can do a lot with this, but not everything.
I would prefer uploading .obj Files of limited Size.

Dont tell me this is impossible in SL, this Nonsense
doesnt get true only because its repeated many times.


Impossible to convert random meshes ?

Errr, that's exactly what my script for Blender does (see above)

I'm not 100% sure what you mean by random. If you mean random vertex placement then it does that. If you mean random vertex order, it also does that. Blender (like .obj files) stores vertices and faces with no particular order (normally the order of creation) but it is quite possible to derive the topology of the surface and put the vertices in order. Once that's done it's simple to convert it to an image suitable for SL.

I know some of the other scripts around seem to be using a spherical projection method to create the image. While very useful in certain cases this is fraught with problems (concave surfaces, evenly distributed points etc.) and I've got a script for Blender that does something similar myself in development.

Lofting (2D Shapes, extruded along a Path) is quite possible in Blender, but is only one modelling method you can use. The above script will accept ANY 32x32 mesh. How you create it is irrelevant. How well it will render in SL is another matter.

As for uploading .obj files, no it wouldn't be impossible for LL to add this facility, but it would increase the load on the servers and clients quite a bit. On the other hand, writing a converter for .obj format into SL Sculpt Texture format wouldn't be too difficult. Actually you could import an obj into Blender and use my script on it for that matter (so long as the mesh is 32x32 of course)

Max
2k Suisei
Registered User
Join date: 9 Nov 2006
Posts: 2,150
05-19-2007 04:52
From: Cindy Crabgrass

I would prefer uploading .obj Files of limited Size.

Dont tell me this is impossible in SL, this Nonsense
doesnt get true only because its repeated many times.


I agree. I'd also prefer the ability to upload objects. I'm happy that sculpties are coming, yet in some ways I'm sad because it shows that Linden Lab are never going to give us "normal" methods for creating content. Why do they have to be so bloody awkward? :)

I know LOD is an issue with meshes. But I'd even put up with objects not being drawn at a distance if it meant having proper modeling tools. Or Linden Lab could just give us the option to set whether an object should continue to be drawn when at a considerable distance from the camera. Lots of objects are located inside buildings and so it wouldn't matter if they weren't drawn at a distance, because they'd hidden by the walls of the building.

Another idea is that we could store models on our own servers. Clients/viewers could then download them from our servers instead of from the LL asset server. This is similar to how Active Worlds works. It could be done by placing a tag and URL inside a prim's comment field. The client would then download the model and use the marker prim's orientation for it.
Cindy Crabgrass
Crashed to Desktop
Join date: 9 Sep 2006
Posts: 158
05-19-2007 06:34
From: Max Duesenburg
Impossible to convert random meshes ?

Errr, that's exactly what my script for Blender does (see above)

...

Max


I tried running your Script in Blender 2.44, using an open Cylinder,
selected 3 vertices on 1 face (order : bottom left - right - up)
and got 'list index out of range' in line 147.

An Example for something impossible would be : a cube, drill 3 holes
through it in Z Direction. Result : Multiple Surfaces that can not be connected
without ugly Results.
IMHO the Limit is a Torus, if you build it along a Path and have the Poles in the same Place.
But how do you Sculpt a 'B' shape ?
The Problem is : everybody wants to use Sculpties, without learning how they work,
thats why .obj import would make (Second) Life a lot easier.
_____________________
Max Duesenburg
Registered User
Join date: 13 Sep 2006
Posts: 33
05-19-2007 10:06
From: Cindy Crabgrass
I tried running your Script in Blender 2.44, using an open Cylinder,
selected 3 vertices on 1 face (order : bottom left - right - up)
and got 'list index out of range' in line 147.

An Example for something impossible would be : a cube, drill 3 holes
through it in Z Direction. Result : Multiple Surfaces that can not be connected
without ugly Results.
IMHO the Limit is a Torus, if you build it along a Path and have the Poles in the same Place.
But how do you Sculpt a 'B' shape ?
The Problem is : everybody wants to use Sculpties, without learning how they work,
thats why .obj import would make (Second) Life a lot easier.


With an open cylinder it needs to be 32x32 vertices and you need to select a face on the bottom edge. The first point (bottom left) is used as the bottom left of the grid. The next point (bottom right) defines the x-direction and the third (top right) defines the y-direction. (With closed surfaces this isn't so critical but it will be when we get open and semi open surfaces)

As to multiple surfaces - you need multiple sculpties - sculpties (at present) can really only support single closed surfaces. The next generation should support open surfaces too according to the wiki.

It should be possible (though awkward) to sculpt a 'B' shape though. It just takes some thought and planning. If you think of it as 'lofting' or extruding along a B-shaped path. You would get some co-planar polygons where the middle part of the 'B' crosses itself but you could get around this by carefully placing the points of the bottom loop on the side of the top loop. This would be topologically equivalent to a closed cylinder/sphere.

An 'A' would be more difficult (I can't see a way offhand to do it without co planar polygons) but clever texturing (making the co-planar polygons transparent) might make it possible.

Sculpties are very limited, especially at present, but we have to expect that - they'll develop in time into something pretty powerful I hope, and in the meantime we'll just have to get around their perceived limitations :)

And yes, people want to be able to make sculpties without any knowledge of how they work. However, I don't see how obj import would help in that. If you can create your own stuff in a 3-D modelling package, exporting it to a texture using a script should be trivial for you, and understanding how they work should also be trivial.

Max
Qarl Linden
Linden Lab Employee
Join date: 13 Feb 2007
Posts: 24
05-19-2007 10:27
From: 2k Suisei
It could be done by placing a tag and URL inside a prim's comment field. The client would then download the model and use the marker prim's orientation for it.


or better yet - you could ask LL for an "extra prim parameter" allocation. we've never given them out before - but i imagine we could be convinced. :)


K.
2k Suisei
Registered User
Join date: 9 Nov 2006
Posts: 2,150
05-19-2007 11:53
From: Qarl Linden
or better yet - you could ask LL for an "extra prim parameter" allocation. we've never given them out before - but i imagine we could be convinced. :)


K.


But then there's the problem of getting the new model viewing code added to the official client.

Umm...

Perhaps with a little financial incentive, we could persuade a real smart and charming Linden to create and add the feature for us.

;)
Photon Pink
Registered User
Join date: 13 Oct 2006
Posts: 1
05-21-2007 01:33
From: Max Duesenburg
There's really no need that I can see for a texture larger than 32x32 to hold the necessary data and either


This is what i thought too until i looked closer that the sculpt sphere mesh. tho its is 32x32 faces, because the verticle does not wrap around like the horozontal, you have thirty THREE verts in each verticle row not 32, so 32x32 image woudl not have a pixel for each vert in a sculptd sphere. (it woudl work in a torus because both edges wrap around)

So how does this work now with 64x64 images? Apparently every other row is sampled plus also the last row, which causes a bit of complication baking a proper texture in Max with the method people hav ebeen using, since that last row has to be squished in there.
hurly Burleigh
Registered User
Join date: 19 Sep 2005
Posts: 167
A plea from all us non techie's
05-21-2007 03:22
Please can someone do a step by step walk through of how to create one of these textures using blender. i appreciate all the hard work people like Max have gone to creating an importer but like many others i dont have a clue what to do with the script.

If someone could do a button by button walk through then it would definately add to the content in SL and benefit everyone.

Please avoid all the tech language too as it only confuses us lesser mortals.

Thanks in hope
1 2 3