same UV coordinates giving different results in differentrenderers 2004-02-12 - By Thomas Williams
Back
>>Lucas wrote: > While doing that 3dsprite class a while ago, I had to carefully set uv > coordinates on the plane, so that each texel would exaclty come down to > one pixel.. Now this looks fine for me in opengl, but in directx it > looks slightly different (wrong), and in software too, but slightly > different in a different way... both have double pixels here and there, > exactly what you'd expect with slightly off uv coordinates.. > > I'm really afraid that this in the end boils down to that each driver > has its own mind, but when examining camera.overlay's, I see that > they're pixelperfect on all renderers.. > > so intel at least was able to set its uv's in such a way that it works > reliably, at least on my card+driver. > > Has anyone already investigated this, and knows what renderers work some > magic on texel centers, and how to adjust for this, so it looks good > everywhere? > > Bye, Lucas
Lucas-
I doubt this will help you at all, but it might help someone. I recently made a Parent script that creates a grid mesh. It also includes a handler ("UVWtile()") that allows the UVWs to be tiled and/or mirrored. Perhaps the UVW tiling and mirroring will be a nice addition to someone's code library. Not tested on various renderers. Apologies to you if this is totally useless.
Thomas
============================================================================ =======================
-- MESHCREATOR - CLASS -- Desc: Create grid meshes and provides methods for controling the mesh. -- RESPONSIBILITIES: -- - Create the mesh grid. Rows will be arrayed along X, columns will be arrayed along Y -- - Assign it UVWs according to parameters #tiling, #mirror -- - Create Row and Column Controllers. This is an array of Transforms that lie at the base of -- each row and column. All the verts in a row or column are children of them and -- transforming a row controller transforms all its verts accordingly. -- METHODS: -- Grid() - creates a grid mesh -- centerPivot() - centers the pivot in the middle of the object by finding the center point and the -- vector difference and then moving all point that amount. -- destroy3D() - deletes all the model and resources and shaders created previously bu this script -- UVWtile(tileU,tileV,bMirrorU,bMirrorV) - resets the UVW coords to tile or mirror according -- to the params. -- ChangeShader() - allows for propties to be set in the shader. -- params: #property - the name of the shader property eg #emissive -- #value - the value associated with the shader property.
global scene,gGradient global gMeshCreatorList -- List of all the objects of the Parent script "meshGenerator"
property pName property pRows,pColumns -- the number of rows and columns property pSpacing -- the spacing between rows and columns. property pModel,pModRes,pShader -- the model created property pTextureCoordinateList -- list [of all the UV values] for every vertex. same length -- as the vertexlist. property pAnimController -- reference to a child object that will animate this model. property pIndex -- --************************************************************************** *********** --**************** CONSTRUCTOR **************************************************** --************************************************************************** *********** on new me, mName, mRows, mColumns,mIndex pIndex = mIndex pName = mName pRows = mRows pColumns = mColumns pSpacing = 45.0/pColumns -- Delete any existing meshes created previously me.destroy3d(pName) -- Create the grid mesh pModel = me.grid( pName&"_"&pIndex, pColumns, pRows, pSpacing) pModRes = pModel.resource pShader = pModel.shader pt1= pTextureCoordinateList.duplicate() --pModel.transform.identity() -- Center the pivot in the center of the mesh me.centerPivot() pModel.visibility = #both pModel.transform.identity() -- UVW - Set the TextureCoordinate tiling tileU = 1 tileV = 1 bMirrorU = 1 bMirrorV = 0 me.UVWtile (tileU,tileV,bMirrorU,bMirrorV) -- Analyze the textureCoords pt2 = pTextureCoordinateList.duplicate() --me.analyzetextureCoordinateList(pt1,pt2) return me end --************************************************************************** *********** --**************** analyzetextureCoordinateList *********************************** --************************************************************************** *********** -- Desc: - Outputs the texture coordinates after they have been mtiled and mirrored.
on analyzetextureCoordinateList (me, pt1, pt2) repeat with t = 1 to pt2.count -- put t,pt1[t],pt2[t] end repeat -- Analyze Row 1 --put "Rows:" repeat with r = 1 to pRows+1 -- put r,ptextureCoordinateList[(r-1)*(pColumns+1)+1],(r-1)*(pColumns+1)+1 end repeat -- Analyze Col 1 -- put "Columns:" repeat with c = 1 to pColumns+1 -- put c,ptextureCoordinateList[c] end repeat
end --************************************************************************** *********** --**************** GRID *********************************************************** --************************************************************************** *********** on grid(me, mName, columns, rows, spacing) --based on the params figure out --how wide and how long the final --grid dimensions will be gridwidth = columns * spacing gridlength = rows * spacing
-- determine the number of faces nFaces = columns * rows * 2 -- determine the number of vertices nVerts = (columns + 1) * (rows + 1)
--create a new mesh modelresource --that defines the number of faces --and vertices from the lines above meshRes = scene.newmesh(mName & "res", nFaces, nVerts, 0, 3, nVerts) meshRes.colorlist = [rgb(0,0,0) ,rgb(0,30,255)]--rgb(255,255,0), rgb(0,100,255)
--since we are going to be using a nested --repeat loop to generate our vertexlist, --we will temporarily add the vertices to --this list, before assigning the value of --this list to the vertexlist all at once tempvertexlist = []
-- the pTextureCoordinateList will have the same number of entries as the vertex list. -- Every entry consists of a 2 item list that is a float from 0-1.0, that corespond to positon in the texture. pTextureCoordinateList = []
-- the tFaceTxCoordinates is a list that will be used to assign the entries of the pTextureCoordinateList -- to all the faces in the nodel. tFaceTxCoordinates = []
-- determine, based on the width and length -- of the final grid, where in local coordinates -- the X/Z starting position should be for the -- first vertex in the grid. -- this will make sure -- that the center of the grid is located at the -- center of model relative coordinate space startwidth = -(gridwidth / 2) startlength = 0 -- place the axis at the bottom of the grid
-- next, we will be generating the vertices for -- the vertexlist by cycling through all of the -- vertices that we need to create from -- -X to +X and -Z to +Z repeat with length = 1 to (rows + 1) repeat with width = 1 to (columns + 1)
-- this next line of code adds -- the a vertex to the temporary vertex list -- Note, that the Y component of this -- list is currently 0, because the grid -- we are creating is flat. When we revisit -- this script, this line in particular will -- be different because we will be setting -- a Y value (to create terrain) --vertPos = vector(t.position.x, startlength, t.position.z) --addat(tempvertexlist, vertPos) addat(tempvertexlist, vector(startwidth, startlength, 0))
--UVW TEXTURE COORDINATES -- add to the list the percent wide and high of the texture Map for each vertex location
pTextureCoordinateList.append([(length-1 (See http://gth-1.ora-code.com)).float/(rows ),(width-1 (See http://dth-1.ora-code.com)).float/(col umns )])
-- add the correct amount of units to the -- current value of startwidth startwidth = startwidth + spacing
end repeat --once we have created all of the vertices in -- a given horizontal row, we need to advance -- the value of startlength, (so that the vertices -- are "closer towards the viewer" on the +Z axis startlength = startlength + spacing --also, when we move to the next row, make sure -- that we reset the position of the X component -- to the starting position of the grid entirely startwidth = -(gridwidth / 2) end repeat
-- once all of the vertexlist have been assigned -- in the temporary list, set them to the actual list meshRes.vertexlist = tempvertexlist
meshRes.textureCoordinateList = pTextureCoordinateList
--next, you will need to assign all of the vertices --to the faces in the grid. This is the most complicated --part of the script.
-- first, I will create several counters that will be used -- to determine "which face" we are on and "which vertex" -- is the first vertex for the current face startvert = 1 facenumber = 1 -- --Vcolumn = 1 -- rowcount=1 -- colcount = 1 VertCount = 1 --reset the nested list that will be used for the verts MDvertlist = [] repeat with r = 1 to rows MDvertlist[r] = [] end repeat
-- multiple is used to make sure that when we are counting -- the value of startvert, that its increment goes something -- like 1, 2, 4, 5, (for a 2 face X 2 face grid) multiple = columns + 1
-- notice that the repeat loop only goes through -- 1/2 the number of faces: why? because the vertices -- for odd faces and even faces will be determined -- using two different schemes! This way, within -- one cycle of the repeat loop, we will define -- an odd face, and then an even face and essentially -- "jump" the counters by two repeat with length = 1 to (nFaces / 2)
--odd face
faceVerts = [startvert, startvert + columns + 1, startvert + 1] -- tFaceTxCoordinates.append = [startvert, startvert + columns + 1, startvert + 1]
meshRes.face[facenumber].vertices = faceverts meshRes.face[facenumber].textureCoordinates = faceverts
-- if length/2 = length.float/2 then -- meshRes.face[facenumber].colors = [1,1,2] -- else -- meshRes.face[facenumber].colors = [2,2,1] -- end if
--add the --even face faceVerts = [startvert + 1, startvert + columns + 1, startvert + columns + 2] --(note how I am adding one to facevalue temporarily -- in order to reference the even numbered face) meshRes.face[facenumber + 1].vertices = faceverts meshRes.face[facenumber + 1].textureCoordinates = faceverts
-- -- assign colors to verts so that every other column is an alternating color -- if length/2 = length.float/2 then -- meshRes.face[facenumber + 1].colors = [2,1,2] -- else -- meshRes.face[facenumber + 1].colors = [1,2,1] -- end if
-- create a list that stores all the vertices in the vertexlist sorted by rows
-- jump the current facenumber by two facenumber = facenumber + 2 --add one to the value of startvert startvert = startvert + 1 VertCount = VertCount +1
--but make sure that if we are at the end of a row --that we skip two vertices and not just one! if startvert mod multiple = 0 then startvert = startvert + 1 rowcount = rowcount +1 colcount = 1 end if end repeat -- I am setting the color of face[1] different -- so that you can locate it in the grid. --meshres.face[1].colors = [3,3,3] -- ---- ---- ---- ----- --generate normals meshRes.generatenormals(#flat) --build the mesh meshRes.build() --create the model obj = scene.newmodel(mName, meshRes) return obj end --************************************************************************** *********** --**************** UVWtile ****************************************************** --************************************************************************** *********** -- Desc: - resets the UVW coords to tile or mirror accorfing to the params. -- params: tileU - float: the amount of repeating along U -- tileV - float: the amount of repeating along V -- bMirrorU - boolean - whether to mirror along U -- bMirrorV - boolean - whether to mirror along V on UVWtile (me,tileU,tileV,bMirrorU,bMirrorV) --- initialize the params if they are set to void if tileU = void then tileU = 1 if tileV = void then tileV = 1 if bMirrorU <> 1 then bMirrorU = 0 if bMirrorV <> 1 then bMirrorV = 0 -- ---- ---- ---- ---- ---- -- pTextureCoordinateList = [] repeat with U = 1 to (pRows + 1) repeat with V = 1 to (pColumns + 1) --Set the UVW TEXTURE COORDINATES. eg pTextureCoordinateList -- ---- ---- ---- -- U -- add to the list the percent wide and high of the texture Map for each vertex location. -- Tiling uvwU = (U-1).float/(pRows)*tileU -- Mirroring if bMirrorU = 1 then uvwU=uvwU*2 if uvwU > 1 then -- Strip Off the numbers to the left of the decimal point. uvwUm = uvwU - getLeftofDecimal(uvwU) -- If the UVW is odd, then mirror its value if (getLeftofDecimal(uvwU)).float/(2 ) <> (getLeftofDecimal(uvwU))/(2 ) then uvwUm = 1-uvwUm end if uvwU = uvwUm end if end if -- ---- ---- ---- -- V -- Tiling uvwV = (V-1).float/(pColumns)*tileV -- Mirroring if bMirrorV = 1 then uvwV=uvwV*2 if uvwV > 1 then -- Strip Off the numbers to the left of the decimal point. uvwVm = uvwV - getLeftofDecimal(uvwV) -- If the UVW is odd, then mirror its value if (getLeftofDecimal(uvwV)).float/2 <> (getLeftofDecimal(uvwV))/2 then uvwVm = 1-uvwVm end if uvwV = uvwVm end if end if -- ---- ---- ---- -- -- Remove the seam if we are mirroring. fudgeEdge = .02 if bMirrorV=1 then if uvwV = 0 then uvwV = fudgeEdge if uvwV = 1 then uvwV = 1-fudgeEdge end if if bMirrorU=1 then if uvwU = 0 then uvwU = fudgeEdge if uvwU = 1 then uvwU = 1-fudgeEdge end if -- Set The Texture Coordinate List pTextureCoordinateList.append([uvwU,uvwV]) end repeat end repeat -- ---- ---- ---- ---- ---- ---- ---- ---- --- -- Assign the texture coords to all the faces. startvert = 1 facenumber = 1 Vcolumn = 1 rowcount=1 colcount = 1 VertCount = 1 nFaces = pModRes.face.count tFaceTxCoordinates = [] --reset the nested list that will be used for the verts MDvertlist = [] repeat with r = 1 to pRows MDvertlist[r] = [] end repeat -- multiple is used to make sure that when we are counting -- the value of startvert, that its increment goes something -- like 1, 2, 4, 5, (for a 2 face X 2 face grid) multiple = pColumns + 1 -- Cycle through the faces repeat with length = 1 to (nFaces / 2) --odd face faceVerts = [startvert, startvert + pColumns + 1, startvert + 1] pModRes.face[facenumber].textureCoordinates = faceverts --even face faceVerts = [startvert + 1, startvert + pColumns + 1, startvert + pColumns + 2] --(note how I am adding one to facevalue temporarily -- in order to reference the even numbered face) pModRes.face[facenumber + 1].vertices = faceverts pModRes.face[facenumber + 1].textureCoordinates = faceverts -- jump the current facenumber by two facenumber = facenumber + 2 -- add one to the value of startvert startvert = startvert + 1 VertCount = VertCount +1 --but make sure that if we are at the end of a row --that we skip two vertices and not just one! if startvert mod multiple = 0 then startvert = startvert + 1 rowcount = rowcount +1 colcount = 1 end if end repeat pModRes.textureCoordinateList = ptextureCoordinateList -- ---- ---- ---- --build the mesh pModRes.build() --recreate the model -- mName = pModel.name -- scene.deleteModel(pModel.name) -- pModel = scene.newmodel(mName, pModRes) -- pModel.visibility = #both pModel.shader = pShader end --************************************************************************** *********** --**************** centerPivot **************************************************** --************************************************************************** *********** -- Desc: - centers the pivot in the middle of the object by finding the center point and the -- vector difference and then moving all point that amount. on centerPivot (me) -- Get the center by getting the 2 corner point (first and last vertex) p1 = pModel.resource.vertexlist[1] p2 = pModel.resource.vertexlist[pModel.resource.vertexlist.count] centerPoint = p1 + ((p2-p1)*.5) modelPoint = pModel.transform.position AdjustmentVector = modelPoint-centerPoint -- Loop through all the vertices and move them by the Adjustment Vector. repeat with v = 1 to pModel.resource.vertexlist.count pModel.resource.vertexlist[v] = pModel.resource.vertexlist[v] +AdjustmentVector end repeat end --************************************************************************** *********** --**************** destroy3D ****************************************************** --************************************************************************** *********** -- Desc: - deletes all the model and resources and shaders created previously bu this script on destroy3D me,mName repeat with mr = 1 to scene.modelResource.count if scene.modelResource[mr].name contains mName then scene.deleteModelResource(scene.modelResource[mr].name) end if end repeat repeat with m = 1 to scene.model.count if scene.model[m].name contains mName then scene.deleteModel(scene.model[m].name) end if end repeat repeat with m = 1 to scene.shader.count if scene.shader[m].name contains mName then scene.deleteShader(scene.shader[m].name) end if end repeat end --************************************************************************** *********** --**************** getProperty **************************************************** --************************************************************************** *********** -- Desc: - gets a property and returns its value. on getProperty (me,mPropName) smPropName = symbol(mPropName) return (me[smPropName]) end --************************************************************************** *********** --**************** setShader **************************************************** --************************************************************************** *********** -- Desc: - sets the shader to the param mNewValue. -- params: mNewValue - shader to be assigned. on setShader (me, mNewShader) pShader = mNewShader pModel.shader = pShader end --************************************************************************** *********** --**************** ChangeShader *************************************************** --************************************************************************** *********** -- Desc: - allows for propties to be set in the shader. -- params: #property - the name of the shader property eg #emissive -- #value - the value associated with the shader property. on ChangeShader (me,mShader,mPropName,mValue,mIndex) setaProperty( mShader, mPropName, mValue, mIndex) end >
__ ____ ____ ____ ____ ____ ____ ____ ____ ____ Dir3d-l mailing list Dir3d-l@(protected) http://nuttybar.drama.uga.edu/mailman/listinfo/dir3d-l
|
|