!!ARBfp1.0 ############################### ## ## ## PolyCubeMap ## ## fragment shader ## ## ver 5.0 ## ## ## ## Visual Computing Lab ## ## ## ## 2004 marco tarini ## ## ## ############################### # more info about PolyCubeMaps at: o o # http://vcg.isti.cnr.it/polycubemaps/ o o # _ O _ # Copyright(C) 2004 \/)\/ # Visual Computing Lab http://vcg.isti.cnr.it /\/| # ISTI - Italian National Research Council | # \ # All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License (http://www.gnu.org/licenses/gpl.txt) # for more details. ATTRIB tc = fragment.texcoord; # 3d text coords # temporary values TEMP map,sub,res, expa,expb; # common expressions, TEMP tmp,tma,tmb, # temp values decoded, # used to store bit values try, tryA,tryB, try3,try5; # just some constants... PARAM consts = {1.99, 0.995, 1, 1}; # Binding of environment parameters ################################### PARAM text_coord_normalizer = program.env[0]; # must be {1/TEXT_SIZE_X, 1/TEXT_SIZE_Y, 0,0 } PARAM text_coord_normalizer_on_TS_times_255 = program.env[1]; # must be {255*HX, 255*HY , 0, 0}; # where HX = TS / TEXT_SIZE_X and HY = TS / TEXT_SIZE_Y # and TS is the squarelet size PARAM text_coord_normalizer_on_TS_0 = program.env[2]; # must be { HX, HY , 1, 0}; PARAM text_coord_normalizer_on_TS_1 = program.env[3]; # must be { HX, HY , 1, 1}; # find cell and position inside it ################################## # find 3D index of cubic cell FLR map, tc; # serialize the 3D index into a 2D index # (the 3D lookup table is stored in a subpart of the 2D texture) DP3 map.x, map, {1,0,16,0}; # texture access to the 3D lookup table # # aim at the center of texel. not needed? # ADD map,map, {0.5,0.5,0.0,0}; MAD map, map, text_coord_normalizer, {0,0,0,-1000}; TXB map, map, texture, 2D ; # get sub-coords (coords inside cubic cell), in [0..1)^3 FRC sub, tc; # put sub-coords in [-1..1)^3 MAD sub, sub, consts.x, -consts.y; # unpack and apply rotation ########################### # the rotation is stored in 1..5 bits of map.z # unpack 1st 2nd 3rd 4th bits of map.z MUL decoded, map.z, {128.0,64.0,32.0, 8.0}; # /2 /4 /8 /32 FRC decoded, decoded; SUB decoded, decoded, {0.49,0.49,0.49,0.234375}; # now decoded[i]>0 iff i-th bit is 1 #...apply rotation to sub-coords, like this: # if (rot&4) { tmp=x; x[0]=-tmp[2];x[1]=-tmp[1];x[2]=-tmp[0];}; # if (rot&8) { tmp=x; x[0]=tmp[1]; x[1]=tmp[2]; x[2]=tmp[0];}; # if (rot&16) { tmp=x; x[0]=tmp[1]; x[1]=tmp[2]; x[2]=tmp[0];}; # if (rot&1) { x[0]=-x[0]; x[1]=-x[1];}; # if (rot&2) { x[1]=-x[1]; x[2]=-x[2];}; SWZ tmp, sub, -z,-y,-x,0; CMP sub, decoded.z, sub, tmp; SWZ tmp, sub, y,z,x,0; CMP sub, decoded.w, sub, tmp; SWZ tmp, sub, y,z,x,0; SUB decoded.w, decoded.w, {0,0,0,0.375}; # quickly compute 5th bit (magic trick). CMP sub, decoded.w, sub, tmp; # testing 5th bit. MUL tmp, sub, {-1,-1,1,0}; CMP sub, decoded.x, sub, tmp; MUL tmp, sub, {1,-1,-1,0}; CMP sub, decoded.y, sub, tmp; # unpack and apply projection and mapping ######################################### # decode combination (it is stored in bits 6,7,8 of map.z) SUB decoded, {0.12375,0.24875,0.37375,0.49875}, map.z ; # after this: # if combiantion==0, decoded={+,+,+,+} C4a # if combiantion==1, decoded={-,+,+,+} C4b # if combiantion==2, decoded={-,-,+,+} C3 # if combiantion==3, decoded={-,-,-,+} C5 # if combiantion==4, decoded={-,-,-,-} ? (anything else) # case "C4a" MOV res, sub; # case "C4b" ADD expa.z, sub.x, sub.z; CMP expa.w, expa.z, -sub.z, sub.x; ADD expa.y, expa.w, {1,1,1,1}; RCP expa.y, expa.y; MUL expa.x, expa.z, expa.y; # expa = { (x+z)*(alfa), alfa=1/(1+x) or 1/(1-z), x+z, x or -z} CMP res.x, decoded.x, expa.x, res.x; # case "C3" ADD try3.y, sub.y, -expa.w; # try.y = (y-x or y+z) MUL try3.y, try3.y, expa.y; # try = ( ( (y-x or z+y)*alfa) CMP res.y, decoded.y, try3.y, res.y; # case "C5" ADD try5.y, sub.y, expa.w; SUB try5.z, {1,1,1,1}, expa.w; RCP try5.z, try5.z; MUL try5.y, try5.y, try5.z; # try = (y+x)/(1-x) or (y-z)/(1+z) CMP res.y, decoded.z, try5.y, res.y; # case "C3" or "C5" horizontal facelets # if (try.y>0...) SWZ expb, sub, z,-x,y,1; ADD expb, expb, sub.y; # expb = { y+z, y-x, 2y, 1+y} RCP expb.w, expb.w; # expb = { y+z, y-x, 2y, 1/(1+y)} CMP tma, expa.z, {0,-1,0,0}, {1, 0,0,0}; MUL tma, expa.x, tma; MAD tma, tma, expb.z, -expb.z; # tma.x (or y) = + (or -) 2y*(...) - 2y ADD tryA, expb, tma; # tryA=(z-y, -x-y) plus (or minus) 2y*(...) at right place MUL tryA, tryA, {-1,1,1,1}; # invert x CMP try, decoded.z, tryA, expb; # tell apart c3 from c5 CMP tmp, try.y, {3,0,0,0}, {1,-1,0,0}; # reassemble quads # note: if c3 then auto 1,-1,0,0 MAD try, try, expb.w, tmp; # tryA=tryA / (y+1) + displ CMP try, decoded.y, try, res; # just undo all this if C4a or C4b CMP res, res.y, res, try; # apply translation (patch global pos, stored in (map[0],map[1])) ################################################################# # res = ( (res+{1,1}+{map[0],map[1]} ) * {TS,TS} / {1024,1024} MAD res, res, text_coord_normalizer_on_TS_0, text_coord_normalizer_on_TS_1; MAD res, map, text_coord_normalizer_on_TS_times_255, res; # final texture access ####################### # some variants here # uncomment only one in (1)..(4), comment the others. # note: (3) and (4) are just for polycube-maps illustrarion # (1) direct texture color copy. TXB result.color, res, texture, 2D ; # (2) modulate the texture with the fragment color: #TXB res, res, texture, 2D ; #MUL result.color, res, fragment.color; # (3) re-color the texture according to cell case #TXB res, res, texture, 2D ; #CMP decoded, decoded, {0.50,0.85,0.50,1}, {1,0.5,1,1}; #MUL result.color, res, decoded; # (4) re-color the texture according to cell case # plus hi-light borders of 3D texture cells #TXB res, res, texture, 2D ; #CMP decoded, decoded, {0.50,0.85,0.50,1}, {1,0.5,1,1}; #DP3 sub, sub, sub; #MUL sub, sub, {0.25,0.25,0.25,0.0}; #MAD result.color, res, decoded,sub; END