Page 1 sur 1

Normal Mapping

Publié : lun. 22/déc./2008 23:09
par Anonyme
Voici ma petite contrib du mois de décembre , Le normal mapping.

Le normal mapping est une technique qui permet de simuler du relief sur un modèle 3d, l'avantage de cette technique c'est l'économie du maillage , car le relief est simulé par la texture.


Avec cette texture en niveau de gris :

Image

on obtient ceci :

Image

Cette image coloré est en fait une représentation de vecteur 3d.
c'est elle qui permet de simulé le relief :

Image


Voici le code qui permet de créer une normal map via une image en niveau de gris :

Code : Tout sélectionner

Global Threshold = 5
Global Progress.i = 0
Procedure.d Min(a.d,b.d)
  If a<b
    ProcedureReturn a
  Else
    ProcedureReturn b
  EndIf
EndProcedure

Procedure.d Max(a.d,b.d)
  If a>b
    ProcedureReturn a
  Else
    ProcedureReturn b
  EndIf
EndProcedure 


Structure VECTOR3
  x.f :  y.f : z.f
EndStructure

Macro SetVector3(V,_x,_y,_z)
V\x=_x
V\y=_y
V\z=_z
EndMacro

Macro VectorLength(V)
(V\x*V\x + V\y*V\y + V\z*V\z)
EndMacro

Macro Normalize(V)
         l.f = VectorLength(V)
         If (l <> 0)
           l =  Sqr(l)
           V\x / l
           V\y / l
           V\z / l
         EndIf
EndMacro

Procedure.f DotProduct(*A.VECTOR3,*B.VECTOR3)
ProcedureReturn *A\X * *B\X + *A\Y * *B\Y + *A\Z * *B\Z
EndProcedure

Macro CharToByte(Char)
Char/255.0
EndMacro

Macro ByteToChar(Byte)
Byte*255
EndMacro

Procedure GetGrayLevel(x,y)
  Color = Point(x,y)
  Red     = Red(Color)
  Green = Green(Color)
  Blue    = Blue(Color)
  Gray = (Red+Green+Blue)/3
  ProcedureReturn Gray
EndProcedure

Procedure Map0_to_255(*V.VECTOR3)
*V\x = max(-256,*V\x)
*V\y = max(-256,*V\y)
*V\z = max(-256,*V\z)
*V\x = min(256,*V\x)
*V\y = min(256,*V\y)
*V\z = min(256,*V\z)
*V\x =*V\x/2 + 127
*V\y =*V\y/2 + 127 
*V\z =*V\z/2 + 127
EndProcedure

Procedure Conv3x3(ImageID, Array Gradient.f(2) , Array Sobel(2))
StartDrawing(ImageOutput(ImageID))
For y = 1 To ImageHeight(ImageID)-1
   For x = 1 To ImageWidth(ImageID)-1
   
   Gradient(x,y) = (CharToByte(GetGrayLevel(x-1,y-1))*Sobel(0,0))+(CharToByte(GetGrayLevel(x,y-1))*Sobel(1,0))+(CharToByte(GetGrayLevel(x+1,y-1))*Sobel(2,0))+(CharToByte(GetGrayLevel(x-1,y))*Sobel(0,1))+(CharToByte(GetGrayLevel(x,y-1))*Sobel(1,1))+(CharToByte(GetGrayLevel(x+1,y))*Sobel(2,1))+(CharToByte(GetGrayLevel(x-1,y+1))*Sobel(0,2))+(CharToByte(GetGrayLevel(x,y+1))*Sobel(1,2))+(CharToByte(GetGrayLevel(x+1,y+1))*Sobel(2,2))                                               
   Gradient(x,y) * Threshold
   
   SetGadgetState(0,Progress) : SmartWindowRefresh(0,1)
   Progress + 1
   Next
Next    
StopDrawing()
EndProcedure

Global  Dim SobelX(2,2)  : 
SobelX(0,0)=-1 : SobelX(1,0)=-2 : SobelX(2,0)=-1
SobelX(0,1)=0  : SobelX(1,1)=0  : SobelX(2,1)=0
SobelX(0,2)=1  : SobelX(1,2)=2  : SobelX(2,2)=1

Global  Dim SobelY(2,2)  : 
SobelY(0,0)=-1 : SobelY(1,0)=0 : SobelY(2,0)=1
SobelY(0,1)=-2 : SobelY(1,1)=0 : SobelY(2,1)=2
SobelY(0,2)=-1 : SobelY(1,2)=0 : SobelY(2,2)=1
                                                  



UsePNGImageDecoder()
UseJPEG2000ImageDecoder()
UseJPEGImageDecoder()
UsePNGImageDecoder()
UseTGAImageDecoder()
UseTIFFImageDecoder()
UsePNGImageEncoder()
UseJPEG2000ImageEncoder()
UseJPEGImageEncoder()
UsePNGImageEncoder()

Filtre$ = "Images|*.bmp;*.jpg,*.png,*.tga,*.tif"
Input$ = OpenFileRequester("Ouvrir une image","",Filtre$,0)


UseJPEGImageDecoder()
LoadImage(0,Input$)
CreateImage(1,ImageWidth(0),ImageHeight(0))

OpenWindow(0,0,0,640,32,"",#PB_Window_BorderLess | #PB_Window_ScreenCentered)
ProgressBarGadget(0,0,0,640,32,0,ImageWidth(0)*ImageHeight(0)*3,#PB_ProgressBar_Smooth)
StickyWindow(0,1)

Global Dim GradientX.f(ImageWidth(0),ImageHeight(0))
Global Dim GradientY.f(ImageWidth(0),ImageHeight(0))

Conv3x3(0, gradientX(), sobelX() );
Conv3x3(0, gradientY(), sobelY() );



StartDrawing(ImageOutput(1))
For y = 0 To ImageHeight(1)
   For x = 0 To ImageWidth(1)
  
  V.VECTOR3
  SetVector3(V,GradientX(x,y),GradientY(x,y),1)
  Normalize(V)
  
  Color.VECTOR3
  SetVector3(Color,ByteToChar(V\x),ByteToChar(V\y),ByteToChar(V\z))
  Map0_to_255(Color)
  Plot(x,y,RGB(Color\x,Color\y,Color\z)) 
  
  SetGadgetState(0,Progress) : SmartWindowRefresh(0,1)
  Progress+1
  
   Next
Next    
StopDrawing()


SaveImage(1,SaveFileRequester("Sauvegarder","",Filtre$,0))

Publié : mar. 23/déc./2008 11:15
par Le psychopathe
Bravo, un truc remplie de mathématiques xD Fallait connaître

Publié : mar. 23/déc./2008 14:03
par cha0s
Merci du code *love* !