| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571 |
- /*
- Real-time DXT1 & YCoCg DXT5 compression (Cg 2.0)
- Copyright (c) NVIDIA Corporation.
- Written by: Ignacio Castano <icastano@nvidia.com>
- Thanks to JMP van Waveren, Simon Green, Eric Werness, Simon Brown
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation
- files (the "Software"), to deal in the Software without
- restriction, including without limitation the rights to use,
- copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following
- conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- */
- const char* pDXTCompressorShaderSource =
- " \n"
- "// vertex program \n"
- "void compress_vp(float4 pos : POSITION, \n"
- " float2 texcoord : TEXCOORD0, \n"
- " out float4 hpos : POSITION, \n"
- " out float2 o_texcoord : TEXCOORD0 \n"
- " ) \n"
- "{ \n"
- " o_texcoord = texcoord; \n"
- " hpos = pos; \n"
- "} \n"
- " \n"
- "typedef unsigned int uint; \n"
- "typedef unsigned int2 uint2; \n"
- "typedef unsigned int3 uint3; \n"
- "typedef unsigned int4 uint4; \n"
- " \n"
- "const float offset = 128.0 / 255.0; \n"
- " \n"
- "// Use dot product to minimize RMS instead absolute distance like in the CPU compressor. \n"
- "float colorDistance(float3 c0, float3 c1) \n"
- "{ \n"
- " return dot(c0-c1, c0-c1); \n"
- "} \n"
- "float colorDistance(float2 c0, float2 c1) \n"
- "{ \n"
- " return dot(c0-c1, c0-c1); \n"
- "} \n"
- " \n"
- " \n"
- "void ExtractColorBlockRGB(out float3 col[16], sampler2D image, float2 texcoord, float2 imageSize) \n"
- "{ \n"
- " // use TXF instruction (integer coordinates with offset) \n"
- " // note offsets must be constant \n"
- " //int4 base = int4(wpos*4-2, 0, 0); \n"
- " int4 base = int4(texcoord * imageSize - 1.5, 0, 0); \n"
- " col[0] = tex2Dfetch(image, base, int2(0, 0)).rgb; \n"
- " col[1] = tex2Dfetch(image, base, int2(1, 0)).rgb; \n"
- " col[2] = tex2Dfetch(image, base, int2(2, 0)).rgb; \n"
- " col[3] = tex2Dfetch(image, base, int2(3, 0)).rgb; \n"
- " col[4] = tex2Dfetch(image, base, int2(0, 1)).rgb; \n"
- " col[5] = tex2Dfetch(image, base, int2(1, 1)).rgb; \n"
- " col[6] = tex2Dfetch(image, base, int2(2, 1)).rgb; \n"
- " col[7] = tex2Dfetch(image, base, int2(3, 1)).rgb; \n"
- " col[8] = tex2Dfetch(image, base, int2(0, 2)).rgb; \n"
- " col[9] = tex2Dfetch(image, base, int2(1, 2)).rgb; \n"
- " col[10] = tex2Dfetch(image, base, int2(2, 2)).rgb; \n"
- " col[11] = tex2Dfetch(image, base, int2(3, 2)).rgb; \n"
- " col[12] = tex2Dfetch(image, base, int2(0, 3)).rgb; \n"
- " col[13] = tex2Dfetch(image, base, int2(1, 3)).rgb; \n"
- " col[14] = tex2Dfetch(image, base, int2(2, 3)).rgb; \n"
- " col[15] = tex2Dfetch(image, base, int2(3, 3)).rgb; \n"
- "} \n"
- " \n"
- "void ExtractColorBlockBGR(out float3 col[16], sampler2D image, float2 texcoord, float2 imageSize) \n"
- "{ \n"
- " // use TXF instruction (integer coordinates with offset) \n"
- " // note offsets must be constant \n"
- " //int4 base = int4(wpos*4-2, 0, 0); \n"
- " int4 base = int4(texcoord * imageSize - 1.5, 0, 0); \n"
- " col[0] = tex2Dfetch(image, base, int2(0, 0)).bgr; \n"
- " col[1] = tex2Dfetch(image, base, int2(1, 0)).bgr; \n"
- " col[2] = tex2Dfetch(image, base, int2(2, 0)).bgr; \n"
- " col[3] = tex2Dfetch(image, base, int2(3, 0)).bgr; \n"
- " col[4] = tex2Dfetch(image, base, int2(0, 1)).bgr; \n"
- " col[5] = tex2Dfetch(image, base, int2(1, 1)).bgr; \n"
- " col[6] = tex2Dfetch(image, base, int2(2, 1)).bgr; \n"
- " col[7] = tex2Dfetch(image, base, int2(3, 1)).bgr; \n"
- " col[8] = tex2Dfetch(image, base, int2(0, 2)).bgr; \n"
- " col[9] = tex2Dfetch(image, base, int2(1, 2)).bgr; \n"
- " col[10] = tex2Dfetch(image, base, int2(2, 2)).bgr; \n"
- " col[11] = tex2Dfetch(image, base, int2(3, 2)).bgr; \n"
- " col[12] = tex2Dfetch(image, base, int2(0, 3)).bgr; \n"
- " col[13] = tex2Dfetch(image, base, int2(1, 3)).bgr; \n"
- " col[14] = tex2Dfetch(image, base, int2(2, 3)).bgr; \n"
- " col[15] = tex2Dfetch(image, base, int2(3, 3)).bgr; \n"
- "} \n"
- " \n"
- "float3 toYCoCg(float3 c) \n"
- "{ \n"
- " float Y = (c.r + 2 * c.g + c.b) * 0.25; \n"
- " float Co = ( ( 2 * c.r - 2 * c.b ) * 0.25 + offset ); \n"
- " float Cg = ( ( -c.r + 2 * c.g - c.b) * 0.25 + offset ); \n"
- " \n"
- " return float3(Y, Co, Cg); \n"
- "} \n"
- " \n"
- "void ExtractColorBlockYCoCg_RGB(out float3 col[16], sampler2D image, float2 texcoord, float2 imageSize) \n"
- "{ \n"
- " // use TXF instruction (integer coordinates with offset) \n"
- " // note offsets must be constant \n"
- " //int4 base = int4(wpos*4-2, 0, 0); \n"
- " int4 base = int4(texcoord * imageSize - 1.5, 0, 0); \n"
- " col[0] = toYCoCg(tex2Dfetch(image, base, int2(0, 0)).rgb); \n"
- " col[1] = toYCoCg(tex2Dfetch(image, base, int2(1, 0)).rgb); \n"
- " col[2] = toYCoCg(tex2Dfetch(image, base, int2(2, 0)).rgb); \n"
- " col[3] = toYCoCg(tex2Dfetch(image, base, int2(3, 0)).rgb); \n"
- " col[4] = toYCoCg(tex2Dfetch(image, base, int2(0, 1)).rgb); \n"
- " col[5] = toYCoCg(tex2Dfetch(image, base, int2(1, 1)).rgb); \n"
- " col[6] = toYCoCg(tex2Dfetch(image, base, int2(2, 1)).rgb); \n"
- " col[7] = toYCoCg(tex2Dfetch(image, base, int2(3, 1)).rgb); \n"
- " col[8] = toYCoCg(tex2Dfetch(image, base, int2(0, 2)).rgb); \n"
- " col[9] = toYCoCg(tex2Dfetch(image, base, int2(1, 2)).rgb); \n"
- " col[10] = toYCoCg(tex2Dfetch(image, base, int2(2, 2)).rgb); \n"
- " col[11] = toYCoCg(tex2Dfetch(image, base, int2(3, 2)).rgb); \n"
- " col[12] = toYCoCg(tex2Dfetch(image, base, int2(0, 3)).rgb); \n"
- " col[13] = toYCoCg(tex2Dfetch(image, base, int2(1, 3)).rgb); \n"
- " col[14] = toYCoCg(tex2Dfetch(image, base, int2(2, 3)).rgb); \n"
- " col[15] = toYCoCg(tex2Dfetch(image, base, int2(3, 3)).rgb); \n"
- "} \n"
- " \n"
- "void ExtractColorBlockYCoCg_BGR(out float3 col[16], sampler2D image, float2 texcoord, float2 imageSize) \n"
- "{ \n"
- " // use TXF instruction (integer coordinates with offset) \n"
- " // note offsets must be constant \n"
- " //int4 base = int4(wpos*4-2, 0, 0); \n"
- " int4 base = int4(texcoord * imageSize - 1.5, 0, 0); \n"
- " col[0] = toYCoCg(tex2Dfetch(image, base, int2(0, 0)).bgr); \n"
- " col[1] = toYCoCg(tex2Dfetch(image, base, int2(1, 0)).bgr); \n"
- " col[2] = toYCoCg(tex2Dfetch(image, base, int2(2, 0)).bgr); \n"
- " col[3] = toYCoCg(tex2Dfetch(image, base, int2(3, 0)).bgr); \n"
- " col[4] = toYCoCg(tex2Dfetch(image, base, int2(0, 1)).bgr); \n"
- " col[5] = toYCoCg(tex2Dfetch(image, base, int2(1, 1)).bgr); \n"
- " col[6] = toYCoCg(tex2Dfetch(image, base, int2(2, 1)).bgr); \n"
- " col[7] = toYCoCg(tex2Dfetch(image, base, int2(3, 1)).bgr); \n"
- " col[8] = toYCoCg(tex2Dfetch(image, base, int2(0, 2)).bgr); \n"
- " col[9] = toYCoCg(tex2Dfetch(image, base, int2(1, 2)).bgr); \n"
- " col[10] = toYCoCg(tex2Dfetch(image, base, int2(2, 2)).bgr); \n"
- " col[11] = toYCoCg(tex2Dfetch(image, base, int2(3, 2)).bgr); \n"
- " col[12] = toYCoCg(tex2Dfetch(image, base, int2(0, 3)).bgr); \n"
- " col[13] = toYCoCg(tex2Dfetch(image, base, int2(1, 3)).bgr); \n"
- " col[14] = toYCoCg(tex2Dfetch(image, base, int2(2, 3)).bgr); \n"
- " col[15] = toYCoCg(tex2Dfetch(image, base, int2(3, 3)).bgr); \n"
- "} \n"
- " \n"
- "// find minimum and maximum colors based on bounding box in color space \n"
- "void FindMinMaxColorsBox(float3 block[16], out float3 mincol, out float3 maxcol) \n"
- "{ \n"
- " mincol = block[0]; \n"
- " maxcol = block[0]; \n"
- " \n"
- " for (int i = 1; i < 16; i++) { \n"
- " mincol = min(mincol, block[i]); \n"
- " maxcol = max(maxcol, block[i]); \n"
- " } \n"
- "} \n"
- " \n"
- "void InsetBBox(in out float3 mincol, in out float3 maxcol) \n"
- "{ \n"
- " float3 inset = (maxcol - mincol) / 16.0 - (8.0 / 255.0) / 16; \n"
- " mincol = saturate(mincol + inset); \n"
- " maxcol = saturate(maxcol - inset); \n"
- "} \n"
- "void InsetYBBox(in out float mincol, in out float maxcol) \n"
- "{ \n"
- " float inset = (maxcol - mincol) / 32.0 - (16.0 / 255.0) / 32.0; \n"
- " mincol = saturate(mincol + inset); \n"
- " maxcol = saturate(maxcol - inset); \n"
- "} \n"
- "void InsetCoCgBBox(in out float2 mincol, in out float2 maxcol) \n"
- "{ \n"
- " float2 inset = (maxcol - mincol) / 16.0 - (8.0 / 255.0) / 16; \n"
- " mincol = saturate(mincol + inset); \n"
- " maxcol = saturate(maxcol - inset); \n"
- "} \n"
- " \n"
- "void SelectDiagonal(float3 block[16], in out float3 mincol, in out float3 maxcol) \n"
- "{ \n"
- " float3 center = (mincol + maxcol) * 0.5; \n"
- " \n"
- " float2 cov = 0; \n"
- " for (int i = 0; i < 16; i++) \n"
- " { \n"
- " float3 t = block[i] - center; \n"
- " cov.x += t.x * t.z; \n"
- " cov.y += t.y * t.z; \n"
- " } \n"
- " \n"
- " if (cov.x < 0) { \n"
- " float temp = maxcol.x; \n"
- " maxcol.x = mincol.x; \n"
- " mincol.x = temp; \n"
- " } \n"
- " if (cov.y < 0) { \n"
- " float temp = maxcol.y; \n"
- " maxcol.y = mincol.y; \n"
- " mincol.y = temp; \n"
- " } \n"
- "} \n"
- " \n"
- "float3 RoundAndExpand(float3 v, out uint w) \n"
- "{ \n"
- " int3 c = round(v * float3(31, 63, 31)); \n"
- " w = (c.r << 11) | (c.g << 5) | c.b; \n"
- " \n"
- " c.rb = (c.rb << 3) | (c.rb >> 2); \n"
- " c.g = (c.g << 2) | (c.g >> 4); \n"
- " \n"
- " return (float3)c * (1.0 / 255.0); \n"
- "} \n"
- " \n"
- "uint EmitEndPointsDXT1(in out float3 mincol, in out float3 maxcol) \n"
- "{ \n"
- " uint2 output; \n"
- " maxcol = RoundAndExpand(maxcol, output.x); \n"
- " mincol = RoundAndExpand(mincol, output.y); \n"
- " \n"
- " // We have to do this in case we select an alternate diagonal. \n"
- " if (output.x < output.y) \n"
- " { \n"
- " float3 tmp = mincol; \n"
- " mincol = maxcol; \n"
- " maxcol = tmp; \n"
- " return output.y | (output.x << 16); \n"
- " } \n"
- " \n"
- " return output.x | (output.y << 16); \n"
- "} \n"
- " \n"
- "uint EmitIndicesDXT1(float3 block[16], float3 mincol, float3 maxcol) \n"
- "{ \n"
- " const float RGB_RANGE = 3; \n"
- " \n"
- " float3 dir = (maxcol - mincol); \n"
- " float3 origin = maxcol + dir / (2.0 * RGB_RANGE); \n"
- " dir /= dot(dir, dir); \n"
- " \n"
- " // Compute indices \n"
- " uint indices = 0; \n"
- " for (int i = 0; i < 16; i++) \n"
- " { \n"
- " uint index = saturate(dot(origin - block[i], dir)) * RGB_RANGE; \n"
- " indices |= index << (i * 2); \n"
- " } \n"
- " \n"
- " uint i0 = (indices & 0x55555555); \n"
- " uint i1 = (indices & 0xAAAAAAAA) >> 1; \n"
- " indices = ((i0 ^ i1) << 1) | i1; \n"
- " \n"
- " // Output indices \n"
- " return indices; \n"
- "} \n"
- " \n"
- "int ScaleYCoCg(float2 minColor, float2 maxColor) \n"
- "{ \n"
- " float2 m0 = abs(minColor - offset); \n"
- " float2 m1 = abs(maxColor - offset); \n"
- " \n"
- " float m = max(max(m0.x, m0.y), max(m1.x, m1.y)); \n"
- " \n"
- " const float s0 = 64.0 / 255.0; \n"
- " const float s1 = 32.0 / 255.0; \n"
- " \n"
- " int scale = 1; \n"
- " if (m < s0) scale = 2; \n"
- " if (m < s1) scale = 4; \n"
- " \n"
- " return scale; \n"
- "} \n"
- " \n"
- "void SelectYCoCgDiagonal(const float3 block[16], in out float2 minColor, in out float2 maxColor) \n"
- "{ \n"
- " float2 mid = (maxColor + minColor) * 0.5; \n"
- " \n"
- " float cov = 0; \n"
- " for (int i = 0; i < 16; i++) \n"
- " { \n"
- " float2 t = block[i].yz - mid; \n"
- " cov += t.x * t.y; \n"
- " } \n"
- " if (cov < 0) { \n"
- " float tmp = maxColor.y; \n"
- " maxColor.y = minColor.y; \n"
- " minColor.y = tmp; \n"
- " } \n"
- "} \n"
- " \n"
- " \n"
- "uint EmitEndPointsYCoCgDXT5(in out float2 mincol, in out float2 maxcol, int scale) \n"
- "{ \n"
- " maxcol = (maxcol - offset) * scale + offset; \n"
- " mincol = (mincol - offset) * scale + offset; \n"
- " \n"
- " InsetCoCgBBox(mincol, maxcol); \n"
- " \n"
- " maxcol = round(maxcol * float2(31, 63)); \n"
- " mincol = round(mincol * float2(31, 63)); \n"
- " \n"
- " int2 imaxcol = maxcol; \n"
- " int2 imincol = mincol; \n"
- " \n"
- " uint2 output; \n"
- " output.x = (imaxcol.r << 11) | (imaxcol.g << 5) | (scale - 1); \n"
- " output.y = (imincol.r << 11) | (imincol.g << 5) | (scale - 1); \n"
- " \n"
- " imaxcol.r = (imaxcol.r << 3) | (imaxcol.r >> 2); \n"
- " imaxcol.g = (imaxcol.g << 2) | (imaxcol.g >> 4); \n"
- " imincol.r = (imincol.r << 3) | (imincol.r >> 2); \n"
- " imincol.g = (imincol.g << 2) | (imincol.g >> 4); \n"
- " \n"
- " maxcol = (float2)imaxcol * (1.0 / 255.0); \n"
- " mincol = (float2)imincol * (1.0 / 255.0); \n"
- " \n"
- " // Undo rescale. \n"
- " maxcol = (maxcol - offset) / scale + offset; \n"
- " mincol = (mincol - offset) / scale + offset; \n"
- " \n"
- " return output.x | (output.y << 16); \n"
- "} \n"
- " \n"
- "uint EmitIndicesYCoCgDXT5(float3 block[16], float2 mincol, float2 maxcol) \n"
- "{ \n"
- " const float COCG_RANGE = 3; \n"
- " \n"
- " float2 dir = (maxcol - mincol); \n"
- " float2 origin = maxcol + dir / (2.0 * COCG_RANGE); \n"
- " dir /= dot(dir, dir); \n"
- " \n"
- " // Compute indices \n"
- " uint indices = 0; \n"
- " for (int i = 0; i < 16; i++) \n"
- " { \n"
- " uint index = saturate(dot(origin - block[i].yz, dir)) * COCG_RANGE; \n"
- " indices |= index << (i * 2); \n"
- " } \n"
- " \n"
- " uint i0 = (indices & 0x55555555); \n"
- " uint i1 = (indices & 0xAAAAAAAA) >> 1; \n"
- " indices = ((i0 ^ i1) << 1) | i1; \n"
- " \n"
- " // Output indices \n"
- " return indices; \n"
- "} \n"
- " \n"
- "uint EmitAlphaEndPointsYCoCgDXT5(float mincol, float maxcol) \n"
- "{ \n"
- " uint c0 = round(mincol * 255); \n"
- " uint c1 = round(maxcol * 255); \n"
- " \n"
- " return (c0 << 8) | c1; \n"
- "} \n"
- " \n"
- "// Optimized index selection. \n"
- "uint2 EmitAlphaIndicesYCoCgDXT5(float3 block[16], float minAlpha, float maxAlpha) \n"
- "{ \n"
- " const int ALPHA_RANGE = 7; \n"
- " \n"
- " float bias = maxAlpha + (maxAlpha - minAlpha) / (2.0 * ALPHA_RANGE); \n"
- " float scale = 1.0f / (maxAlpha - minAlpha); \n"
- " \n"
- " uint2 indices = 0; \n"
- " \n"
- " for (int i = 0; i < 6; i++) \n"
- " { \n"
- " uint index = saturate((bias - block[i].x) * scale) * ALPHA_RANGE; \n"
- " indices.x |= index << (3 * i); \n"
- " } \n"
- " \n"
- " for (int i = 6; i < 16; i++) \n"
- " { \n"
- " uint index = saturate((bias - block[i].x) * scale) * ALPHA_RANGE; \n"
- " indices.y |= index << (3 * i - 18); \n"
- " } \n"
- " \n"
- " uint2 i0 = (indices >> 0) & 0x09249249; \n"
- " uint2 i1 = (indices >> 1) & 0x09249249; \n"
- " uint2 i2 = (indices >> 2) & 0x09249249; \n"
- " \n"
- " i2 ^= i0 & i1; \n"
- " i1 ^= i0; \n"
- " i0 ^= (i1 | i2); \n"
- " \n"
- " indices.x = (i2.x << 2) | (i1.x << 1) | i0.x; \n"
- " indices.y = (((i2.y << 2) | (i1.y << 1) | i0.y) << 2) | (indices.x >> 16); \n"
- " indices.x <<= 16; \n"
- " \n"
- " return indices; \n"
- "} \n"
- " \n"
- "// compress a 4x4 block to DXT1 format \n"
- "// integer version, renders to 2 x int32 buffer \n"
- "uint4 compress_DXT1_RGBA_fp(float2 texcoord : TEXCOORD0, \n"
- " uniform sampler2D image, \n"
- " uniform float2 imageSize = { 512.0, 512.0 } \n"
- " ) : COLOR \n"
- "{ \n"
- " // read block \n"
- " float3 block[16]; \n"
- " ExtractColorBlockRGB(block, image, texcoord, imageSize); \n"
- " \n"
- " // find min and max colors \n"
- " float3 mincol, maxcol; \n"
- " FindMinMaxColorsBox(block, mincol, maxcol); \n"
- " \n"
- " SelectDiagonal(block, mincol, maxcol); \n"
- " \n"
- " InsetBBox(mincol, maxcol); \n"
- " \n"
- " uint4 output; \n"
- " output.x = EmitEndPointsDXT1(mincol, maxcol); \n"
- " output.w = EmitIndicesDXT1(block, mincol, maxcol); \n"
- " \n"
- " return output; \n"
- "} \n"
- " \n"
- "uint4 compress_DXT1_BGRA_fp(float2 texcoord : TEXCOORD0, \n"
- " uniform sampler2D image, \n"
- " uniform float2 imageSize = { 512.0, 512.0 } \n"
- " ) : COLOR \n"
- "{ \n"
- " // read block \n"
- " float3 block[16]; \n"
- " ExtractColorBlockBGR(block, image, texcoord, imageSize); \n"
- " \n"
- " // find min and max colors \n"
- " float3 mincol, maxcol; \n"
- " FindMinMaxColorsBox(block, mincol, maxcol); \n"
- " \n"
- " SelectDiagonal(block, mincol, maxcol); \n"
- " \n"
- " InsetBBox(mincol, maxcol); \n"
- " \n"
- " uint4 output; \n"
- " output.x = EmitEndPointsDXT1(mincol, maxcol); \n"
- " output.w = EmitIndicesDXT1(block, mincol, maxcol); \n"
- " \n"
- " return output; \n"
- "} \n"
- " \n"
- " \n"
- "// compress a 4x4 block to YCoCg DXT5 format \n"
- "// integer version, renders to 4 x int32 buffer \n"
- "uint4 compress_YCoCgDXT5_RGBA_fp(float2 texcoord : TEXCOORD0, \n"
- " uniform sampler2D image, \n"
- " uniform float2 imageSize = { 512.0, 512.0 } \n"
- " ) : COLOR \n"
- "{ \n"
- " //imageSize = tex2Dsize(image, texcoord); \n"
- " \n"
- " // read block \n"
- " float3 block[16]; \n"
- " ExtractColorBlockYCoCg_RGB(block, image, texcoord, imageSize); \n"
- " \n"
- " // find min and max colors \n"
- " float3 mincol, maxcol; \n"
- " FindMinMaxColorsBox(block, mincol, maxcol); \n"
- " \n"
- " SelectYCoCgDiagonal(block, mincol.yz, maxcol.yz); \n"
- " \n"
- " int scale = ScaleYCoCg(mincol.yz, maxcol.yz); \n"
- " \n"
- " // Output CoCg in DXT1 block. \n"
- " uint4 output; \n"
- " output.z = EmitEndPointsYCoCgDXT5(mincol.yz, maxcol.yz, scale); \n"
- " output.w = EmitIndicesYCoCgDXT5(block, mincol.yz, maxcol.yz); \n"
- " \n"
- " InsetYBBox(mincol.x, maxcol.x); \n"
- " \n"
- " // Output Y in DXT5 alpha block. \n"
- " output.x = EmitAlphaEndPointsYCoCgDXT5(mincol.x, maxcol.x); \n"
- " \n"
- " uint2 indices = EmitAlphaIndicesYCoCgDXT5(block, mincol.x, maxcol.x); \n"
- " output.x |= indices.x; \n"
- " output.y = indices.y; \n"
- " \n"
- " return output; \n"
- "} \n"
- " \n"
- "uint4 compress_YCoCgDXT5_BGRA_fp(float2 texcoord : TEXCOORD0, \n"
- " uniform sampler2D image, \n"
- " uniform float2 imageSize = { 512.0, 512.0 } \n"
- " ) : COLOR \n"
- "{ \n"
- " //imageSize = tex2Dsize(image, texcoord); \n"
- " \n"
- " // read block \n"
- " float3 block[16]; \n"
- " ExtractColorBlockYCoCg_BGR(block, image, texcoord, imageSize); \n"
- " \n"
- " // find min and max colors \n"
- " float3 mincol, maxcol; \n"
- " FindMinMaxColorsBox(block, mincol, maxcol); \n"
- " \n"
- " SelectYCoCgDiagonal(block, mincol.yz, maxcol.yz); \n"
- " \n"
- " int scale = ScaleYCoCg(mincol.yz, maxcol.yz); \n"
- " \n"
- " // Output CoCg in DXT1 block. \n"
- " uint4 output; \n"
- " output.z = EmitEndPointsYCoCgDXT5(mincol.yz, maxcol.yz, scale); \n"
- " output.w = EmitIndicesYCoCgDXT5(block, mincol.yz, maxcol.yz); \n"
- " \n"
- " InsetYBBox(mincol.x, maxcol.x); \n"
- " \n"
- " // Output Y in DXT5 alpha block. \n"
- " output.x = EmitAlphaEndPointsYCoCgDXT5(mincol.x, maxcol.x); \n"
- " \n"
- " uint2 indices = EmitAlphaIndicesYCoCgDXT5(block, mincol.x, maxcol.x); \n"
- " output.x |= indices.x; \n"
- " output.y = indices.y; \n"
- " \n"
- " return output; \n"
- "} \n"
- " \n"
- "uniform bool reconstructColor = false; \n"
- "uniform bool displayError = false; \n"
- "uniform float errorScale = 4.0f; \n"
- " \n"
- "uniform sampler2D image : TEXUNIT0; \n"
- "uniform sampler2D originalImage : TEXUNIT1; \n"
- " \n"
- "float4 display_fp(float2 texcoord : TEXCOORD0) : COLOR \n"
- "{ \n"
- " float4 rgba = tex2D(image, texcoord); \n"
- " \n"
- " if (reconstructColor) \n"
- " { \n"
- " float Y = rgba.a; \n"
- " float scale = 1.0 / ((255.0 / 8.0) * rgba.b + 1); \n"
- " float Co = (rgba.r - offset) * scale; \n"
- " float Cg = (rgba.g - offset) * scale; \n"
- " \n"
- " float R = Y + Co - Cg; \n"
- " float G = Y + Cg; \n"
- " float B = Y - Co - Cg; \n"
- " \n"
- " rgba = float4(R, G, B, 1); \n"
- " } \n"
- " \n"
- " if (displayError) \n"
- " { \n"
- " float3 originalColor = tex2D(originalImage, texcoord).rgb; \n"
- " float3 diff = abs(rgba.rgb - originalColor) * errorScale; \n"
- " return float4(diff, 1); \n"
- " } \n"
- " else \n"
- " { \n"
- " return rgba; \n"
- " } \n"
- "} \n"
- " \n";
|