/* ========================================================================================== Cg Acceleration Research Edgar Velázquez Armendáriz - edgar [at] graphics [dot] cornell [dot] edu ------------------------------------------------------------------------------------------ pointProjection.cg Point cloud projection shaders using MRT. Requires fp40 profile. ========================================================================================== */ /* Vertex information to be transfered */ struct vertexInfo { float4 pos : POSITION; half2 uv : TEXCOORD0; half4 color : COLOR0; half4 colorSec : COLOR1; half2 subPixel; }; // vp40: # 18 instructions, 2 R-regs void vertMain( uniform float4x4 ModelViewProj : state.matrix.mvp, uniform half2 c, // Vector <width/2, height/2> for subpixel transformation in vertexInfo IN, out vertexInfo OUT ) { // Transformed position of the vertex into clip coordinates OUT.pos = mul(ModelViewProj, IN.pos); // Force points into clipping plane, to avoid the backgroud points to be // deleted by the depth cull OUT.pos.z = clamp(OUT.pos.z, -1e38, OUT.pos.w * (0.999999523162841796875)); // Just copy the input color, and the secondary color which contains the encoded pointID OUT.color = IN.color; OUT.colorSec = IN.colorSec; // The rectangle texture coordinates encode the index of the vertex into the // original array of data, in such a way that all its original data is read from // the packed texture OUT.uv = IN.uv; // Get the pixel mapping, integer and fractional part (characteristic and mantissa) const half2 gamma = c * OUT.pos.xy / OUT.pos.w + c; // The fractional part is stored in a varying parameter: // Each mantissa will give me the information about subpixel location OUT.subPixel = frac(gamma); OUT.subPixel.y = 1 - OUT.subPixel.y; // Calculated with origin on bottom left corner, It must // be in the upper left corner. } // fp40: # 15 instructions, 1 R-regs, 1 H-regs void fragMain( uniform samplerRECT packData : TEXUNIT0, in vertexInfo IN, in float3 pos : WPOS, out float depth : DEPTH, out half4 outputs[3] : COLOR0 ) { // UPDATE TO REFLECT CHANGES IN ENVIRONMENT const half MAX_AGE = 255; // [0,255] const half FLAGS = 64; // [0,255] // FLAGS == 0x40 // After the texture operation, do some math to cover the latency half4 idAgePacked = texRECT(packData, IN.uv); // Subpixel info half2 subPixV = floor(half2(4,4) * IN.subPixel); half subPix = 1/255.0h * (4*subPixV.y + subPixV.x); // subPix (not scaled) is in the range [0, 15] // The secondary color contains the pointID, with the LSB in R and the MSB in B, so I just // need to copy that information half4 idVertex = half4(FLAGS/255.0, IN.colorSec.rgb); // If this is an invalid point, because of the age, discard if (idAgePacked.r >= MAX_AGE/255.0h) { outputs[0] = half4(1,0,0, subPix); }//discard; } // Normal color, it also copies the subpixel info into the final RGBA texture, // ready to be attached to the EPI-GPU. outputs[0] = half4(IN.color.rgb, subPix); // The final output contains the Flags in R and the pointID splitted in GBA outputs[1] = idVertex; // In the third render buffer, I will store: // r - Priority // g - seqnum // b - flags/seqnum info // a - 0 as flag -> invalid pixels have a = 1 half priority = saturate(idAgePacked.r/2.0 - 8/255.0); // priority = max(0,age-16) / 2 outputs[2] = half4(priority, IN.color.a, 1/255.0h * FLAGS + IN.color.a, 0); }