How to create pixelshader with mp3d

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
mpz
Enthusiast
Enthusiast
Posts: 497
Joined: Sat Oct 11, 2008 9:07 pm
Location: Germany, Berlin > member German forum

How to create pixelshader with mp3d

Post by mpz »

Hi folks,

I would like to introduce you to a program that I created with my mp3d Lib (sourcecode is in my mp3d engine available). It is possible to create pixel shader and test them. The generated pixel shader can then be used with the mp3d Lib. You can compile the shader and then use him permanently. The execution speed depends on the graphics card. An image with 1024 * 1024 pixels with 16 bit takes me an average of 3 ms. I give you 54 test shader. The strength of the shader is the real-time changes (which I have not integrated into this shader program). The help button has no function. Anyone who has a desire to help can write a help file and send me the text (as MessageRequester)?

PixelShaderprogram
http://www.file-upload.net/download-282 ... r.zip.html

Here is a little introduction. The program can load two images called TextureA and TextureB. Further, there are three variables Var1.f, Var2.f and Var3.f which can be controlled via sliders. The range is from 0-1 here (float) and the default is 0.5 (middle)

Example Shader:
Creating a shader: This is written as ascii text and corresponds to the C language

1) Import of the variables

Code: Select all

texture TextureA;
Here the texture is defined TextureA. variables are to upper / lower case sensetive!

Code: Select all

float Var1;
Here is the "Slider Variabel" is defined and delivered

2) treatment of texture in the shader

Code: Select all

sampler Sampler1 = sampler_state
{
    texture   = <TextureA>;
    AddressU  = Clamp;
    AddressV  = Clamp;
    MipFilter = None;
    MagFilter = None;
    MinFilter = None;
};
The functions AddressU etc. define the properties of the texture in the shader

3) Function invers

Code: Select all

float4 PSInverse(float2 Tex : TEXCOORD0) : COLOR
{
    return 1.0f - tex2D(Sampler1, Tex);
}
PSInverse -> name of function
float2 Tex : TEXCOORD0 -> Doublefloat, these are the texturecoords

return 1.0f - tex2D(Sampler1, Tex); -> Texture return means, the color rgba is 255,255,255,255 minus color and make every color invers

3) Brightness function
Example of brightness Shader

Code: Select all

return  tex2D(Sampler1, Tex)*Var1*2;
Var1 = 0.5(middle of the Slider) * 2 = 1 every color are color * 1. Slider up Hoch = color * 2 or Slider down color * 0

4) start function

Code: Select all

technique t1
{
    pass p1  
    {
        PixelShader = compile ps_2_0 PSInverse();
    }
}
technique t1 -> this i one of some possible functions you can write in a shader (The Pixelshadertestprogramm use t1 to start a shader)
pass p1 -> Number of passes p1 = 1. For more complex shaders, you have several loops / steps and then requires several iterations
PixelShader = compile ps_2_0 PSInverse(); -> Depending on the graphics card can be used more and more complex commands

Here is the finished shader to to invert a texture

finished shader

Code: Select all

texture TextureA;
sampler Sampler1 = sampler_state
{
    texture   = <TextureA>;
};

float4 PSInverse(float2 Tex : TEXCOORD0) : COLOR
{
    return 1 - tex2D(Sampler1, Tex);
}

technique t1
{
    pass p1  
    {
        PixelShader = compile ps_2_0 PSInverse();
    }
}


Greetings
Michael
Working on - MP3D Library - PB 5.73 version ready for download
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: How to create pixelshader with mp3d

Post by djes »

I've modified the code to have a realtime effect when dragging vars sliders (just a little hack), and the shader according to your instructions. It works perfectly :)

Code: Select all

;////////////////////////////////////////////////////////////////
;//
;// Project Title: MP 3D Engine
;// File Title: MP_ShaderEffecte.pb
;// Created On: 27.04.2010
;// Updated On: 
;// Author: Michael Paulwitz
;// OS:Windows
;// 
;// Make Shader for TextureChanging, IMPORTANT use the demofile directory 
;// 
;//
;////////////////////////////////////////////////////////////////


;- Gadget Constants
;
Enumeration
  #Button_0
  #Button_1
  #Button_2
  #Button_3
  #Button_4
  #Button_5
  #Button_6
  #Button_7
  #Editor_0
  #TrackBar_0
  #TrackBar_1
  #TrackBar_2
  #Text_0
  #Text_1
  #Text_2
  #Text_3
EndEnumeration

Var1.f = 0.5
Var2.f = 0.5
Var3.f = 0.5

