improve ptex guttering.

This commit is contained in:
Takahito Tejima 2013-10-15 17:47:58 -07:00
parent 23a518b42f
commit dd8cc1a3b7
8 changed files with 672 additions and 410 deletions

View File

@ -116,6 +116,7 @@ enum HudCheckBox { HUD_CB_ADAPTIVE,
HUD_CB_PATCH_CULL,
HUD_CB_IBL,
HUD_CB_BLOOM,
HUD_CB_SEAMLESS_MIPMAP,
HUD_CB_FREEZE };
enum HudRadioGroup { HUD_RB_KERNEL,
@ -188,6 +189,8 @@ bool g_adaptive = true,
bool g_occlusion = false,
g_specular = false;
bool g_seamless = true;
// camera
float g_rotate[2] = {0, 0},
g_prev_x = 0,
@ -425,6 +428,7 @@ union Effect {
int screenSpaceTess:1;
int fractionalSpacing:1;
int ibl:1;
int seamless:1;
};
int value;
@ -565,6 +569,10 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc, ID3D11Device
sconfig->pixelShader.AddDefine("PRIM_TRI");
}
if (effect.seamless) {
sconfig->commonShader.AddDefine("SEAMLESS_MIPMAP");
}
if (effect.wire == 0) {
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_WIRE");
sconfig->pixelShader.AddDefine("GEOMETRY_OUT_WIRE");
@ -973,6 +981,7 @@ drawModel()
effect.fractionalSpacing = g_fractionalSpacing;
effect.ibl = g_ibl;
effect.wire = g_wire;
effect.seamless = g_seamless;
bindProgram(effect, patch);
@ -1213,6 +1222,9 @@ callbackCheckBox(bool checked, int button)
case HUD_CB_IBL:
g_ibl = checked;
break;
case HUD_CB_SEAMLESS_MIPMAP:
g_seamless = checked;
break;
case HUD_CB_FREEZE:
g_freeze = checked;
break;
@ -1331,6 +1343,8 @@ initHUD()
-200, 450, 20, false, callbackSlider, 0);
g_hud->AddSlider("Displacement", 0, 5, 1,
-200, 490, 20, false, callbackSlider, 1);
g_hud->AddCheckBox("Seamless Mipmap", g_seamless,
-200, 530, callbackCheckBox, HUD_CB_SEAMLESS_MIPMAP, 'j');
if (g_osdPTexOcclusion != NULL) {
g_hud->AddCheckBox("Ambient Occlusion (A)", g_occlusion,

View File

@ -37,6 +37,7 @@ struct PtexPacking
int nMipmap;
int uOffset;
int vOffset;
int adjSizeDiffs[4];
int width;
int height;
};
@ -44,13 +45,20 @@ struct PtexPacking
PtexPacking getPtexPacking(Buffer<int> packings, int faceID)
{
PtexPacking packing;
packing.page = packings[faceID*5+0].x;
packing.nMipmap = packings[faceID*5+1].x;
packing.uOffset = packings[faceID*5+2].x;
packing.vOffset = packings[faceID*5+3].x;
int wh = packings[faceID*5+4].x;
packing.page = packings[faceID*6+0].x;
packing.nMipmap = packings[faceID*6+1].x;
packing.uOffset = packings[faceID*6+2].x;
packing.vOffset = packings[faceID*6+3].x;
int wh = packings[faceID*6+5].x;
packing.width = 1 << (wh >> 8);
packing.height = 1 << (wh & 0xff);
int adjSizeDiffs = packings[faceID*6+4].x;
packing.adjSizeDiffs[0] = (adjSizeDiffs >> 12) & 0xf;
packing.adjSizeDiffs[1] = (adjSizeDiffs >> 8) & 0xf;
packing.adjSizeDiffs[2] = (adjSizeDiffs >> 4) & 0xf;
packing.adjSizeDiffs[3] = (adjSizeDiffs >> 0) & 0xf;
return packing;
}
@ -73,11 +81,11 @@ int computeMipmapOffsetV(int h, int level)
PtexPacking getPtexPacking(Buffer<int> packings, int faceID, int level)
{
PtexPacking packing;
packing.page = packings[faceID*5+0].x;
packing.nMipmap = packings[faceID*5+1].x;
packing.uOffset = packings[faceID*5+2].x;
packing.vOffset = packings[faceID*5+3].x;
int wh = packings[faceID*5+4].x;
packing.page = packings[faceID*6+0].x;
packing.nMipmap = packings[faceID*6+1].x;
packing.uOffset = packings[faceID*6+2].x;
packing.vOffset = packings[faceID*6+3].x;
int wh = packings[faceID*6+5].x;
int w = wh >> 8;
int h = wh & 0xff;
@ -90,6 +98,7 @@ PtexPacking getPtexPacking(Buffer<int> packings, int faceID, int level)
packing.height = 1 << (h-level);
return packing;
}
float4 PTexLookupNearest(float4 patchCoord,
@ -220,7 +229,15 @@ float4 PTexMipmapLookup(float4 patchCoord,
Texture2DArray data,
Buffer<int> packings)
{
// TODO take into account difflevel
#if defined(SEAMLESS_MIPMAP)
// diff level
int faceID = int(patchCoord.w);
float2 uv = patchCoord.xy;
PtexPacking packing = getPtexPacking(packings, faceID);
level += lerp(lerp(packing.adjSizeDiffs[0], packing.adjSizeDiffs[1], uv.x),
lerp(packing.adjSizeDiffs[3], packing.adjSizeDiffs[2], uv.x),
uv.y);
#endif
int levelm = int(floor(level));
int levelp = int(ceil(level));
@ -238,7 +255,15 @@ float4 PTexMipmapLookupQuadratic(out float4 du,
Texture2DArray data,
Buffer<int> packings)
{
// TODO take into account difflevel
#if defined(SEAMLESS_MIPMAP)
// diff level
int faceID = int(patchCoord.w);
float2 uv = patchCoord.xy;
PtexPacking packing = getPtexPacking(packings, faceID);
level += lerp(lerp(packing.adjSizeDiffs[0], packing.adjSizeDiffs[1], uv.x),
lerp(packing.adjSizeDiffs[3], packing.adjSizeDiffs[2], uv.x),
uv.y);
#endif
int levelm = int(floor(level));
int levelp = int(ceil(level));

View File

@ -34,6 +34,7 @@ struct PtexPacking
int nMipmap;
int uOffset;
int vOffset;
int adjSizeDiffs[4];
int width;
int height;
};
@ -54,13 +55,20 @@ vec4 GeneratePatchCoord(vec2 localUV, int primitiveID) // for non-adpative
PtexPacking getPtexPacking(isamplerBuffer packings, int faceID)
{
PtexPacking packing;
packing.page = texelFetch(packings, faceID*5).x;
packing.nMipmap = texelFetch(packings, faceID*5+1).x;
packing.uOffset = texelFetch(packings, faceID*5+2).x;
packing.vOffset = texelFetch(packings, faceID*5+3).x;
int wh = texelFetch(packings, faceID*5+4).x;
packing.page = texelFetch(packings, faceID*6).x;
packing.nMipmap = texelFetch(packings, faceID*6+1).x;
packing.uOffset = texelFetch(packings, faceID*6+2).x;
packing.vOffset = texelFetch(packings, faceID*6+3).x;
int wh = texelFetch(packings, faceID*6+5).x;
packing.width = 1 << (wh >> 8);
packing.height = 1 << (wh & 0xff);
int adjSizeDiffs = texelFetch(packings, faceID*6+4).x;
packing.adjSizeDiffs[0] = (adjSizeDiffs >> 12) & 0xf;
packing.adjSizeDiffs[1] = (adjSizeDiffs >> 8) & 0xf;
packing.adjSizeDiffs[2] = (adjSizeDiffs >> 4) & 0xf;
packing.adjSizeDiffs[3] = (adjSizeDiffs >> 0) & 0xf;
return packing;
}
@ -83,11 +91,12 @@ int computeMipmapOffsetV(int h, int level)
PtexPacking getPtexPacking(isamplerBuffer packings, int faceID, int level)
{
PtexPacking packing;
packing.page = texelFetch(packings, faceID*5).x;
packing.nMipmap = texelFetch(packings, faceID*5+1).x;
packing.uOffset = texelFetch(packings, faceID*5+2).x;
packing.vOffset = texelFetch(packings, faceID*5+3).x;
int wh = texelFetch(packings, faceID*5+4).x;
packing.page = texelFetch(packings, faceID*6).x;
packing.nMipmap = texelFetch(packings, faceID*6+1).x;
packing.uOffset = texelFetch(packings, faceID*6+2).x;
packing.vOffset = texelFetch(packings, faceID*6+3).x;
int sizeDiffs = texelFetch(packings, faceID*6+4).x;
int wh = texelFetch(packings, faceID*6+5).x;
int w = wh >> 8;
int h = wh & 0xff;
@ -125,6 +134,19 @@ vec4 PTexLookupNearest(vec4 patchCoord,
return texelFetch(data, ivec3(int(coords.x), int(coords.y), ppack.page), 0);
}
vec4 PTexLookupNearest(vec4 patchCoord,
int level,
sampler2DArray data,
isamplerBuffer packings)
{
vec2 uv = patchCoord.xy;
int faceID = int(patchCoord.w);
PtexPacking ppack = getPtexPacking(packings, faceID, level);
vec2 coords = vec2(uv.x * ppack.width + ppack.uOffset,
uv.y * ppack.height + ppack.vOffset);
return texelFetch(data, ivec3(int(coords.x), int(coords.y), ppack.page), 0);
}
vec4 PTexLookupFast(vec4 patchCoord,
sampler2DArray data,
isamplerBuffer packings)
@ -255,7 +277,15 @@ vec4 PTexMipmapLookup(vec4 patchCoord,
sampler2DArray data,
isamplerBuffer packings)
{
// TODO take into account difflevel
#if defined(SEAMLESS_MIPMAP)
// diff level
int faceID = int(patchCoord.w);
vec2 uv = patchCoord.xy;
PtexPacking packing = getPtexPacking(packings, faceID);
level += mix(mix(packing.adjSizeDiffs[0], packing.adjSizeDiffs[1], uv.x),
mix(packing.adjSizeDiffs[3], packing.adjSizeDiffs[2], uv.x),
uv.y);
#endif
int levelm = int(floor(level));
int levelp = int(ceil(level));
@ -274,7 +304,15 @@ vec4 PTexMipmapLookupQuadratic(out vec4 du,
sampler2DArray data,
isamplerBuffer packings)
{
// TODO take into account difflevel
#if defined(SEAMLESS_MIPMAP)
// diff level
int faceID = int(patchCoord.w);
vec2 uv = patchCoord.xy;
PtexPacking packing = getPtexPacking(packings, faceID);
level += mix(mix(packing.adjSizeDiffs[0], packing.adjSizeDiffs[1], uv.x),
mix(packing.adjSizeDiffs[3], packing.adjSizeDiffs[2], uv.x),
uv.y);
#endif
int levelm = int(floor(level));
int levelp = int(ceil(level));

View File

@ -167,6 +167,7 @@ enum HudCheckBox { HUD_CB_ADAPTIVE,
HUD_CB_PATCH_CULL,
HUD_CB_IBL,
HUD_CB_BLOOM,
HUD_CB_SEAMLESS_MIPMAP,
HUD_CB_FREEZE };
enum HudRadioGroup { HUD_RB_KERNEL,
@ -253,6 +254,8 @@ struct Transform {
bool g_occlusion = false,
g_specular = false;
bool g_seamless = true;
// camera
float g_rotate[2] = {0, 0},
g_dolly = 5,
@ -683,6 +686,7 @@ union Effect {
int screenSpaceTess:1;
int fractionalSpacing:1;
int ibl:1;
int seamless:1;
};
int value;
@ -823,6 +827,10 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc)
sconfig->fragmentShader.AddDefine("PRIM_TRI");
}
if (effect.seamless) {
sconfig->commonShader.AddDefine("SEAMLESS_MIPMAP");
}
if (effect.wire == 0) {
sconfig->geometryShader.AddDefine("GEOMETRY_OUT_WIRE");
sconfig->fragmentShader.AddDefine("GEOMETRY_OUT_WIRE");
@ -1552,6 +1560,7 @@ drawModel()
effect.fractionalSpacing = g_fractionalSpacing;
effect.ibl = g_ibl;
effect.wire = g_wire;
effect.seamless = g_seamless;
GLuint program = bindProgram(effect, patch);
@ -1953,6 +1962,9 @@ callbackCheckBox(bool checked, int button)
case HUD_CB_BLOOM:
g_bloom = checked;
break;
case HUD_CB_SEAMLESS_MIPMAP:
g_seamless = checked;
break;
case HUD_CB_FREEZE:
g_freeze = checked;
break;
@ -2390,8 +2402,10 @@ int main(int argc, char ** argv)
g_hud.AddSlider("Mipmap Bias", 0, 5, 0,
-200, 450, 20, false, callbackSlider, 0);
g_hud.AddSlider("Displacementd", 0, 5, 1,
g_hud.AddSlider("Displacement", 0, 5, 1,
-200, 490, 20, false, callbackSlider, 1);
g_hud.AddCheckBox("Seamless Mipmap", g_seamless,
-200, 530, callbackCheckBox, HUD_CB_SEAMLESS_MIPMAP, 'j');
if (occlusionFilename != NULL) {
g_hud.AddCheckBox("Ambient Occlusion (A)", g_occlusion,

View File

@ -101,7 +101,7 @@ OsdD3D11PtexMipmapTexture::Create(ID3D11DeviceContext *deviceContext,
int numFaces = loader.GetNumFaces();
ID3D11Buffer *layout = genTextureBuffer(deviceContext,
numFaces * 5 * sizeof(short),
numFaces * 6 * sizeof(short),
loader.GetLayoutBuffer());
if (not layout) return NULL;
@ -184,7 +184,7 @@ OsdD3D11PtexMipmapTexture::Create(ID3D11DeviceContext *deviceContext,
srvd.Format = DXGI_FORMAT_R16_UINT;
srvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
srvd.Buffer.FirstElement = 0;
srvd.Buffer.NumElements = numFaces * 5;
srvd.Buffer.NumElements = numFaces * 6;
hr = device->CreateShaderResourceView(layout, &srvd, &layoutSRV);
if (FAILED(hr)) return NULL;

View File

@ -85,7 +85,7 @@ OsdGLPtexMipmapTexture::Create(PtexTexture * reader,
int numFaces = loader.GetNumFaces();
GLuint layout = genTextureBuffer(GL_R16I,
numFaces * 5 * sizeof(GLshort),
numFaces * 6 * sizeof(GLshort),
loader.GetLayoutBuffer());
GLenum format, type;

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,7 @@
#include "../version.h"
#include <stdint.h>
#include <vector>
class PtexTexture;
@ -39,7 +40,8 @@ public:
OsdPtexMipmapTextureLoader(PtexTexture *ptex,
int maxNumPages,
int maxLevels = -1,
size_t targetMemory = 0);
size_t targetMemory = 0,
bool seamlessMipmap = true);
~OsdPtexMipmapTextureLoader();
@ -100,36 +102,25 @@ private:
struct Block {
int index; // ptex index
int nMipmaps;
unsigned short u, v; // top-left texel offset
unsigned short width, height; // texel dimension (includes mipmap)
unsigned char ulog2, vlog2; // texel dimension log2 (original tile)
uint16_t u, v; // top-left texel offset
uint16_t width, height; // texel dimension (includes mipmap)
uint16_t adjSizeDiffs; // maximum tile size difference around each vertices
int8_t ulog2, vlog2; // texel dimension log2 (original tile)
void Generate(PtexTexture *ptex, unsigned char *destination,
void Generate(OsdPtexMipmapTextureLoader *loader, PtexTexture *ptex,
unsigned char *destination,
int bpp, int width, int maxLevels);
void guttering(PtexTexture *ptex, int level, int width, int height,
unsigned char *pptr, int bpp, int stride);
void SetSize(unsigned char ulog2_, unsigned char vlog2_, bool mipmap);
void SetSize(unsigned char ulog2_, unsigned char vlog2_, bool mipmap) {
ulog2 = ulog2_;
vlog2 = vlog2_;
int w = 1 << ulog2;
int h = 1 << vlog2;
// includes mipmap
if (mipmap) {
w = w + w/2 + 4;
h = h + 2;
}
width = w;
height = h;
}
int GetNumTexels() const {
return width*height;
}
void guttering(OsdPtexMipmapTextureLoader *loader, PtexTexture *ptex,
int level, int width, int height,
unsigned char *pptr, int bpp, int stride);
static bool sort(const Block *a, const Block *b) {
return (a->height > b->height) or
((a->height == b->height) and (a->width > b->width));
@ -137,9 +128,18 @@ private:
};
struct Page;
class CornerIterator;
void generateBuffers();
void optimizePacking(int maxNumPages, size_t targetMemory);
int getLevelDiff(int face, int edge);
bool getCornerPixel(float *resultPixel, int numchannels,
int face, int edge, int bpp, int8_t res);
void sampleNeighbor(unsigned char *border,
int face, int edge, int length, int bpp);
int resampleBorder(int face, int edgeId, unsigned char *result,
int dstLength, int bpp,
float srcStart = 0.0f, float srcEnd = 1.0f);
std::vector<Block> _blocks;
std::vector<Page *> _pages;