mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2025-01-11 17:10:08 +00:00
improve ptex guttering.
This commit is contained in:
parent
23a518b42f
commit
dd8cc1a3b7
@ -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,
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user