Procedure CompileAndRun()
  
  Shared MyShader, MyEffect.s, TextureA, TextureB, Var1, Var2, Var3, DestTexture, Surface
  
  If MyShader : MP_FreeShader(MyShader) : EndIf
  
  MyEffect.s = GetGadgetText(#Editor_0) 
  
  MyShader = MP_CreateMyShader (MyEffect.s)
  If MyShader 
     MP_SetTechniqueMyShader (MyShader,"t1")
     MP_ShaderSetTexture (MyShader,"TextureA",TextureA)
     MP_ShaderSetTexture (MyShader,"TextureB",TextureB)
     MP_ShaderSetVar_f(MyShader,"Var1",Var1.f) 
     MP_ShaderSetVar_f(MyShader,"Var2",Var2.f) 
     MP_ShaderSetVar_f(MyShader,"Var3",Var3.f) 
     StartTime = MP_ElapsedMicroseconds()
     MP_UsePixelShader (DestTexture, MyShader)
     ElapsedTime = MP_ElapsedMicroseconds() - StartTime 
     SetWindowTitle(0, "Shader For TextureChanging V0.1 - Runtime of compiled Shader in ms "+StrF(ElapsedTime/100,2)) 
     If Surface : MP_FreeSurface (Surface) : EndIf
     Surface = MP_TextureToSurface(DestTexture)
     MP_SurfaceSetPosition(Surface, 0,0,1) 
     MP_SurfaceDestRect(Surface, 20,20,490,490)    
  Else
     MessageRequester("Shader Error", MP_GetLastError())
  EndIf
  
EndProcedure
  
MP_Graphics3D (933,511,0,2) ; Erstelle ein WindowsFenster mit 3D Funktion #Window = 0
SetWindowTitle(0, "Shader for TextureChanging V0.1") ; Setzt einen Fensternamen

ButtonGadget(#Button_0, 510, 20, 140, 30, "Load TextureA")
ButtonGadget(#Button_1, 510, 70, 140, 30, "Load TextureB")
ButtonGadget(#Button_2, 510, 140, 140, 30, "Load Shader")
ButtonGadget(#Button_3, 510, 190, 140, 30, "Save Shader")
ButtonGadget(#Button_4, 680, 20, 130, 30, "Help")
ButtonGadget(#Button_5, 680, 70, 130, 30, "TextureA on Screen")
ButtonGadget(#Button_6, 680, 140, 130, 30, "Compile and Run")
ButtonGadget(#Button_7, 680, 190, 130, 30, "Save New Textur")
EditorGadget(#Editor_0, 510, 250, 400, 220)
TextGadget(#Text_0, 820, 20, 40, 20, "Var1")
TrackBarGadget(#TrackBar_0, 825, 40, 30, 180, 0, 100, #PB_TrackBar_Vertical);#PB_TrackBar_Ticks | #PB_TrackBar_Vertical)
SetGadgetState(#TrackBar_0, 50)
TextGadget(#Text_1, 860, 20, 40, 20, "Var2")
TrackBarGadget(#TrackBar_1, 860, 40, 30, 180, 0, 100, #PB_TrackBar_Vertical);#PB_TrackBar_Ticks | #PB_TrackBar_Vertical)
SetGadgetState(#TrackBar_1, 50)      
TextGadget(#Text_2, 900, 20, 40, 20, "Var3")
TrackBarGadget(#TrackBar_2, 895, 40, 30, 180, 0, 100, #PB_TrackBar_Vertical);#PB_TrackBar_Ticks | #PB_TrackBar_Vertical)
SetGadgetState(#TrackBar_2, 50)      
TextGadget(#Text_3, 510, 230, 400, 20, "Shadername: ")

MP_Viewport(20,20,470,470)
directory$ = GetPathPart(ProgramFilename())


While Not MP_KeyDown(#PB_Key_Escape) ; Esc abfrage / SC pushed?
 Select MP_WindowEvent()
      
   Case #PB_Event_Gadget
     Select EventGadget()
         
      Case #Button_0
              Pattern$ = "Image File (bmp,jpg,tga,png,dds,ppm,dib,hdr,pfm|*.bmp;*.jpg;*.tga;*.png;*.dds;*.ppm;*.dib;*.hdr;*.pfm" 
              ;SetCurrentDirectory(directory$)
              ;directory$ = GetCurrentDirectory();"C:\Programme\PureBasic\media\" 
              TexturFile.s = OpenFileRequester("Load Texture A", directory$, Pattern$,  0) 
              If TexturFile
                 MP_FreeTexture (TextureA)
                 TextureA =  MP_LoadTexture(TexturFile)
                 If DestTexture : MP_FreeTexture ( DestTexture ) : EndIf
                 DestTexture = MP_CreateTexture(MP_TextureGetWidth(TextureA),MP_TextureGetHeight(TextureA))
                 If Surface : MP_FreeSurface (Surface) : EndIf
                 Surface = MP_TextureToSurface(TextureA)
                 MP_SurfaceSetPosition(Surface, 0,0,1) 
                 MP_SurfaceDestRect(Surface, 20,20,490,490) 
              EndIf
      Case #Button_1
              Pattern$ = "Image File (bmp,jpg,tga,png,dds,ppm,dib,hdr,pfm|*.bmp;*.jpg;*.tga;*.png;*.dds;*.ppm;*.dib;*.hdr;*.pfm" 
              ;SetCurrentDirectory(directory$)
              ;directory$ = GetCurrentDirectory();"C:\Programme\PureBasic\media\" 
              TexturFile = OpenFileRequester("Load Texture B", directory$, Pattern$,  0) 
              If TexturFile
                 MP_FreeTexture (TextureB)
                 TextureB =  MP_LoadTexture(TexturFile)
              EndIf
      Case #Button_2
              File.s = OpenFileRequester("Load Shader FX File", directory$, "Shader File (fx)|*.fx",  0) 
              If File
                If ReadFile(0,  File)   ; wenn die Datei geöffnet werden konnte, setzen wir fort...
                  MyEffect.s = ""
                  While Eof(0) = 0           ; sich wiederholende Schleife bis das Ende der Datei ("end of file") erreicht ist
                    MyEffect.s + ReadString(0) + Chr(10)      ; Zeile für Zeile im Debugger-Fenster anzeigen
                  Wend
                  CloseFile(0)
                  ClearGadgetItems(#Editor_0)                ; schließen der zuvor geöffneten Datei
                  AddGadgetItem(#Editor_0, 0,MyEffect) 
                EndIf
                SetGadgetText(#Text_3, "Shadername: "+file)
              EndIf
     Case #Button_3
              File.s = SaveFileRequester("Save Shader File", directory$+"\"+File, "Shader Files (*.fx)|*.fx",  0)
              If File
                  MyEffect.s = GetGadgetText(#Editor_0) 
                  If CreateFile(0, File)
                     WriteString(0, MyEffect)
                     CloseFile(0)
                  EndIf
                SetGadgetText(#Text_3, "Shadername: "+file)
              EndIf
      Case #Button_4
            MessageRequester("Help", "will coming soon, pray for it", #PB_MessageRequester_Ok)
      Case #Button_5
            If Surface : MP_FreeSurface (Surface) : EndIf
            Surface = MP_TextureToSurface(TextureA)
            MP_SurfaceSetPosition(Surface, 0,0,1) 
            MP_SurfaceDestRect(Surface, 20,20,490,490) 
      Case #Button_6
        CompileAndRun()
      Case #Button_7
        File.s = SaveFileRequester("Save Textur as JPG", "Textur.jpg", "Textur Files(*.jpg)|*.jpg",  0)
        If File
           MP_SaveTexture (File, DestTexture , 1)
         EndIf
      Case #TrackBar_0
        i.f = GetGadgetState(#TrackBar_0)/100 
        If i <> Var1.f : Var1 = i : CompileAndRun() : EndIf
      Case #TrackBar_1
        i.f = GetGadgetState(#TrackBar_1)/100 
        If i <> Var2.f : Var2 = i : CompileAndRun() : EndIf
      Case #TrackBar_2
        i.f = GetGadgetState(#TrackBar_2)/100
        If i <> Var3.f : Var3 = i : CompileAndRun() : EndIf
      EndSelect 
    
  Case #PB_Event_CloseWindow 
         End 
 EndSelect 
  
    MP_RenderWorld () 
    MP_Flip () 
Wend 

Code: Select all

texture TextureA;
float Var1;
sampler Sampler1 = sampler_state
{
    texture   = <TextureA>;
};

float4 PSInverse(float2 Tex : TEXCOORD0) : COLOR
{
    return  tex2D(Sampler1, Tex)*Var1*2;
}

technique t1
{
    pass p1  
    {
        PixelShader = compile ps_2_0 PSInverse();
    }
}
mpz
Enthusiast
Enthusiast
Posts: 497
Joined: Sat Oct 11, 2008 9:07 pm
Location: Germany, Berlin > member German forum

Re: How to create pixelshader with mp3d

Post by mpz »

Hi djes,

thanks for your modification, it works great . :D I put this modification to my Demo files...

Greetings
Michael
Working on - MP3D Library - PB 5.73 version ready for download
Post Reply