diff --git a/examples/dxPtexViewer/dxPtexViewer.cpp b/examples/dxPtexViewer/dxPtexViewer.cpp index 50a16b01..1afc0377 100644 --- a/examples/dxPtexViewer/dxPtexViewer.cpp +++ b/examples/dxPtexViewer/dxPtexViewer.cpp @@ -460,6 +460,8 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc, ID3D11Device { Effect effect = desc.second; + SetPtexEnabled(true); + SourceConfigType * sconfig = BaseRegistry::_CreateDrawSourceConfig(desc.first, pd3dDevice); assert(sconfig); diff --git a/examples/dxPtexViewer/shader.hlsl b/examples/dxPtexViewer/shader.hlsl index bb8d2c57..e735edd0 100644 --- a/examples/dxPtexViewer/shader.hlsl +++ b/examples/dxPtexViewer/shader.hlsl @@ -31,264 +31,6 @@ cbuffer Config : register( b3 ) { float mipmapBias; }; -struct PtexPacking -{ - int page; - int nMipmap; - int uOffset; - int vOffset; - int adjSizeDiffs[4]; - int width; - int height; -}; - -PtexPacking getPtexPacking(Buffer packings, int faceID) -{ - PtexPacking packing; - 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; -} - -int computeMipmapOffsetU(int w, int level) -{ - int width = 1 << w; - int m = (0x55555555 & (width | (width-1))) << (w&1); - int x = ~((1 << (w -((level-1)&~1))) - 1); - return (m & x) + ((level+1)&~1); -} - -int computeMipmapOffsetV(int h, int level) -{ - int height = 1 << h; - int m = (0x55555555 & (height-1)) << ((h+1)&1);; - int x = ~((1 << (h - (level&~1))) - 1 ); - return (m & x) + (level&~1); -} - -PtexPacking getPtexPacking(Buffer packings, int faceID, int level) -{ - PtexPacking packing; - 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; - - // clamp max level - level = min(level, packing.nMipmap); - - packing.uOffset += computeMipmapOffsetU(w, level); - packing.vOffset += computeMipmapOffsetV(h, level); - packing.width = 1 << (w-level); - packing.height = 1 << (h-level); - - return packing; - -} - -float4 PTexLookupNearest(float4 patchCoord, - Texture2DArray data, - Buffer packings) -{ - float2 uv = patchCoord.xy; - int faceID = patchCoord.w; - PtexPacking ppack = getPtexPacking(packings, faceID); - float2 coords = float2(uv.x * ppack.width + ppack.uOffset, - uv.y * ppack.height + ppack.vOffset); - return data[int3(int(coords.x), int(coords.y), ppack.page)]; -} - -float4 PTexLookup(float4 patchCoord, - int level, - Texture2DArray data, - Buffer packings) -{ - float2 uv = patchCoord.xy; - int faceID = int(patchCoord.w); - PtexPacking ppack = getPtexPacking(packings, faceID, level); - - float2 coords = float2(uv.x * ppack.width + ppack.uOffset, - uv.y * ppack.height + ppack.vOffset); - - coords -= float2(0.5, 0.5); - - int c0X = int(floor(coords.x)); - int c1X = int(ceil(coords.x)); - int c0Y = int(floor(coords.y)); - int c1Y = int(ceil(coords.y)); - - float t = coords.x - float(c0X); - float s = coords.y - float(c0Y); - - float4 d0 = data[int3(c0X, c0Y, ppack.page)]; - float4 d1 = data[int3(c0X, c1Y, ppack.page)]; - float4 d2 = data[int3(c1X, c0Y, ppack.page)]; - float4 d3 = data[int3(c1X, c1Y, ppack.page)]; - - float4 result = (1-t) * ((1-s)*d0 + s*d1) + t * ((1-s)*d2 + s*d3); - - return result; -} - -// quadratic - -void EvalQuadraticBSpline(float u, out float B[3], out float BU[3]) -{ - B[0] = 0.5 * (u*u - 2.0*u + 1); - B[1] = 0.5 + u - u*u; - B[2] = 0.5 * u*u; - - BU[0] = u - 1.0; - BU[1] = 1 - 2 * u; - BU[2] = u; -} - -float4 PTexLookupQuadratic(out float4 du, - out float4 dv, - float4 patchCoord, - int level, - Texture2DArray data, - Buffer packings) -{ - float2 uv = patchCoord.xy; - int faceID = int(patchCoord.w); - PtexPacking ppack = getPtexPacking(packings, faceID, level); - - float2 coords = float2(uv.x * ppack.width + ppack.uOffset, - uv.y * ppack.height + ppack.vOffset); - - coords -= float2(0.5, 0.5); - - int cX = int(round(coords.x)); - int cY = int(round(coords.y)); - - float x = 0.5 - (float(cX) - coords.x); - float y = 0.5 - (float(cY) - coords.y); - - // --------------------------- - - float4 d[9]; - d[0] = data[int3(cX-1, cY-1, ppack.page)]; - d[1] = data[int3(cX-1, cY-0, ppack.page)]; - d[2] = data[int3(cX-1, cY+1, ppack.page)]; - d[3] = data[int3(cX-0, cY-1, ppack.page)]; - d[4] = data[int3(cX-0, cY-0, ppack.page)]; - d[5] = data[int3(cX-0, cY+1, ppack.page)]; - d[6] = data[int3(cX+1, cY-1, ppack.page)]; - d[7] = data[int3(cX+1, cY-0, ppack.page)]; - d[8] = data[int3(cX+1, cY+1, ppack.page)]; - - float B[3], D[3]; - float4 BUCP[3], DUCP[3]; - EvalQuadraticBSpline(y, B, D); - - for (int i = 0; i < 3; ++i) { - BUCP[i] = float4(0, 0, 0, 0); - DUCP[i] = float4(0, 0, 0, 0); - for (int j = 0; j < 3; j++) { - float4 A = d[i*3+j]; - BUCP[i] += A * B[j]; - DUCP[i] += A * D[j]; - } - } - - EvalQuadraticBSpline(x, B, D); - - float4 result = float4(0, 0, 0, 0); - du = float4(0, 0, 0, 0); - dv = float4(0, 0, 0, 0); - for (int i = 0; i < 3; ++i) { - result += B[i] * BUCP[i]; - du += D[i] * BUCP[i]; - dv += B[i] * DUCP[i]; - } - - du *= ppack.width; - dv *= ppack.height; - - return result; -} - -float4 PTexMipmapLookup(float4 patchCoord, - float level, - Texture2DArray data, - Buffer packings) -{ -#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)); - float t = level - float(levelm); - - float4 result = (1-t) * PTexLookup(patchCoord, levelm, data, packings) - + t * PTexLookup(patchCoord, levelp, data, packings); - return result; -} - -float4 PTexMipmapLookupQuadratic(out float4 du, - out float4 dv, - float4 patchCoord, - float level, - Texture2DArray data, - Buffer packings) -{ -#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)); - float t = level - float(levelm); - - float4 du0, du1, dv0, dv1; - float4 r0 = PTexLookupQuadratic(du0, dv0, patchCoord, levelm, data, packings); - float4 r1 = PTexLookupQuadratic(du1, dv1, patchCoord, levelp, data, packings); - - float4 result = lerp(r0, r1, t); - du = lerp(du0, du1, t); - dv = lerp(dv0, dv1, t); - - return result; -} - -float4 PTexMipmapLookupQuadratic(float4 patchCoord, - float level, - Texture2DArray data, - Buffer packings) -{ - float4 du, dv; - return PTexMipmapLookupQuadratic(du, dv, patchCoord, level, data, packings); -} - // --------------------------------------------------------------------------- #if defined(DISPLACEMENT_HW_BILINEAR) \ @@ -317,15 +59,15 @@ Buffer textureDisplace_Packing : register(t7); float4 displacement(float4 position, float3 normal, float4 patchCoord) { #if defined(DISPLACEMENT_HW_BILINEAR) - float disp = PTexLookupFast(patchCoord, + float disp = PtexLookupFast(patchCoord, textureDisplace_Data, textureDisplace_Packing).x; #elif defined(DISPLACEMENT_BILINEAR) - float disp = PTexMipmapLookup(patchCoord, mipmapBias, + float disp = PtexMipmapLookup(patchCoord, mipmapBias, textureDisplace_Data, textureDisplace_Packing).x; #elif defined(DISPLACEMENT_BIQUADRATIC) - float disp = PTexMipmapLookupQuadratic(patchCoord, mipmapBias, + float disp = PtexMipmapLookupQuadratic(patchCoord, mipmapBias, textureDisplace_Data, textureDisplace_Packing).x; #endif @@ -577,7 +319,7 @@ ps_main(in OutputVertex input, input.patchCoord); #elif defined(NORMAL_BIQUADRATIC) || defined(NORMAL_BIQUADRATIC_WG) float4 du, dv; - float4 disp = PTexMipmapLookupQuadratic(du, dv, input.patchCoord, + float4 disp = PtexMipmapLookupQuadratic(du, dv, input.patchCoord, mipmapBias, textureDisplace_Data, textureDisplace_Packing); @@ -602,19 +344,19 @@ ps_main(in OutputVertex input, // ------------ color --------------- #if defined(COLOR_PTEX_NEAREST) - float4 texColor = PTexLookupNearest(input.patchCoord, + float4 texColor = PtexLookupNearest(input.patchCoord, textureImage_Data, textureImage_Packing); #elif defined(COLOR_PTEX_HW_BILINEAR) - float4 texColor = PTexLookupFast(input.patchCoord, + float4 texColor = PtexLookupFast(input.patchCoord, textureImage_Data, textureImage_Packing); #elif defined(COLOR_PTEX_BILINEAR) - float4 texColor = PTexMipmapLookup(input.patchCoord, mipmapBias, + float4 texColor = PtexMipmapLookup(input.patchCoord, mipmapBias, textureImage_Data, textureImage_Packing); #elif defined(COLOR_PTEX_BIQUADRATIC) - float4 texColor = PTexMipmapLookupQuadratic(input.patchCoord, mipmapBias, + float4 texColor = PtexMipmapLookupQuadratic(input.patchCoord, mipmapBias, textureImage_Data, textureImage_Packing); #elif defined(COLOR_PATCHTYPE) @@ -639,7 +381,7 @@ ps_main(in OutputVertex input, // ------------ occlusion --------------- #ifdef USE_PTEX_OCCLUSION - float occ = PTexLookup(input.patchCoord, + float occ = PtexLookup(input.patchCoord, textureOcclusion_Data, textureOcclusion_Packing).x; #else @@ -649,7 +391,7 @@ ps_main(in OutputVertex input, // ------------ specular --------------- #ifdef USE_PTEX_SPECULAR - float specular = PTexLookup(input.patchCoord, + float specular = PtexLookup(input.patchCoord, textureSpecular_Data, textureSpecular_Packing).x; #else diff --git a/examples/ptexViewer/shader.glsl b/examples/ptexViewer/shader.glsl index 75b4d642..97b9ab2d 100644 --- a/examples/ptexViewer/shader.glsl +++ b/examples/ptexViewer/shader.glsl @@ -22,23 +22,14 @@ // language governing permissions and limitations under the Apache License. // #line 25 + //-------------------------------------------------------------- // Common //-------------------------------------------------------------- + uniform float displacementScale = 1.0; uniform float mipmapBias = 0; -struct PtexPacking -{ - int page; - int nMipmap; - int uOffset; - int vOffset; - int adjSizeDiffs[4]; - int width; - int height; -}; - vec4 GeneratePatchCoord(vec2 localUV, int primitiveID) // for non-adpative { ivec2 ptexIndex = texelFetch(OsdPatchParamBuffer, primitiveID).xy; @@ -52,303 +43,6 @@ vec4 GeneratePatchCoord(vec2 localUV, int primitiveID) // for non-adpative return vec4(uv.x, uv.y, lv+0.5, faceID+0.5); } -PtexPacking getPtexPacking(isamplerBuffer packings, int faceID) -{ - PtexPacking packing; - 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; -} - -int computeMipmapOffsetU(int w, int level) -{ - int width = 1 << w; - int m = (0x55555555 & (width | (width-1))) << (w&1); - int x = ~((1 << (w -((level-1)&~1))) - 1); - return (m & x) + ((level+1)&~1); -} - -int computeMipmapOffsetV(int h, int level) -{ - int height = 1 << h; - int m = (0x55555555 & (height-1)) << ((h+1)&1);; - int x = ~((1 << (h - (level&~1))) - 1 ); - return (m & x) + (level&~1); -} - -PtexPacking getPtexPacking(isamplerBuffer packings, int faceID, int level) -{ - PtexPacking packing; - 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; - - // clamp max level - level = min(level, packing.nMipmap); - -#if 0 - packing.width = 1 << w; - packing.height = 1 << h; - // offset mipmap location (slow!) - for (int i = 1; i <= level; ++i) { - packing.uOffset += (packing.width+2) * (i&1); - packing.vOffset += (packing.height+2) * (1-i&1); - packing.width /= 2; - packing.height /= 2; - } -#else - packing.uOffset += computeMipmapOffsetU(w, level); - packing.vOffset += computeMipmapOffsetV(h, level); - packing.width = 1 << (w-level); - packing.height = 1 << (h-level); -#endif - return packing; -} - -vec4 PTexLookupNearest(vec4 patchCoord, - sampler2DArray data, - isamplerBuffer packings) -{ - vec2 uv = patchCoord.xy; - int faceID = int(patchCoord.w); - PtexPacking ppack = getPtexPacking(packings, faceID); - 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 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) -{ - vec2 uv = patchCoord.xy; - int faceID = int(patchCoord.w); - PtexPacking ppack = getPtexPacking(packings, faceID); - - ivec3 size = textureSize(data, 0); - vec2 coords = vec2((uv.x * ppack.width + ppack.uOffset)/size.x, - (uv.y * ppack.height + ppack.vOffset)/size.y); - return texture(data, vec3(coords.x, coords.y, ppack.page)); -} - -vec4 PTexLookup(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); - - coords -= vec2(0.5, 0.5); - - int c0X = int(floor(coords.x)); - int c1X = int(ceil(coords.x)); - int c0Y = int(floor(coords.y)); - int c1Y = int(ceil(coords.y)); - - float t = coords.x - float(c0X); - float s = coords.y - float(c0Y); - - vec4 d0 = texelFetch(data, ivec3(c0X, c0Y, ppack.page), 0); - vec4 d1 = texelFetch(data, ivec3(c0X, c1Y, ppack.page), 0); - vec4 d2 = texelFetch(data, ivec3(c1X, c0Y, ppack.page), 0); - vec4 d3 = texelFetch(data, ivec3(c1X, c1Y, ppack.page), 0); - - vec4 result = (1-t) * ((1-s)*d0 + s*d1) + t * ((1-s)*d2 + s*d3); - - return result; -} - -// quadratic - -void EvalQuadraticBSpline(float u, out float B[3], out float BU[3]) -{ - B[0] = 0.5 * (u*u - 2.0*u + 1); - B[1] = 0.5 + u - u*u; - B[2] = 0.5 * u*u; - - BU[0] = u - 1.0; - BU[1] = 1 - 2 * u; - BU[2] = u; -} - -vec4 PTexLookupQuadratic(out vec4 du, - out vec4 dv, - 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); - - coords -= vec2(0.5, 0.5); - - int cX = int(round(coords.x)); - int cY = int(round(coords.y)); - - float x = 0.5 - (float(cX) - coords.x); - float y = 0.5 - (float(cY) - coords.y); - - // --------------------------- - - vec4 d[9]; - d[0] = texelFetch(data, ivec3(cX-1, cY-1, ppack.page), 0); - d[1] = texelFetch(data, ivec3(cX-1, cY-0, ppack.page), 0); - d[2] = texelFetch(data, ivec3(cX-1, cY+1, ppack.page), 0); - d[3] = texelFetch(data, ivec3(cX-0, cY-1, ppack.page), 0); - d[4] = texelFetch(data, ivec3(cX-0, cY-0, ppack.page), 0); - d[5] = texelFetch(data, ivec3(cX-0, cY+1, ppack.page), 0); - d[6] = texelFetch(data, ivec3(cX+1, cY-1, ppack.page), 0); - d[7] = texelFetch(data, ivec3(cX+1, cY-0, ppack.page), 0); - d[8] = texelFetch(data, ivec3(cX+1, cY+1, ppack.page), 0); - - float B[3], D[3]; - vec4 BUCP[3], DUCP[3]; - EvalQuadraticBSpline(y, B, D); - - for (int i = 0; i < 3; ++i) { - BUCP[i] = vec4(0); - DUCP[i] = vec4(0); - for (int j = 0; j < 3; j++) { - vec4 A = d[i*3+j]; - BUCP[i] += A * B[j]; - DUCP[i] += A * D[j]; - } - } - - EvalQuadraticBSpline(x, B, D); - - vec4 result = vec4(0); - du = vec4(0); - dv = vec4(0); - for (int i = 0; i < 3; ++i) { - result += B[i] * BUCP[i]; - du += D[i] * BUCP[i]; - dv += B[i] * DUCP[i]; - } - - du *= ppack.width; - dv *= ppack.height; - - return result; -} - -vec4 PTexMipmapLookup(vec4 patchCoord, - float level, - sampler2DArray data, - isamplerBuffer packings) -{ -#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)); - float t = level - float(levelm); - - vec4 result = (1-t) * PTexLookup(patchCoord, levelm, data, packings) - + t * PTexLookup(patchCoord, levelp, data, packings); - return result; -} - - -vec4 PTexMipmapLookupQuadratic(out vec4 du, - out vec4 dv, - vec4 patchCoord, - float level, - sampler2DArray data, - isamplerBuffer packings) -{ -#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)); - float t = level - float(levelm); - - vec4 du0, du1, dv0, dv1; - vec4 r0 = PTexLookupQuadratic(du0, dv0, patchCoord, levelm, data, packings); - vec4 r1 = PTexLookupQuadratic(du1, dv1, patchCoord, levelp, data, packings); - - vec4 result = mix(r0, r1, t); - du = mix(du0, du1, t); - dv = mix(dv0, dv1, t); - - return result; -} - -vec4 PTexMipmapLookupQuadratic(vec4 patchCoord, - float level, - sampler2DArray data, - isamplerBuffer packings) -{ - vec4 du, dv; - return PTexMipmapLookupQuadratic(du, dv, patchCoord, level, data, packings); -} - - -vec4 PTexLookup(vec4 patchCoord, - sampler2DArray data, - isamplerBuffer packings) -{ - return PTexMipmapLookup(patchCoord, mipmapBias, data, packings); -} - - - - #if defined(DISPLACEMENT_HW_BILINEAR) \ || defined(DISPLACEMENT_BILINEAR) \ || defined(DISPLACEMENT_BIQUADRATIC) \ @@ -372,15 +66,17 @@ uniform isamplerBuffer textureDisplace_Packing; vec4 displacement(vec4 position, vec3 normal, vec4 patchCoord) { #if defined(DISPLACEMENT_HW_BILINEAR) - float disp = PTexLookupFast(patchCoord, + float disp = PtexLookupFast(patchCoord, textureDisplace_Data, textureDisplace_Packing).x; #elif defined(DISPLACEMENT_BILINEAR) - float disp = PTexMipmapLookup(patchCoord, mipmapBias, + float disp = PtexMipmapLookup(patchCoord, + mipmapBias, textureDisplace_Data, textureDisplace_Packing).x; #elif defined(DISPLACEMENT_BIQUADRATIC) - float disp = PTexMipmapLookupQuadratic(patchCoord, mipmapBias, + float disp = PtexMipmapLookupQuadratic(patchCoord, + mipmapBias, textureDisplace_Data, textureDisplace_Packing).x; #endif @@ -705,13 +401,13 @@ perturbNormalFromDisplacement(vec3 position, vec3 normal, vec4 patchCoord) vec4 STlr = patchCoord + d * vec4(texDx.x, texDx.y, 0, 0); vec4 STul = patchCoord + d * vec4(texDy.x, texDy.y, 0, 0); #if defined NORMAL_HW_SCREENSPACE - float Hll = PTexLookupFast(STll, textureDisplace_Data, textureDisplace_Packing).x * displacementScale; - float Hlr = PTexLookupFast(STlr, textureDisplace_Data, textureDisplace_Packing).x * displacementScale; - float Hul = PTexLookupFast(STul, textureDisplace_Data, textureDisplace_Packing).x * displacementScale; + float Hll = PtexLookupFast(STll, textureDisplace_Data, textureDisplace_Packing).x * displacementScale; + float Hlr = PtexLookupFast(STlr, textureDisplace_Data, textureDisplace_Packing).x * displacementScale; + float Hul = PtexLookupFast(STul, textureDisplace_Data, textureDisplace_Packing).x * displacementScale; #elif defined NORMAL_SCREENSPACE - float Hll = PTexMipmapLookup(STll, mipmapBias, textureDisplace_Data, textureDisplace_Packing).x * displacementScale; - float Hlr = PTexMipmapLookup(STlr, mipmapBias, textureDisplace_Data, textureDisplace_Packing).x * displacementScale; - float Hul = PTexMipmapLookup(STul, mipmapBias, textureDisplace_Data, textureDisplace_Packing).x * displacementScale; + float Hll = PtexMipmapLookup(STll, mipmapBias, textureDisplace_Data, textureDisplace_Packing).x * displacementScale; + float Hlr = PtexMipmapLookup(STlr, mipmapBias, textureDisplace_Data, textureDisplace_Packing).x * displacementScale; + float Hul = PtexMipmapLookup(STul, mipmapBias, textureDisplace_Data, textureDisplace_Packing).x * displacementScale; #endif float dBs = (Hlr - Hll)/d; float dBt = (Hul - Hll)/d; @@ -801,7 +497,7 @@ main() inpt.v.patchCoord); #elif defined(NORMAL_BIQUADRATIC) || defined(NORMAL_BIQUADRATIC_WG) vec4 du, dv; - vec4 disp = PTexMipmapLookupQuadratic(du, dv, inpt.v.patchCoord, + vec4 disp = PtexMipmapLookupQuadratic(du, dv, inpt.v.patchCoord, mipmapBias, textureDisplace_Data, textureDisplace_Packing); @@ -827,19 +523,21 @@ main() // ------------ color --------------- #if defined COLOR_PTEX_NEAREST - vec4 texColor = PTexLookupNearest(inpt.v.patchCoord, + vec4 texColor = PtexLookupNearest(inpt.v.patchCoord, textureImage_Data, textureImage_Packing); #elif defined COLOR_PTEX_HW_BILINEAR - vec4 texColor = PTexLookupFast(inpt.v.patchCoord, + vec4 texColor = PtexLookupFast(inpt.v.patchCoord, textureImage_Data, textureImage_Packing); #elif defined COLOR_PTEX_BILINEAR - vec4 texColor = PTexMipmapLookup(inpt.v.patchCoord, mipmapBias, + vec4 texColor = PtexMipmapLookup(inpt.v.patchCoord, + mipmapBias, textureImage_Data, textureImage_Packing); #elif defined COLOR_PTEX_BIQUADRATIC - vec4 texColor = PTexMipmapLookupQuadratic(inpt.v.patchCoord, mipmapBias, + vec4 texColor = PtexMipmapLookupQuadratic(inpt.v.patchCoord, + mipmapBias, textureImage_Data, textureImage_Packing); #elif defined COLOR_PATCHTYPE @@ -864,9 +562,10 @@ main() // ------------ occlusion --------------- #ifdef USE_PTEX_OCCLUSION - float occ = PTexLookup(inpt.v.patchCoord, - textureOcclusion_Data, - textureOcclusion_Packing).x; + float occ = PtexMipMapLookup(inpt.v.patchCoord, + mipmapBias, + textureOcclusion_Data, + textureOcclusion_Packing).x; #else float occ = 0.0; #endif @@ -874,9 +573,10 @@ main() // ------------ specular --------------- #ifdef USE_PTEX_SPECULAR - float specular = PTexLookup(inpt.v.patchCoord, - textureSpecular_Data, - textureSpecular_Packing).x; + float specular = PtexMipMapLookup(inpt.v.patchCoord, + mipmapBias, + textureSpecular_Data, + textureSpecular_Packing).x; #else float specular = 1.0; #endif diff --git a/examples/ptexViewer/viewer.cpp b/examples/ptexViewer/viewer.cpp index 609dc97c..62de88c4 100644 --- a/examples/ptexViewer/viewer.cpp +++ b/examples/ptexViewer/viewer.cpp @@ -702,9 +702,10 @@ union Effect { typedef std::pair EffectDesc; -class EffectDrawRegistry : public OpenSubdiv::OsdGLDrawRegistry -{ - protected: +class EffectDrawRegistry : public OpenSubdiv::OsdGLDrawRegistry { + +protected: + virtual ConfigType * _CreateDrawConfig(DescType const & desc, SourceConfigType const * sconfig); @@ -717,6 +718,8 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc) { Effect effect = desc.second; + SetPtexEnabled(true); + SourceConfigType * sconfig = BaseRegistry::_CreateDrawSourceConfig(desc.first); @@ -764,62 +767,62 @@ EffectDrawRegistry::_CreateDrawSourceConfig(DescType const & desc) sconfig->fragmentShader.AddDefine("FRAGMENT_SHADER"); switch (effect.color) { - case COLOR_NONE: - break; - case COLOR_PTEX_NEAREST: - sconfig->fragmentShader.AddDefine("COLOR_PTEX_NEAREST"); - break; - case COLOR_PTEX_HW_BILINEAR: - sconfig->fragmentShader.AddDefine("COLOR_PTEX_HW_BILINEAR"); - break; - case COLOR_PTEX_BILINEAR: - sconfig->fragmentShader.AddDefine("COLOR_PTEX_BILINEAR"); - break; - case COLOR_PTEX_BIQUADRATIC: - sconfig->fragmentShader.AddDefine("COLOR_PTEX_BIQUADRATIC"); - break; - case COLOR_PATCHTYPE: - sconfig->fragmentShader.AddDefine("COLOR_PATCHTYPE"); - break; - case COLOR_PATCHCOORD: - sconfig->fragmentShader.AddDefine("COLOR_PATCHCOORD"); - break; - case COLOR_NORMAL: - sconfig->fragmentShader.AddDefine("COLOR_NORMAL"); - break; + case COLOR_NONE: + break; + case COLOR_PTEX_NEAREST: + sconfig->fragmentShader.AddDefine("COLOR_PTEX_NEAREST"); + break; + case COLOR_PTEX_HW_BILINEAR: + sconfig->fragmentShader.AddDefine("COLOR_PTEX_HW_BILINEAR"); + break; + case COLOR_PTEX_BILINEAR: + sconfig->fragmentShader.AddDefine("COLOR_PTEX_BILINEAR"); + break; + case COLOR_PTEX_BIQUADRATIC: + sconfig->fragmentShader.AddDefine("COLOR_PTEX_BIQUADRATIC"); + break; + case COLOR_PATCHTYPE: + sconfig->fragmentShader.AddDefine("COLOR_PATCHTYPE"); + break; + case COLOR_PATCHCOORD: + sconfig->fragmentShader.AddDefine("COLOR_PATCHCOORD"); + break; + case COLOR_NORMAL: + sconfig->fragmentShader.AddDefine("COLOR_NORMAL"); + break; } switch (effect.displacement) { - case DISPLACEMENT_NONE: - break; - case DISPLACEMENT_HW_BILINEAR: - sconfig->commonShader.AddDefine("DISPLACEMENT_HW_BILINEAR"); - break; - case DISPLACEMENT_BILINEAR: - sconfig->commonShader.AddDefine("DISPLACEMENT_BILINEAR"); - break; - case DISPLACEMENT_BIQUADRATIC: - sconfig->commonShader.AddDefine("DISPLACEMENT_BIQUADRATIC"); - break; + case DISPLACEMENT_NONE: + break; + case DISPLACEMENT_HW_BILINEAR: + sconfig->commonShader.AddDefine("DISPLACEMENT_HW_BILINEAR"); + break; + case DISPLACEMENT_BILINEAR: + sconfig->commonShader.AddDefine("DISPLACEMENT_BILINEAR"); + break; + case DISPLACEMENT_BIQUADRATIC: + sconfig->commonShader.AddDefine("DISPLACEMENT_BIQUADRATIC"); + break; } switch (effect.normal) { - case NORMAL_FACET: - sconfig->commonShader.AddDefine("NORMAL_FACET"); - break; - case NORMAL_HW_SCREENSPACE: - sconfig->commonShader.AddDefine("NORMAL_HW_SCREENSPACE"); - break; - case NORMAL_SCREENSPACE: - sconfig->commonShader.AddDefine("NORMAL_SCREENSPACE"); - break; - case NORMAL_BIQUADRATIC: - sconfig->commonShader.AddDefine("NORMAL_BIQUADRATIC"); - break; - case NORMAL_BIQUADRATIC_WG: - sconfig->commonShader.AddDefine("OSD_COMPUTE_NORMAL_DERIVATIVES"); - sconfig->commonShader.AddDefine("NORMAL_BIQUADRATIC_WG"); - break; + case NORMAL_FACET: + sconfig->commonShader.AddDefine("NORMAL_FACET"); + break; + case NORMAL_HW_SCREENSPACE: + sconfig->commonShader.AddDefine("NORMAL_HW_SCREENSPACE"); + break; + case NORMAL_SCREENSPACE: + sconfig->commonShader.AddDefine("NORMAL_SCREENSPACE"); + break; + case NORMAL_BIQUADRATIC: + sconfig->commonShader.AddDefine("NORMAL_BIQUADRATIC"); + break; + case NORMAL_BIQUADRATIC_WG: + sconfig->commonShader.AddDefine("OSD_COMPUTE_NORMAL_DERIVATIVES"); + sconfig->commonShader.AddDefine("NORMAL_BIQUADRATIC_WG"); + break; } if (effect.occlusion) diff --git a/opensubdiv/osd/CMakeLists.txt b/opensubdiv/osd/CMakeLists.txt index cbb84dfb..dacedbb2 100644 --- a/opensubdiv/osd/CMakeLists.txt +++ b/opensubdiv/osd/CMakeLists.txt @@ -256,6 +256,7 @@ if( OPENGL_FOUND OR OPENGLES_FOUND ) glslPatchBSpline.glsl glslPatchGregory.glsl glslPatchTransition.glsl + glslPtexCommon.glsl ) endif() list(APPEND PLATFORM_GPU_LIBRARIES @@ -347,6 +348,7 @@ if( DXSDK_FOUND ) hlslPatchBSpline.hlsl hlslPatchGregory.hlsl hlslPatchTransition.hlsl + hlslPtexCommon.hlsl ) list(APPEND PLATFORM_GPU_LIBRARIES ${DXSDK_LIBRARIES} diff --git a/opensubdiv/osd/d3d11DrawRegistry.cpp b/opensubdiv/osd/d3d11DrawRegistry.cpp index 3749231b..6d52e142 100644 --- a/opensubdiv/osd/d3d11DrawRegistry.cpp +++ b/opensubdiv/osd/d3d11DrawRegistry.cpp @@ -45,6 +45,9 @@ OsdD3D11DrawConfig::~OsdD3D11DrawConfig() static const char *commonShaderSource = #include "hlslPatchCommon.inc" ; +static const char *ptexShaderSource = +#include "hlslPtexCommon.inc" +; static const char *bsplineShaderSource = #include "hlslPatchBSpline.inc" ; @@ -64,6 +67,12 @@ OsdD3D11DrawRegistryBase::_CreateDrawSourceConfig( OsdD3D11DrawSourceConfig * sconfig = _NewDrawSourceConfig(); sconfig->commonShader.source = commonShaderSource; + + if (IsPtexEnabled()) { + sconfig->commonShader.source += ptexShaderSource; + } + + { std::ostringstream ss; ss << (int)desc.GetMaxValence(); diff --git a/opensubdiv/osd/d3d11DrawRegistry.h b/opensubdiv/osd/d3d11DrawRegistry.h index 22557e14..8a648261 100644 --- a/opensubdiv/osd/d3d11DrawRegistry.h +++ b/opensubdiv/osd/d3d11DrawRegistry.h @@ -62,6 +62,8 @@ struct OsdD3D11DrawConfig : public OsdDrawConfig { ID3D11PixelShader *pixelShader; }; +//------------------------------------------------------------------------------ + struct OsdD3D11DrawSourceConfig { OsdDrawShaderSource commonShader; OsdDrawShaderSource vertexShader; @@ -71,16 +73,28 @@ struct OsdD3D11DrawSourceConfig { OsdDrawShaderSource pixelShader; }; -//////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------------ class OsdD3D11DrawRegistryBase { + public: typedef OsdDrawContext::PatchDescriptor DescType; typedef OsdD3D11DrawConfig ConfigType; typedef OsdD3D11DrawSourceConfig SourceConfigType; + OsdD3D11DrawRegistryBase(bool enablePtex=false) : _enablePtex(enablePtex) { } + virtual ~OsdD3D11DrawRegistryBase(); + bool IsPtexEnabled() const { + return _enablePtex; + } + + void SetPtexEnabled(bool b) { + _enablePtex=b; + } + protected: virtual ConfigType * _NewDrawConfig() { return new ConfigType(); } virtual ConfigType * @@ -94,12 +108,18 @@ protected: virtual SourceConfigType * _NewDrawSourceConfig() { return new SourceConfigType(); } virtual SourceConfigType * _CreateDrawSourceConfig(DescType const & desc, ID3D11Device * pd3dDevice); + +private: + bool _enablePtex; }; +//------------------------------------------------------------------------------ + template + class SOURCE_CONFIG_TYPE = OsdD3D11DrawSourceConfig> class OsdD3D11DrawRegistry : public OsdD3D11DrawRegistryBase { + public: typedef OsdD3D11DrawRegistryBase BaseRegistry; @@ -145,18 +165,27 @@ public: } protected: - virtual ConfigType * _NewDrawConfig() { return new ConfigType(); } - virtual ConfigType * - _CreateDrawConfig(DescType const & desc, - SourceConfigType const * sconfig, - ID3D11Device * pd3dDevice, - ID3D11InputLayout ** ppInputLayout, - D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs, - int numInputElements) { return NULL; } + virtual ConfigType * _NewDrawConfig() { + return new ConfigType(); + } - virtual SourceConfigType * _NewDrawSourceConfig() { return new SourceConfigType(); } - virtual SourceConfigType * - _CreateDrawSourceConfig(DescType const & desc, ID3D11Device * pd3dDevice) { return NULL; } + virtual ConfigType * _CreateDrawConfig(DescType const & desc, + SourceConfigType const * sconfig, + ID3D11Device * pd3dDevice, + ID3D11InputLayout ** ppInputLayout, + D3D11_INPUT_ELEMENT_DESC const * pInputElementDescs, + int numInputElements) { + return NULL; + } + + virtual SourceConfigType * _NewDrawSourceConfig() { + return new SourceConfigType(); + } + + virtual SourceConfigType * _CreateDrawSourceConfig(DescType const & desc, + ID3D11Device * pd3dDevice) { + return NULL; + } private: ConfigMap _configMap; diff --git a/opensubdiv/osd/d3d11PtexMipmapTexture.cpp b/opensubdiv/osd/d3d11PtexMipmapTexture.cpp index dc542016..abaec2fe 100644 --- a/opensubdiv/osd/d3d11PtexMipmapTexture.cpp +++ b/opensubdiv/osd/d3d11PtexMipmapTexture.cpp @@ -109,42 +109,42 @@ OsdD3D11PtexMipmapTexture::Create(ID3D11DeviceContext *deviceContext, int bpp = 0; int numChannels = reader->numChannels(); switch (reader->dataType()) { - case Ptex::dt_uint16: - switch (numChannels) { - case 1: format = DXGI_FORMAT_R16_UINT; break; - case 2: format = DXGI_FORMAT_R16G16_UINT; break; - case 3: assert(false); break; - case 4: format = DXGI_FORMAT_R16G16B16A16_UINT; break; - } - bpp = numChannels * 2; - break; - case Ptex::dt_float: - switch (numChannels) { - case 1: format = DXGI_FORMAT_R32_FLOAT; break; - case 2: format = DXGI_FORMAT_R32G32_FLOAT; break; - case 3: format = DXGI_FORMAT_R32G32B32_FLOAT; break; - case 4: format = DXGI_FORMAT_R32G32B32A32_FLOAT; break; - } - bpp = numChannels * 4; - break; - case Ptex::dt_half: - switch (numChannels) { - case 1: format = DXGI_FORMAT_R16_FLOAT; break; - case 2: format = DXGI_FORMAT_R16G16_FLOAT; break; - case 3:assert(false); break; - case 4: format = DXGI_FORMAT_R16G16B16A16_FLOAT; break; - } - bpp = numChannels * 2; - break; - default: - switch (numChannels) { - case 1: format = DXGI_FORMAT_R8_UINT; break; - case 2: format = DXGI_FORMAT_R8G8_UINT; break; - case 3: assert(false); break; - case 4: format = DXGI_FORMAT_R8G8B8A8_UINT; break; - } - bpp = numChannels; - break; + case Ptex::dt_uint16: + switch (numChannels) { + case 1: format = DXGI_FORMAT_R16_UINT; break; + case 2: format = DXGI_FORMAT_R16G16_UINT; break; + case 3: assert(false); break; + case 4: format = DXGI_FORMAT_R16G16B16A16_UINT; break; + } + bpp = numChannels * 2; + break; + case Ptex::dt_float: + switch (numChannels) { + case 1: format = DXGI_FORMAT_R32_FLOAT; break; + case 2: format = DXGI_FORMAT_R32G32_FLOAT; break; + case 3: format = DXGI_FORMAT_R32G32B32_FLOAT; break; + case 4: format = DXGI_FORMAT_R32G32B32A32_FLOAT; break; + } + bpp = numChannels * 4; + break; + case Ptex::dt_half: + switch (numChannels) { + case 1: format = DXGI_FORMAT_R16_FLOAT; break; + case 2: format = DXGI_FORMAT_R16G16_FLOAT; break; + case 3:assert(false); break; + case 4: format = DXGI_FORMAT_R16G16B16A16_FLOAT; break; + } + bpp = numChannels * 2; + break; + default: + switch (numChannels) { + case 1: format = DXGI_FORMAT_R8_UINT; break; + case 2: format = DXGI_FORMAT_R8G8_UINT; break; + case 3: assert(false); break; + case 4: format = DXGI_FORMAT_R8G8B8A8_UINT; break; + } + bpp = numChannels; + break; } // actual texels texture array diff --git a/opensubdiv/osd/glDrawRegistry.cpp b/opensubdiv/osd/glDrawRegistry.cpp index c9747f9a..c63248c2 100644 --- a/opensubdiv/osd/glDrawRegistry.cpp +++ b/opensubdiv/osd/glDrawRegistry.cpp @@ -41,6 +41,9 @@ OsdGLDrawConfig::~OsdGLDrawConfig() static const char *commonShaderSource = #include "glslPatchCommon.inc" ; +static const char *ptexShaderSource = +#include "glslPtexCommon.inc" +; static const char *bsplineShaderSource = #include "glslPatchBSpline.inc" ; @@ -55,12 +58,18 @@ static const char *transitionShaderSource = OsdGLDrawRegistryBase::~OsdGLDrawRegistryBase() {} OsdGLDrawSourceConfig * -OsdGLDrawRegistryBase::_CreateDrawSourceConfig(OsdDrawContext::PatchDescriptor const & desc) +OsdGLDrawRegistryBase::_CreateDrawSourceConfig( + OsdDrawContext::PatchDescriptor const & desc) { OsdGLDrawSourceConfig * sconfig = _NewDrawSourceConfig(); #if defined(GL_ARB_tessellation_shader) || defined(GL_VERSION_4_0) sconfig->commonShader.source = commonShaderSource; + + if (IsPtexEnabled()) { + sconfig->commonShader.source += ptexShaderSource; + } + { std::ostringstream ss; ss << (int)desc.GetMaxValence(); diff --git a/opensubdiv/osd/glDrawRegistry.h b/opensubdiv/osd/glDrawRegistry.h index 5dbc4cd4..3ae8dd87 100644 --- a/opensubdiv/osd/glDrawRegistry.h +++ b/opensubdiv/osd/glDrawRegistry.h @@ -39,10 +39,10 @@ namespace OpenSubdiv { namespace OPENSUBDIV_VERSION { struct OsdGLDrawConfig : public OsdDrawConfig { + OsdGLDrawConfig() : - program(0), - primitiveIdBaseUniform(-1), - gregoryQuadOffsetBaseUniform(-1) {} + program(0), primitiveIdBaseUniform(-1), gregoryQuadOffsetBaseUniform(-1) { } + virtual ~OsdGLDrawConfig(); GLuint program; @@ -50,6 +50,8 @@ struct OsdGLDrawConfig : public OsdDrawConfig { GLint gregoryQuadOffsetBaseUniform; }; +//------------------------------------------------------------------------------ + struct OsdGLDrawSourceConfig : public OsdDrawSourceConfig { OsdDrawShaderSource commonShader; OsdDrawShaderSource vertexShader; @@ -59,41 +61,62 @@ struct OsdGLDrawSourceConfig : public OsdDrawSourceConfig { OsdDrawShaderSource fragmentShader; }; -//////////////////////////////////////////////////////////// +//------------------------------------------------------------------------------ class OsdGLDrawRegistryBase { + public: typedef OsdDrawContext::PatchDescriptor DescType; typedef OsdGLDrawConfig ConfigType; typedef OsdGLDrawSourceConfig SourceConfigType; + OsdGLDrawRegistryBase(bool enablePtex=false) : _enablePtex(enablePtex) { } + virtual ~OsdGLDrawRegistryBase(); -protected: - virtual ConfigType * _NewDrawConfig() { return new ConfigType(); } - virtual ConfigType * - _CreateDrawConfig(DescType const & desc, - SourceConfigType const * sconfig); + bool IsPtexEnabled() const { + return _enablePtex; + } + + void SetPtexEnabled(bool b) { + _enablePtex=b; + } - virtual SourceConfigType * _NewDrawSourceConfig() { return new SourceConfigType(); } - virtual SourceConfigType * - _CreateDrawSourceConfig(DescType const & desc); +protected: + virtual ConfigType * _NewDrawConfig() { + return new ConfigType(); + } + + virtual ConfigType * _CreateDrawConfig(DescType const & desc, + SourceConfigType const * sconfig); + + virtual SourceConfigType * _NewDrawSourceConfig() { + return new SourceConfigType(); + } + + virtual SourceConfigType * _CreateDrawSourceConfig(DescType const & desc); + +private: + bool _enablePtex; }; +//------------------------------------------------------------------------------ + template -class OsdGLDrawRegistry : public OsdGLDrawRegistryBase { -public: - typedef OsdGLDrawRegistryBase BaseRegistry; +class OsdGLDrawRegistry : public OsdGLDrawRegistryBase { + +public: typedef DESC_TYPE DescType; typedef CONFIG_TYPE ConfigType; typedef SOURCE_CONFIG_TYPE SourceConfigType; + typedef OsdGLDrawRegistryBase BaseRegistry; + typedef std::map ConfigMap; -public: virtual ~OsdGLDrawRegistry() { Reset(); } @@ -107,8 +130,8 @@ public: } // fetch shader config - ConfigType * - GetDrawConfig(DescType const & desc) { + ConfigType * GetDrawConfig(DescType const & desc) { + typename ConfigMap::iterator it = _configMap.find(desc); if (it != _configMap.end()) { return it->second; @@ -121,14 +144,22 @@ public: } protected: - virtual ConfigType * _NewDrawConfig() { return new ConfigType(); } - virtual ConfigType * - _CreateDrawConfig(DescType const & desc, - SourceConfigType const * sconfig) { return NULL; } + virtual ConfigType * _NewDrawConfig() { + return new ConfigType(); + } + + virtual ConfigType * _CreateDrawConfig(DescType const & desc, + SourceConfigType const * sconfig) { + return NULL; + } - virtual SourceConfigType * _NewDrawSourceConfig() { return new SourceConfigType(); } - virtual SourceConfigType * - _CreateDrawSourceConfig(DescType const & desc) { return NULL; } + virtual SourceConfigType * _NewDrawSourceConfig() { + return new SourceConfigType(); + } + + virtual SourceConfigType * _CreateDrawSourceConfig(DescType const & desc) { + return NULL; + } private: ConfigMap _configMap; diff --git a/opensubdiv/osd/glslPtexCommon.glsl b/opensubdiv/osd/glslPtexCommon.glsl new file mode 100644 index 00000000..824c080c --- /dev/null +++ b/opensubdiv/osd/glslPtexCommon.glsl @@ -0,0 +1,355 @@ +// +// Copyright 2013 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// + +//---------------------------------------------------------- +// Ptex.Common +//---------------------------------------------------------- + +struct PtexPacking { + int page; + int nMipmap; + int uOffset; + int vOffset; + int adjSizeDiffs[4]; + int width; + int height; +}; + +PtexPacking getPtexPacking(isamplerBuffer packings, int faceID) +{ + PtexPacking packing; + 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; +} + +int computeMipmapOffsetU(int w, int level) +{ + int width = 1 << w; + int m = (0x55555555 & (width | (width-1))) << (w&1); + int x = ~((1 << (w -((level-1)&~1))) - 1); + return (m & x) + ((level+1)&~1); +} + +int computeMipmapOffsetV(int h, int level) +{ + int height = 1 << h; + int m = (0x55555555 & (height-1)) << ((h+1)&1);; + int x = ~((1 << (h - (level&~1))) - 1 ); + return (m & x) + (level&~1); +} + +PtexPacking getPtexPacking(isamplerBuffer packings, int faceID, int level) +{ + PtexPacking packing; + 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; + + // clamp max level + level = min(level, packing.nMipmap); + + packing.uOffset += computeMipmapOffsetU(w, level); + packing.vOffset += computeMipmapOffsetV(h, level); + packing.width = 1 << (w-level); + packing.height = 1 << (h-level); + + return packing; +} + +void evalQuadraticBSpline(float u, out float B[3], out float BU[3]) +{ + B[0] = 0.5 * (u*u - 2.0*u + 1); + B[1] = 0.5 + u - u*u; + B[2] = 0.5 * u*u; + + BU[0] = u - 1.0; + BU[1] = 1 - 2 * u; + BU[2] = u; +} + +// ---------------------------------------------------------------------------- +// Non-Mipmap Lookups +// ---------------------------------------------------------------------------- + +vec4 PtexLookupNearest(vec4 patchCoord, + sampler2DArray data, + isamplerBuffer packings) +{ + vec2 uv = patchCoord.xy; + int faceID = int(patchCoord.w); + PtexPacking ppack = getPtexPacking(packings, faceID); + 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 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) +{ + vec2 uv = patchCoord.xy; + int faceID = int(patchCoord.w); + PtexPacking ppack = getPtexPacking(packings, faceID); + + ivec3 size = textureSize(data, 0); + vec2 coords = vec2((uv.x * ppack.width + ppack.uOffset)/size.x, + (uv.y * ppack.height + ppack.vOffset)/size.y); + return texture(data, vec3(coords.x, coords.y, ppack.page)); +} + +vec4 PtexLookupFast(vec4 patchCoord, + int level, + sampler2DArray data, + isamplerBuffer packings) +{ + vec2 uv = patchCoord.xy; + int faceID = int(patchCoord.w); + PtexPacking ppack = getPtexPacking(packings, faceID, level); + + ivec3 size = textureSize(data, 0); + vec2 coords = vec2((uv.x * ppack.width + ppack.uOffset)/size.x, + (uv.y * ppack.height + ppack.vOffset)/size.y); + return texture(data, vec3(coords.x, coords.y, ppack.page)); +} + +vec4 PtexLookup(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); + + coords -= vec2(0.5, 0.5); + + int c0X = int(floor(coords.x)); + int c1X = int(ceil(coords.x)); + int c0Y = int(floor(coords.y)); + int c1Y = int(ceil(coords.y)); + + float t = coords.x - float(c0X); + float s = coords.y - float(c0Y); + + vec4 d0 = texelFetch(data, ivec3(c0X, c0Y, ppack.page), 0); + vec4 d1 = texelFetch(data, ivec3(c0X, c1Y, ppack.page), 0); + vec4 d2 = texelFetch(data, ivec3(c1X, c0Y, ppack.page), 0); + vec4 d3 = texelFetch(data, ivec3(c1X, c1Y, ppack.page), 0); + + vec4 result = (1-t) * ((1-s)*d0 + s*d1) + t * ((1-s)*d2 + s*d3); + + return result; +} + +vec4 PtexLookupQuadratic(out vec4 du, + out vec4 dv, + 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); + + coords -= vec2(0.5, 0.5); + + int cX = int(round(coords.x)); + int cY = int(round(coords.y)); + + float x = 0.5 - (float(cX) - coords.x); + float y = 0.5 - (float(cY) - coords.y); + + vec4 d[9]; + d[0] = texelFetch(data, ivec3(cX-1, cY-1, ppack.page), 0); + d[1] = texelFetch(data, ivec3(cX-1, cY-0, ppack.page), 0); + d[2] = texelFetch(data, ivec3(cX-1, cY+1, ppack.page), 0); + d[3] = texelFetch(data, ivec3(cX-0, cY-1, ppack.page), 0); + d[4] = texelFetch(data, ivec3(cX-0, cY-0, ppack.page), 0); + d[5] = texelFetch(data, ivec3(cX-0, cY+1, ppack.page), 0); + d[6] = texelFetch(data, ivec3(cX+1, cY-1, ppack.page), 0); + d[7] = texelFetch(data, ivec3(cX+1, cY-0, ppack.page), 0); + d[8] = texelFetch(data, ivec3(cX+1, cY+1, ppack.page), 0); + + float B[3], D[3]; + vec4 BUCP[3], DUCP[3]; + evalQuadraticBSpline(y, B, D); + + for (int i = 0; i < 3; ++i) { + BUCP[i] = vec4(0); + DUCP[i] = vec4(0); + for (int j = 0; j < 3; j++) { + vec4 A = d[i*3+j]; + BUCP[i] += A * B[j]; + DUCP[i] += A * D[j]; + } + } + + evalQuadraticBSpline(x, B, D); + + vec4 result = vec4(0); + du = vec4(0); + dv = vec4(0); + for (int i = 0; i < 3; ++i) { + result += B[i] * BUCP[i]; + du += D[i] * BUCP[i]; + dv += B[i] * DUCP[i]; + } + + du *= ppack.width; + dv *= ppack.height; + + return result; +} + +// ---------------------------------------------------------------------------- +// MipMap Lookups +// ---------------------------------------------------------------------------- +vec4 PtexMipmapLookupNearest(vec4 patchCoord, + float level, + sampler2DArray data, + isamplerBuffer packings) +{ +#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)); + float t = level - float(levelm); + + vec4 result = (1-t) * PtexLookupNearest(patchCoord, levelm, data, packings) + + t * PtexLookupNearest(patchCoord, levelp, data, packings); + return result; +} + + +vec4 PtexMipmapLookup(vec4 patchCoord, + float level, + sampler2DArray data, + isamplerBuffer packings) +{ +#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)); + float t = level - float(levelm); + + vec4 result = (1-t) * PtexLookup(patchCoord, levelm, data, packings) + + t * PtexLookup(patchCoord, levelp, data, packings); + return result; +} + +vec4 PtexMipmapLookupQuadratic(out vec4 du, + out vec4 dv, + vec4 patchCoord, + float level, + sampler2DArray data, + isamplerBuffer packings) +{ +#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)); + float t = level - float(levelm); + + vec4 du0, du1, dv0, dv1; + vec4 r0 = PtexLookupQuadratic(du0, dv0, patchCoord, levelm, data, packings); + vec4 r1 = PtexLookupQuadratic(du1, dv1, patchCoord, levelp, data, packings); + + vec4 result = mix(r0, r1, t); + du = mix(du0, du1, t); + dv = mix(dv0, dv1, t); + + return result; +} + +vec4 PtexMipmapLookupQuadratic(vec4 patchCoord, + float level, + sampler2DArray data, + isamplerBuffer packings) +{ + vec4 du, dv; + return PtexMipmapLookupQuadratic(du, dv, patchCoord, level, data, packings); +} + diff --git a/opensubdiv/osd/hlslPtexCommon.hlsl b/opensubdiv/osd/hlslPtexCommon.hlsl new file mode 100644 index 00000000..da094d29 --- /dev/null +++ b/opensubdiv/osd/hlslPtexCommon.hlsl @@ -0,0 +1,326 @@ +// +// Copyright 2013 Pixar +// +// Licensed under the Apache License, Version 2.0 (the "Apache License") +// with the following modification; you may not use this file except in +// compliance with the Apache License and the following modification to it: +// Section 6. Trademarks. is deleted and replaced with: +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor +// and its affiliates, except as required to comply with Section 4(c) of +// the License and to reproduce the content of the NOTICE file. +// +// You may obtain a copy of the Apache License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the Apache License with the above modification is +// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the Apache License for the specific +// language governing permissions and limitations under the Apache License. +// + +//---------------------------------------------------------- +// Ptex.Common +//---------------------------------------------------------- + +struct PtexPacking { + int page; + int nMipmap; + int uOffset; + int vOffset; + int adjSizeDiffs[4]; + int width; + int height; +}; + +PtexPacking getPtexPacking(Buffer packings, int faceID) +{ + PtexPacking packing; + 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; +} + +int computeMipmapOffsetU(int w, int level) +{ + int width = 1 << w; + int m = (0x55555555 & (width | (width-1))) << (w&1); + int x = ~((1 << (w -((level-1)&~1))) - 1); + return (m & x) + ((level+1)&~1); +} + +int computeMipmapOffsetV(int h, int level) +{ + int height = 1 << h; + int m = (0x55555555 & (height-1)) << ((h+1)&1);; + int x = ~((1 << (h - (level&~1))) - 1 ); + return (m & x) + (level&~1); +} + +PtexPacking getPtexPacking(Buffer packings, int faceID, int level) +{ + PtexPacking packing; + 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 sizeDiffs = packings[faceID*6+4].x; + int wh = packings[faceID*6+5].x; + int w = wh >> 8; + int h = wh & 0xff; + + // clamp max level + level = min(level, packing.nMipmap); + + packing.uOffset += computeMipmapOffsetU(w, level); + packing.vOffset += computeMipmapOffsetV(h, level); + packing.width = 1 << (w-level); + packing.height = 1 << (h-level); + + return packing; +} + +void evalQuadraticBSpline(float u, out float B[3], out float BU[3]) +{ + B[0] = 0.5 * (u*u - 2.0*u + 1); + B[1] = 0.5 + u - u*u; + B[2] = 0.5 * u*u; + + BU[0] = u - 1.0; + BU[1] = 1 - 2 * u; + BU[2] = u; +} + +// ---------------------------------------------------------------------------- +// Non-Mipmap Lookups +// ---------------------------------------------------------------------------- + +float4 PtexLookupNearest(float4 patchCoord, + Texture2DArray data, + Buffer packings) +{ + float2 uv = patchCoord.xy; + int faceID = int(patchCoord.w); + PtexPacking ppack = getPtexPacking(packings, faceID); + float2 coords = float2(uv.x * ppack.width + ppack.uOffset, + uv.y * ppack.height + ppack.vOffset); + return data[int3(int(coords.x), int(coords.y), ppack.page)]; +} + +float4 PtexLookupNearest(float4 patchCoord, + int level, + Texture2DArray data, + Buffer packings) +{ + float2 uv = patchCoord.xy; + int faceID = int(patchCoord.w); + PtexPacking ppack = getPtexPacking(packings, faceID, level); + float2 coords = float2(uv.x * ppack.width + ppack.uOffset, + uv.y * ppack.height + ppack.vOffset); + return data[int3(int(coords.x), int(coords.y), ppack.page)]; +} + +float4 PtexLookup(float4 patchCoord, + int level, + Texture2DArray data, + Buffer packings) +{ + float2 uv = patchCoord.xy; + int faceID = int(patchCoord.w); + PtexPacking ppack = getPtexPacking(packings, faceID, level); + + float2 coords = float2(uv.x * ppack.width + ppack.uOffset, + uv.y * ppack.height + ppack.vOffset); + + coords -= float2(0.5, 0.5); + + int c0X = int(floor(coords.x)); + int c1X = int(ceil(coords.x)); + int c0Y = int(floor(coords.y)); + int c1Y = int(ceil(coords.y)); + + float t = coords.x - float(c0X); + float s = coords.y - float(c0Y); + + float4 d0 = data[int3(c0X, c0Y, ppack.page)]; + float4 d1 = data[int3(c0X, c1Y, ppack.page)]; + float4 d2 = data[int3(c1X, c0Y, ppack.page)]; + float4 d3 = data[int3(c1X, c1Y, ppack.page)]; + + float4 result = (1-t) * ((1-s)*d0 + s*d1) + t * ((1-s)*d2 + s*d3); + + return result; +} + +float4 PtexLookupQuadratic(out float4 du, + out float4 dv, + float4 patchCoord, + int level, + Texture2DArray data, + Buffer packings) +{ + float2 uv = patchCoord.xy; + int faceID = int(patchCoord.w); + PtexPacking ppack = getPtexPacking(packings, faceID, level); + + float2 coords = float2(uv.x * ppack.width + ppack.uOffset, + uv.y * ppack.height + ppack.vOffset); + + coords -= float2(0.5, 0.5); + + int cX = int(round(coords.x)); + int cY = int(round(coords.y)); + + float x = 0.5 - (float(cX) - coords.x); + float y = 0.5 - (float(cY) - coords.y); + + float4 d[9]; + d[0] = data[int3(cX-1, cY-1, ppack.page)]; + d[1] = data[int3(cX-1, cY-0, ppack.page)]; + d[2] = data[int3(cX-1, cY+1, ppack.page)]; + d[3] = data[int3(cX-0, cY-1, ppack.page)]; + d[4] = data[int3(cX-0, cY-0, ppack.page)]; + d[5] = data[int3(cX-0, cY+1, ppack.page)]; + d[6] = data[int3(cX+1, cY-1, ppack.page)]; + d[7] = data[int3(cX+1, cY-0, ppack.page)]; + d[8] = data[int3(cX+1, cY+1, ppack.page)]; + + float B[3], D[3]; + float4 BUCP[3], DUCP[3]; + evalQuadraticBSpline(y, B, D); + + for (int i = 0; i < 3; ++i) { + BUCP[i] = float4(0, 0, 0, 0); + DUCP[i] = float4(0, 0, 0, 0); + for (int j = 0; j < 3; j++) { + float4 A = d[i*3+j]; + BUCP[i] += A * B[j]; + DUCP[i] += A * D[j]; + } + } + + evalQuadraticBSpline(x, B, D); + + float4 result = float4(0, 0, 0, 0); + du = float4(0, 0, 0, 0); + dv = float4(0, 0, 0, 0); + for (int i = 0; i < 3; ++i) { + result += B[i] * BUCP[i]; + du += D[i] * BUCP[i]; + dv += B[i] * DUCP[i]; + } + + du *= ppack.width; + dv *= ppack.height; + + return result; +} + +// ---------------------------------------------------------------------------- +// MipMap Lookups +// ---------------------------------------------------------------------------- + +float4 PtexMipmapLookupNearest(float4 patchCoord, + int level, + Texture2DArray data, + Buffer packings) +{ +#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)); + float t = level - float(levelm); + + float4 result = (1-t) * PtexLookupNearest(patchCoord, levelm, data, packings) + + t * PtexLookupNearest(patchCoord, levelp, data, packings); + return result; +} + +float4 PtexMipmapLookup(float4 patchCoord, + float level, + Texture2DArray data, + Buffer packings) +{ +#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)); + float t = level - float(levelm); + + float4 result = (1-t) * PtexLookup(patchCoord, levelm, data, packings) + + t * PtexLookup(patchCoord, levelp, data, packings); + return result; +} + +float4 PtexMipmapLookupQuadratic(out float4 du, + out float4 dv, + float4 patchCoord, + float level, + Texture2DArray data, + Buffer packings) +{ +#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)); + float t = level - float(levelm); + + float4 du0, du1, dv0, dv1; + float4 r0 = PtexLookupQuadratic(du0, dv0, patchCoord, levelm, data, packings); + float4 r1 = PtexLookupQuadratic(du1, dv1, patchCoord, levelp, data, packings); + + float4 result = lerp(r0, r1, t); + du = lerp(du0, du1, t); + dv = lerp(dv0, dv1, t); + + return result; +} + +float4 PtexMipmapLookupQuadratic(float4 patchCoord, + float level, + Texture2DArray data, + Buffer packings) +{ + float4 du, dv; + return PtexMipmapLookupQuadratic(du, dv, patchCoord, level, data, packings); +} +