Smidigt steg

En plot av funktionerna smoothstep(x) och smootherstep(x), med 0 som vänsterkant och 1 som högerkant

Smoothstep är en familj av sigmoid-liknande interpolations- och klämfunktioner som vanligtvis används i datorgrafik , videospelmotorer och maskininlärning .

Funktionen beror på tre parametrar, ingången x , "vänster kant" och "höger kant", där vänsterkanten antas vara mindre än högerkanten. Funktionen tar emot ett reellt tal x som ett argument och returnerar 0 om x är mindre än eller lika med den vänstra kanten, 1 om x är större än eller lika med den högra kanten, och interpolerar smidigt, med hjälp av ett hermitpolynom , mellan 0 och 1 annars. Gradienten för smoothstep -funktionen är noll vid båda kanterna. Detta är praktiskt för att skapa en sekvens av övergångar med hjälp av smoothstep för att interpolera varje segment som ett alternativ till att använda mer sofistikerade eller dyra interpolationstekniker.

I HLSL och GLSL implementerar smoothstep { , den kubiska Hermite-interpolationen efter klämning :

Om man antar att den vänstra kanten är 0 är den högra kanten 1, där övergången mellan kanterna sker där 0 ≤ x ≤ 1.

AC/C++ exempelimplementering tillhandahållen av AMD följer.

       

      
       0

      
       

   
           

            
 float  smoothstep  (  float  edge0  ,  float  edge1  ,  float  x  )  {  if  (  x  <  edge0  )  return  ;  if  (  x  >=  kant1  )  returnera  1  ;  // Skala/bias till [0..1] intervall  x  =  (  x  -  kant0  )  /  (  kant1  -  kant0  );  returnera  x  *  x  *  (  3  -  2  *  x  );  } 

Den allmänna formen för smoothstep , återigen förutsatt att den vänstra kanten är 0 och den högra kanten är 1, är

är identisk med klämfunktionen :

Den karakteristiska "S"-formade sigmoidkurvan erhålls med endast för heltal n ≥ 1. Ordningen för polynomet i det allmänna jämna steget är 2 n + 1. Med n = 1 är lutningarna eller förstaderivatorna av det jämna steget lika med noll vid vänster och höger kant ( x = 0 och x = 1), där kurvan läggs till de konstanta eller mättade nivåerna . Med högre heltal n är den andra och högre derivatan noll vid kanterna, vilket gör polynomfunktionerna så platta som möjligt och skarven till gränsvärdena 0 eller 1 mer sömlös.

Variationer

Ken Perlin föreslog en förbättrad version av den vanligen använda första ordningens smoothstep-funktionen, motsvarande den andra ordningen i dess allmänna form. Den har noll 1:a och 2:a ordningens derivator vid x = 0 och x = 1:

C/C++ referensimplementering:

       
  
            
  
                 


       
     
      
     
      
   
 float  smootherstep  (  float  edge0  ,  float  edge1  ,  float  x  )  {  // Scale, and clamp x to 0..1 range  x  =  clamp  ((  x  -  edge0  )  /  (  edge1  -  edge0  ),  0.0  ,  1.0  );  // Utvärdera polynomavkastning  x  *  x  *  x  *  (  x  *  (  x  *  6  -  15  )  +  10  )  ;  }  float  clamp  (  float  x  ,  float  nedre gräns  ,  float  övre gräns  )  {  if  (  x  <  nedre gräns  )  x  =  nedre gräns  ;  if  (  x  >  övre gräns  )  x  =  övre gräns  ;  returnera  x  ;  } 

Ursprung

3:e ordningens ekvation

Börjar med en generisk tredje ordningens polynomfunktion och dess första derivata :

Tillämpa de önskade värdena för funktionen vid båda ändpunkterna:

Tillämpa de önskade värdena för den första derivatan av funktionen vid båda ändpunkterna:

Att lösa systemet med 4 okända som bildas av de senaste 4 ekvationerna resulterar i värdena på polynomkoefficienterna:

Detta resulterar i tredje ordningens "smoothstep" -funktion:

5:e ordningens ekvation

Börjar med en generisk femte ordningens polynomfunktion , dess första derivata och dess andra derivata:

Tillämpa de önskade värdena för funktionen vid båda ändpunkterna:

Tillämpa de önskade värdena för den första derivatan av funktionen vid båda ändpunkterna:

Tillämpa de önskade värdena för den andra derivatan av funktionen vid båda ändpunkterna:

Att lösa systemet med 6 okända som bildas av de senaste 6 ekvationerna resulterar i värdena på polynomkoefficienterna:

Detta resulterar i femte ordningens "smootherstep" -funktion:

7:e ordningens ekvation

Genom att tillämpa liknande tekniker visar sig 7:e ordningens ekvation vara:

Generalisering till högre ordningens ekvationer

Smidigstegspolynom är generaliserade, med 0 ≤ x ≤ 1 som

där N bestämmer ordningen för den resulterande polynomfunktionen, som är 2 N + 1. De första sju jämnstegspolynomen, med 0 ≤ x ≤ 1, är

Differentialen för är

Det kan visas att de jämna stegspolynomen som övergår från 0 till 1 när x övergår från 0 till 1 enkelt kan mappas till udda- symmetripolynom _

var

och

Argumentet för R N ( x ) är −1 ≤ x ≤ 1 och läggs till konstanten −1 till vänster och +1 till höger.

En implementering av i Javascript:


   
     0  
     0
      0    
          
                      
                   
   




   
      
      0    
            
   


    
     
      
     
      
   
 // Generaliserad smoothstep  -funktion  generalSmoothStep  (  N  ,  x  )  {  x  =  clamp  (  x  ,  ,  1  );  // x måste vara lika med eller mellan 0 och 1  var  result  =  ;  för  (  var  n  =  ;  n  <  =  N  ;  ++  n  )  resultat  +=  pascalTriangle  (  -N  -  1  ,  n  )  *  pascalTriangle  (  2  *  N  +  1  ,  N  -  n  )  *  Math  .  pow  (  x  ,  N  +  n  +  1  );  returnera  resultat  ;  }  // Returnerar binomial koefficient utan explicit användning av fakulteter,  // som inte kan användas med negativa heltal  funktion  pascalTriangle  (  a  ,  b  )  {  var  result  =  1  ;  för  (  vari  =  ;  i  <  b  ;  ++  i  )  resultat  *=  (  a  -  i  )  /  (  i  +  1  )  ;  returnera  resultat  ;  }  funktionsklämma  (  x  ,  nedre gräns  ,  övre  gräns  )  {  if  (  x  <  nedre gräns  )  x  =  nedre gräns  ;  if  (  x  >  övre gräns  )  x  =  övre gräns  ;  returnera  x  ;  } 

Omvänt Smoothstep

Inversen av smoothstep() kan vara användbar när man gör vissa operationer i datorgrafik när dess effekt måste vändas eller kompenseras för. I fallet med 3:e ordningens ekvation finns det en analytisk lösning för det omvända, vilket är:

Detta uppstår som inversen av , vars Maclaurin-serie slutar vid , vilket betyder och uttrycker samma funktion. Serieexpansionen av inversen upphör å andra sidan inte.

I GLSL:

   
           
 float  inverse_smoothstep  (  float  x  )  {  return  0,5  -  sin  (  asin  (  1,0  -  2,0  *  x  )  /  3,0  );  } 

externa länkar