2010-02-26 6 views

Répondre

1

J'ai regardé le filtre de tampon dans Photoshop et il ressemble à un seuil et à un fort flou ajouté ensemble. J'ai utilisé le noyau HorizontalGaussianBlur trouvé Pixel Bender Basics Article on Devnet et j'ai juste ajouté un seuil bon marché. Voici comment mon noyau ressemble à:

<languageVersion : 1.0;> 

kernel stamp 
< namespace : "toMaterial"; 
    vendor : "George Profenza"; 
    version : 1; 
    description : "Attempt to simulate Photoshop Stamp Filter. Original blur code: http://www.adobe.com/devnet/flash/articles/pixel_bender_basics_05.html"; 
> 
{ 
    input image4 src; 
    output pixel4 dst; 

    parameter float threshold< 
     minValue: 0.0; 
     defaultValue:0.5; 
     maxValue:1.0; 
    >; 
    parameter int radius 
    < 
     minValue : 1; 
     maxValue : 6; 
     defaultValue : 6; 
    >; 

    void 
    evaluatePixel() 
    { 
     pixel4 center, band1, band2, band3, band4, band5, band6; 
     float2 pos = outCoord(); 

     //Sample image in bands 
     if(radius > 5) { 
      pixel4 left = dst; 
      pixel4 right = dst; 
      left.x -= 6.0; 
      right.x += 6.0; 
      band6 = left+right; 
     } 
     if(radius > 4) { 
      pixel4 left = dst; 
      pixel4 right = dst; 
      left.x -= 5.0; 
      right.x += 5.0; 
      band5 = left+right; 
     } 
     if(radius > 3) { 
      pixel4 left = dst; 
      pixel4 right = dst; 
      left.x -= 4.0; 
      right.x += 4.0; 
      band4 = left+right; 
     } 
     if(radius > 2) { 
      pixel4 left = dst; 
      pixel4 right = dst; 
      left.x -= 3.0; 
      right.x += 3.0; 
      band3 = left+right; 
     } 
     if(radius > 1) { 
      pixel4 left = dst; 
      pixel4 right = dst; 
      left.x -= 2.0; 
      right.x += 2.0; 
      band2 = left+right; 
     } 
     pixel4 left = dst; 
     pixel4 right = dst; 
     left.x -= 1.0; 
     right.x += 1.0; 
     band1 = left+right; 

     dst = sampleNearest(src,pos); 
     //quick'n'dirty grayscale 
     dst.rgb = float3(dst.r + dst.g + dst.b) * 0.333333333; 
     //threshold 
     if(dst.r < threshold) dst.r = 0.0; else dst.r = 1.0; 
     if(dst.g < threshold) dst.g = 0.0; else dst.g = 1.0; 
     if(dst.b < threshold) dst.b = 0.0; else dst.b = 1.0; 

     center = dst; 

     //Apply weights and compute resulting pixel 
     if(radius == 6) 
     { 
      dst = (band6 + (band5 * 12.0) + (band4 * 66.0) + (band3 * 220.0) + (band2 * 495.0) + (band1 * 792.0) + (center * 924.0)) * 0.000244140625;//4096.0; 
     } 
     if(radius == 5) 
     { 
      dst = (band5 + (band4 * 10.0) + (band3 * 45.0) + (band2 * 120.0) + (band1 * 210.0) + (center * 252.0)) * 0.0009765625;//1024.0; 
     }  
     if(radius == 4) 
     { 
      dst = (band4 + (band3 * 8.0) + (band2 * 28.0) + (band1 * 56.0) + (center * 70.0)) * 0.00390625;//256.0; 
     } 
     if(radius == 3) 
     { 
      dst = (band3 + (band2 * 6.0) + (band1 * 15.0) + (center * 20.0)) * 0.015625;//64.0; 
     } 
     if(radius == 2) 
     { 
      dst = (band2 + (band1 * 4.0) + (center * 6.0)) * 0.0625;//16.0 
     } 
     if(radius == 1) 
     { 
      dst = (band1 + (center * 2.0)) * 0.25;//4.0 
     } 

    } 
} 

Ce qui est loin d'être parfait, il est ce que je pourrais pirater rapidement à cette heure. Cela devrait vous donner quelques idées cependant.

MISE À JOUR:

Voici une version mise à jour à l'aide en niveaux de gris approprié et le code flou gaussien est la plupart du temps de la Pixel Bender Guide.

