/**
* Copyright Glidias ( http://wonderfl.net/user/Glidias )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/tqWU
*/
static alternativa3d const getDiffuseProcedure:Procedure = new Procedure([
"#v0=vUV",
"#v1=vZDistance",
"#s0=sDiffuse",
"#s1=sTileIndices", // sample texture index for tile indices
"#s2=sMipmapOffsets",
"#s3=sBlendAtlas",
"#c0=cThresholdAlpha",
"#c1=cTilePaddSize",
"#c2=cTileFrac", // 1/ noTilesAcross u and v directions, + tileSizeWidth and tileSizeHeight in UV coordinates within atlas
"#c3=cF", //(f=camera.focalLength / resolution, totalMipmaps, mipmapUVCap, 1)
"#c4=cAtlasTiles",
//"mov t1, c1", // dummy usage if needed
"tex t1, v0, s1 <2d,nearest,clamp,nomip>", // sample t1 tile index lookup
// Find t2 transform
"mul t0.z, t1.z, c4.z",
"frc t0.w, t0.z", // right half 4 bits (to split later.)
"sub t0.z, t0.z, t0.w",
"mul t0.z, t0.z, c4.w", // left half 4 bits
"mul t0.z, t0.z, c4.w", // split left half of 4 bits
"frc t1.w, t0.z", // right half 2 bits (b)
"sub t0.z, t0.z, t1.w",
//"mul t0.z, t0.z, c4.y", // left half 2 bits (a)
// finalise right half of 2 bits (b) as a value of either: -1, 0, 1, 2
"mul t1.w, t1.w, c4.x",
"sub t2.y, t1.w, c3.w",
// finalise left half of 2 bits (a) as a value of either: -1, 0, 1, 2
//"mul t0.z, t0.z, c4.x",
"sub t2.x, t0.z, c3.w",
"mul t0.w, t0.w, c4.w", // split right half of 4 bits (finally..)
"frc t1.w, t0.w", // right half 2 bits (d)
"sub t0.w, t0.w, t1.w",
//"mul t0.w, t0.w, c4.y", // left half 2 bits (c)
// finalise right half of 2 bits (d) as a value of either: -1, 0, 1, 2
"mul t1.w, t1.w, c4.x",
"sub t2.w, t1.w, c3.w",
// finalise left half of 2 bits (c) as a value of either: -1, 0, 1, 2
//"mul t0.w, t0.w, c4.x",
"sub t2.z, t0.z, c3.w",
"mov t0, v0", // dummy usage required somehow.
// ------ get normalized tile-based uv offsets with fractionals (t0)
"div t0.xy, t0.xy, c2.xy",
"frc t0.xy, t0.xy",
// todo: rotate t0.xy vector by t2 matrix (need a .5 constant)
// now calculate mipmap level ( t2 can be resued again)
"mov t2, v1",
"div t2.x, t2.z, c3.x", // Calculate mipmap level manually per pixel (z >= f) ? (log(z/f)) : 0;
"log t2.x, t2.x", // binary log
"frc t2.y, t2.x", // round down
"sub t2.x, t2.x, t2.y",
"div t2.x, t2.x, c3.y", // get uv sample ratio of current mipmap level against total mipmaps
"mul t2.x, t2.x, c3.z", // clamp ratio to base uv cap amount
"tex t2, t2, s2 <2d,nearest,clamp,nomip>", // sample mipmap level offset lookup // assume t2.zw ignored ?
"mul t2.y, t2.y, c2.z", // as actual u offset value
"mul t2.w, t2.z, c2.z", // this value is either zero or 1*tileSize, depending on t2.z is either zero or 1.
"add t2.y, t2.y, t2.w", // last operand should be t2.w (mipmap offset for u)
"mul t2.z, c2.z, t2.x", // take into consideration tile size reduction due to mipmapping
"mul t2.w, c2.w, t2.x",
// todo: subtract t2.zw accordingly by the needed ratios
"mul t0.x, t0.x, t2.z", // normalized tile-based uv offset * tile uv size on atlas .
"mul t0.y, t0.y, t2.w", // normalized tile-based uv offset * tile uv size on atlas .
"add t0.x, t0.x, t2.y", // add mipmap offset
// t0, t1 reserved!
// todo: subtract additive offset by needed ratios
// Find t0-t2.w, from t2.xyz: blend intensities
"mul t2.z, t1.y, c4.z",
// left half of 4 bits can consider later for the B color sample
"frc t2.w, t2.z", // right half 4 bits (blend uv tile)
"mul t2.w, t2.w, c4.x", // split right half of 4 bits
"frc t2.y, t2.w", // right half of 2 bits (v)
"sub t2.z, t2.z, t2.y",
"mul t2.x, t2.z, c4.y", // left half of 2 bits (u)
"tex t2, t2, s3 <2d, linear,clamp, nomip>", // assume t2.zw ignored
"mov t0.w, t2.x",
"mov t1.w, t2.y",
"mov t2.w, t2.z",
// Finalise t2.xyzw output color
//"sub t2.xyz, t2.xyz, t2.xyz", // negate vector to zero!
// Sample and Add B
// Sample and Add R
// Sample and Add G
// -- SAMPLE
// "tex t0, t0, s0 <2d, linear,clamp, nomip>",
// "mul t0.w, t0.w, c0.w",
"mov o0, t2" // todo:
], "getDiffuseProcedure");
//*/
/* ROAD MAP:
Sample t1.xyz
-----------------
t1.xyz - the tile sample rgb (refer to bit layout for t1 tile)
Find t0.xy: (transformed uv mipmapped offset on atlas)
----------
// (t0.zw free, t1.w free)
t2.xyzw - unpack t1.z transform to get uv transform matrix
t0.xy - find normalized uv ratio -> transform it by matrix
// (t0.zw and t2.w free)
t2.xyz - reuse variable now for the mipmapped sample,
// (t1.z free)
t0.xy -> -> translate to atlas scale + mipmapped uv offset
Find t0-t2.w, from t2.xyz: blend intensities
-----------------------------------
t2.xyz - sample from t1.xyz over blend map
mov t2.x, t0.w
mov t2.y, t1.w
mov t2.z, t2.w
Finalise t2.xyzw output color
-----------------
Sample R texture color from t1, multiply by t0.www, store into t2.xyz (t0.w free)
Sample G texture color from t1, multiply by t1.www, add into t2.xyz (t1.w free)
Sample B texture color from t1, multiply by t2.www, add into t2.xyz (t2.w free)
mov constant 1 back to t2.w for output color t2.xyzw
_________________________________________________________________________
EXTRACTING DATA within a single RGB color sample:
Bit layout per t1 tile
-----------------------------------------
4x4 textures: (16 textures to select from, 16 available rgb blend variations (3 key pattern blends with variations of them))
--------------
Red - RRRRGGGG
Green - BBBBkkkk
Blue - aabbccdd // Once t0 is found, t1.z can be used as a temporary slot
Legend:
aabbccdd - Orthogonal rotation matrix values [a,b,c,d] for normalized tile UV coordinate
RRRR - u v lookup on texture tile atlas for Red intensity texture
GGGG - u v lookup on texture tile atlas for Green intensity texture
BBBB - u v lookup on texture tile atlas for Blue intensity texture
kkkk - u v lookup on blend tile atlas to get proper blending intensities for all 3 textures.
_________________________________________________________________________
To get upper and lower bit ratios:
w = ratio * 2^bits shifted
k = frc(w) - for lower bit ratio;
w = w - k;
w / 2^bits shifted - for upper bits ratio
_______________________________________
Given a decimal ratio spanning across 2 bits, determine upper bit and lower bit
respectively in terms of 0 or 1. This is the final prorcess which can easily be
simplified as:
0 00 0/4
0.25 01 1/4
.5 10 2/4
.75 11 3/4
Math.round( ratio ) // for upper bit, if ratio is lower than .5, return 0,
else return 1
frc(ratio*2) != 0 ? 1 : 0 // for lower bit, if remainder of ratio*2 is found,
return 1, else return 0.
*/