/* ========================================================================================== Cg Acceleration Research Optimized: Edgar Velázquez-Armendáriz - edgar [at] graphics [dot] cornell [dot] edu Original: Eugene Lee (el77 [at] cornell [dot] edu), Alex Liberman (al262 [at] cornell [dot] edu) ------------------------------------------------------------------------------------------ PixelClass.cg Classifies pixels into empty, simple, and complex pixels. Also handles ordering of edges. ========================================================================================== */ // # 82 instructions, 3 R-regs, 2 H-regs, no if-code // # 84 instructions, 2 R-regs, 3 H-regs, if code fp40 // This unified shader performs both the pixel classify and the point cull, using MRT! // OUT[0] = PixelClass // OUT[1] = PointCull // // Original: // -PixelClass: # 94 instructions, 3 R-regs, 1 H-regs // -PointCull: # 4 instructions, 2 R-regs, 0 H-regs void PixelClassPointCull( in half2 pixelPos : WPOS, const uniform samplerRECT edgeIntersections, const uniform samplerRECT subPixelLocations, const uniform samplerRECT bitExtract, const uniform samplerRECT emptyOrder, out half3 OUT[2] : COLOR0) { const static float BOTTOM = 0; const static float RIGHT = 1; const static float TOP = 2; const static float LEFT = 3; // Save all intersections in a single half4 vector // - Top: x // - Botton: y // - Left: z // - Right: w half4 Intersections; // Extract the all 4 intersections around the pixel. Intersections.xz = texRECT(edgeIntersections, pixelPos).rg; // Top-Left Intersections.y = texRECT(edgeIntersections, half2(pixelPos.x, pixelPos.y - 1)).r; // Bottom Intersections.w = texRECT(edgeIntersections, half2(pixelPos.x + 1, pixelPos.y)).g; // Right const half4 colorSample = texRECT(subPixelLocations, pixelPos); // Scale by 255 so that the intersections are in [0, 8]. For all intersections, at once Intersections = round(Intersections * 255.0); // intersection information half intersectionCount = dot( step(0.001953125h.xxxx, Intersections), 1.0h.xxxx ); if (intersectionCount == 2) { // construct a 5 bit mask whos information is given by the following // the 2 MSB: indicates where left = 3, top = 2, right = 1, bottom = 0 float4 edgeIntersection; // Top intersection if(Intersections.x > 0) { edgeIntersection.z = texRECT(bitExtract, float2(Intersections.x, 1)).r; edgeIntersection.w = TOP; //intersectionCount++; } // Bottom intersection if(Intersections.y > 0) { edgeIntersection.xy = edgeIntersection.zw; edgeIntersection.z = texRECT(bitExtract, float2(Intersections.y, 1)).r; edgeIntersection.w = BOTTOM; //intersectionCount++; } // Left intersection if(Intersections.z > 0) { edgeIntersection.xy = edgeIntersection.zw; edgeIntersection.z = texRECT(bitExtract, float2(Intersections.z, 1)).r; edgeIntersection.w = LEFT; //intersectionCount++; } // Right intersection if(Intersections.w > 0) { edgeIntersection.xy = edgeIntersection.zw; edgeIntersection.z = texRECT(bitExtract, float2(Intersections.w, 1)).r; edgeIntersection.w = RIGHT; //intersectionCount++; } half3 tColor = float3(0, 0, 255); //half4 colorSample = texRECT(subPixelLocations, pixelPos); half2 subPixelMask = round(colorSample.ba * 255); if(subPixelMask.x == 0) subPixelMask.y = 16; // Do edge ordering //float emptyIndex = edgeIntersection.y * 256 + edgeIntersection.w * 64 + // edgeIntersection.x * 8 + edgeIntersection.z; float emptyIndex = dot(edgeIntersection, half4(8,256,1,64)); float t = texRECT(emptyOrder, float2(emptyIndex, subPixelMask.y)).r; if(t >= 2) tColor.b = 0; if(t == 1 || t == 3) { tColor.rg = edgeIntersection.zw * float2(8,4) + edgeIntersection.xy; } else { tColor.rg = edgeIntersection.xy * float2(8,4) + edgeIntersection.zw; } // Pixel class info OUT[0] = tColor / 255.0; } else { OUT[0] = half3( (intersectionCount > 2 ? half2(1, 15/255.0) : half2(0,0) ),1); } // And now writes the point cull OUT[1] = half3(colorSample.rg, colorSample.b * OUT[0].b); }