<languageVersion : 1.0;> 

kernel Stamp 
< namespace : "gp"; 
    vendor : "George Profenza"; 
    version : 1; 
    description : "Attempt to do a filter similar to Photoshop's Stamp Filter, blur code mostly from the guide: http://www.adobe.com/go/pixelbender_devguide"; 
> 
{ 
    input image4 source; 
    output pixel4 result; 

    parameter int blur< 
     minValue:1; 
     defaultValue:3; 
     maxValue:8; 
    >; 
    parameter float threshold< 
     minValue:0.0; 
     maxValue:1.0; 
     defaultValue:0.5; 
    >; 

    void 
    evaluatePixel() 
    { 
     //blur 
     const float sigma = 2.0; 
     float c = 1.0/(sqrt(2.0 * 3.1415926535) * sigma); 
     float ec = 2.0 * sigma * sigma; 
     float weight0 = exp(-(0.0 * 0.0)/ec) * c; 
     float weight1 = exp(-(1.0 * 1.0)/ec) * c; 
     if(blur > 1) float weight2 = exp(-(2.0 * 2.0)/ec) * c; 
     if(blur > 2) float weight3 = exp(-(3.0 * 3.0)/ec) * c; 
     if(blur > 3) float weight4 = exp(-(4.0 * 4.0)/ec) * c; 
     if(blur > 4) float weight5 = exp(-(5.0 * 5.0)/ec) * c; 
     if(blur > 5) float weight6 = exp(-(6.0 * 6.0)/ec) * c; 
     if(blur > 6) float weight7 = exp(-(7.0 * 7.0)/ec) * c; 
     if(blur > 7) float weight8 = exp(-(8.0 * 7.0)/ec) * c; 

     float4 acc = float4(0.0); 

     acc += sampleNearest(source, outCoord()) * weight0; 
     acc += sampleNearest(source, outCoord() + float2(1.0, 0.0)) * weight1; 
     acc += sampleNearest(source, outCoord() + float2(-1.0, 0.0)) * weight1; 
     if(blur > 1) { 
      acc += sampleNearest(source, outCoord() + float2(2.0, 0.0)) * weight2; 
      acc += sampleNearest(source, outCoord() + float2(-2.0, 0.0)) * weight2; 
     } 
     if(blur > 2) { 
      acc += sampleNearest(source, outCoord() + float2(3.0, 0.0)) * weight3; 
      acc += sampleNearest(source, outCoord() + float2(-3.0, 0.0)) * weight3; 
     } 
     if(blur > 3) { 
      acc += sampleNearest(source, outCoord() + float2(4.0, 0.0)) * weight4; 
      acc += sampleNearest(source, outCoord() + float2(-4.0, 0.0)) * weight4; 
     } 
     if(blur > 4) { 
      acc += sampleNearest(source, outCoord() + float2(5.0, 0.0)) * weight5; 
      acc += sampleNearest(source, outCoord() + float2(-5.0, 0.0)) * weight5; 
     } 
     if(blur > 5) { 
      acc += sampleNearest(source, outCoord() + float2(6.0, 0.0)) * weight6; 
      acc += sampleNearest(source, outCoord() + float2(-6.0, 0.0)) * weight6; 
     } 
     if(blur > 6) { 
      acc += sampleNearest(source, outCoord() + float2(7.0, 0.0)) * weight7; 
      acc += sampleNearest(source, outCoord() + float2(-7.0, 0.0)) * weight7; 
     } 
     if(blur > 7) { 
      acc += sampleNearest(source, outCoord() + float2(8.0, 0.0)) * weight8; 
      acc += sampleNearest(source, outCoord() + float2(-8.0, 0.0)) * weight8; 
     } 
     //grayscale 
     float luma = 0.299 * acc.r + 0.587 * acc.g + 0.114 * acc.b; 
     acc = float4(luma,luma,luma,1.0); 
     //threshold 
     if(acc.r < threshold) acc.r = 0.0; else acc.r = 1.0; 
     if(acc.g < threshold) acc.g = 0.0; else acc.g = 1.0; 
     if(acc.b < threshold) acc.b = 0.0; else acc.b = 1.0; 

     result = acc; 
    } 
} 

Note: I a appliqué le seuil après le flou, de sorte que le résultat est pas exactement un filtre de timbre, mais à proximité.

HTH, George

Questions connexes