It is currently Sun Sep 24, 2017 2:59 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Transparent Black Pixel Shader
PostPosted: Sun Nov 22, 2015 7:09 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Jul 29, 2012 10:33 pm
Posts: 706
Location: United States
Hello everyone,
Well, I haven't posted any shader examples in a while. I moved on to other 3D options in Purebasic almost a year ago so I'm a little rusty when it comes to writing material scripts. Hopefully everything will work smoothly for those interested in it.

First off here's what the shader looks like. The left entities are using the shader and the right ones are not.
Image
Nothing fancy all it does is take the pure black pixels and then discards them. It does leave jagged edges, and sadly there's not much you can do to get rid of them.

Well, technically you can get rid of them, but then you have to deal with transparent triangles being out of order. And reordering the triangles in Purebasic is simply not possible and I don't see a good enough reason why it ever would be.
In other words you have to choose either jagged edges with correct ordering or smooth edges which have the possibility of incorrect ordering.

Now a simple explanation on how to use this shader with the textures you want. If you open TransparentMaterial.MATERIAL in notepad (or some other text editor) and scroll to the bottom you should find
Code:
material Transparent01 : TransparentTexture
{
   set $Texture Image01.png
}

material Transparent02 : TransparentTexture
{
   set $Texture Image02.png
}

I'll break down what these lines mean. The Transparent01 and Transparent02 are the Name$ that you call from Purebasic with GetScriptMaterial(#Material, Name$).
Image01.png and Image02.png are the actual image that the shader will use. In other words you need to write one of these out for every material that has a unique image.
For example if I were to add another one to the list it might look something like this.
Code:
material Transparent01 : TransparentTexture
{
   set $Texture Image01.png
}

material Transparent02 : TransparentTexture
{
   set $Texture Image02.png
}

material Stars : TransparentTexture
{
   set $Texture NightSky.png
}

And I'd call the new material in Purebasic like so.
Code:
MaterialHandle = GetScriptMaterial(#PB_Any, "Stars")


That's about all you need to do as the end user of this shader.
This script includes both GLSL and HLSL shaders so you don't need to worry about it not working on your system. Just include all the files and the script will pick whichever one is currently in use by your program.

Now then here's the link to all the files and the example code to run them. Just start up the pb file and it should run without an issue. If there are problems let me know and I'll see what I can do to fix them.
Shader Transparent.zip

I'll also post the script and shaders below, but you can ignore them if you downloaded the files from the link above.
Enjoy! :)



If you copy and paste them into notepad just make sure you save them exactly as labeled below.
TransparentMaterial.MATERIAL
Code:
// GLSL simple transparency
vertex_program transparencyVSGLSL glsl
{
   source TransparentGLSL.vert
}

fragment_program transparencyFSGLSL glsl
{
   source TransparentGLSL.frag
   default_params
   {
      param_named TexTU int 0
   }
}

// HLSL simple transparency
vertex_program transparencyVSHLSL hlsl
{
   source TransparentHLSL.hlsl
   entry_point AlphaTexture_Vert
   target vs_1_1 

   default_params
   {
      param_named_auto worldViewProj worldviewproj_matrix
   } 
}

fragment_program transparencyFSHLSL hlsl
{
   source TransparentHLSL.hlsl
   entry_point AlphaTexture_Frag
   target ps_2_0
}

// Delegates
vertex_program transparencyVp unified
{
   delegate transparencyVSGLSL
   delegate transparencyVSHLSL
}

fragment_program transparencyFp unified
{
   delegate transparencyFSGLSL
   delegate transparencyFSHLSL
}

abstract material TransparentTexture
{
   technique
   {
      pass
      {
         vertex_program_ref transparencyVp
         {
         }

         fragment_program_ref transparencyFp
         { 
         }

         texture_unit
         {
            texture $Texture
            tex_coord_set 0
         }
      }
   }

   technique
   {
      pass
      {
         texture_unit
         {
            texture $Texture
            tex_coord_set 0
         }
      }
   }
}

material Transparent01 : TransparentTexture
{
   set $Texture Image01.png
}

material Transparent02 : TransparentTexture
{
   set $Texture Image02.png
}


TransparentHLSL.HLSL
Code:
void AlphaTexture_Vert(
         float4 position : POSITION,
         float2 uv       : TEXCOORD0,
         uniform float4x4 worldViewProj,
         out     float4   oPosition : POSITION,
         out     float2   oUv       : TEXCOORD0)

{
   position = mul(worldViewProj, position);

   oPosition = position;

   oUv = uv;
}
 

void AlphaTexture_Frag(
         float4 position    : POSITION,
         float2 uv          : TEXCOORD0,
         out float4 oColour : COLOR,
         uniform sampler2D TextureMap : register(s0))

{   
   float4 Color = tex2D(TextureMap, uv.xy);

   float Black = Color.r + Color.g + Color.b;

   if(Black == 0)
      discard;

   oColour = Color;
}


TransparentGLSL.VERT

Code:
varying vec2 TexCoord;

void main(void)
{
   TexCoord = gl_MultiTexCoord0.xy;
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}


TransparentGLSL.FRAG

Code:
varying vec2 TexCoord;
uniform sampler2D TexTU;

void main(void)
{   
   vec4 Color = texture2D(TexTU, TexCoord);
 
   if (Color.rgb == vec3(0.0,0.0,0.0))
      discard;

   gl_FragColor = Color;
}


Top
 Profile  
Reply with quote  
 Post subject: Re: Transparent Black Pixel Shader
PostPosted: Sun Nov 22, 2015 1:34 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sat Feb 19, 2011 10:06 am
Posts: 681
Location: Denmark
Very nice example, Samuel.
Thanks.

_________________
“Tell me and I forget. Teach me and I remember. Involve me and I learn.”
— Benjamin Franklin
Current configurations: Windows 7/10, Intel 6800K, Gtx 970, 32 gb ram.


Top
 Profile  
Reply with quote  
 Post subject: Re: Transparent Black Pixel Shader
PostPosted: Fri Sep 08, 2017 6:28 pm 
Offline
User
User

Joined: Fri Sep 28, 2012 10:22 am
Posts: 39
I realise I am resurrecting an old thread.

@Samuel:

How would you go around replacing the texture in the shader 'on the fly'? I've tried

Code:
LoadTexture(0, "Image03.png")
    AddMaterialLayer(#ShaderMaterial1, TextureID(0), #PB_Material_Replace, 0)


but it doesn't seem to work? Is there a simple way to do this? Or do I need EntityCustomParameter(...)

Michael


Top
 Profile  
Reply with quote  
 Post subject: Re: Transparent Black Pixel Shader
PostPosted: Fri Sep 08, 2017 8:41 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Jul 29, 2012 10:33 pm
Posts: 706
Location: United States
I remember me and Alexi having some difficulty with that a few years back. The only solution we could come up with was recreating the texture's image on the hard drive and then reparsing the material scripts. Which wasn't efficient, but it worked.

Hmm, after looking through the newer 3D commands I think GetScriptTexture() might do the trick. If GetScriptTexture() is returning the texture's handle then you might be able to alter the texture by just drawing over it.


Top
 Profile  
Reply with quote  
 Post subject: Re: Transparent Black Pixel Shader
PostPosted: Mon Sep 11, 2017 1:52 pm 
Offline
User
User

Joined: Fri Sep 28, 2012 10:22 am
Posts: 39
Hi Samuel,

Thanks for the answer. I think you can do it by

Code:
        RemoveMaterialLayer(#ShaderMaterial1)
        AddMaterialLayer(#ShaderMaterial1, TextureID(TextureBlue), #PB_Material_Replace)


which seems encouraging.. I think removing it first must unregister the Texture with material script...

I'll play around a bit more and see what I can do...

Michael

Code:

If InitEngine3D(#PB_Engine3D_DebugLog) = 0
    MessageRequester("ERROR!", "Failed to initialize the 3D engine.", #PB_MessageRequester_Ok)
    End
EndIf

If InitSprite() = 0
    MessageRequester("ERROR!", "Failed to initialize the sprite environment.", #PB_MessageRequester_Ok)
    End
EndIf

If InitKeyboard() = 0
    MessageRequester("ERROR!", "Failed to initialize the keyboard environment.", #PB_MessageRequester_Ok)
    End
EndIf

Enumeration
    #Window
    #Camera
    #Node
    #Light
    #Sphere
    #Plane
    #ShaderEntity1
    #ShaderEntity2
    #RegularEntity1
    #RegularEntity2
    #ShaderMaterial1
    #ShaderMaterial2
    #RegularTexture1
    #RegularTexture2
    #RegularMaterial1
    #RegularMaterial2
EndEnumeration

ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)

OpenWindow(#Window, 0, 0, DesktopW, DesktopH, "Black To Alpha Shader")
OpenWindowedScreen(WindowID(#Window), 0, 0, DesktopW, DesktopH)



TextureBlue.i = CreateTexture(#PB_Any, 256, 256)
StartDrawing(TextureOutput(TextureBlue))
Box(0, 0, TextureWidth(TextureBlue)/2, TextureHeight(TextureBlue)/2, RGB(0, 0, 255))
StopDrawing()
MaterialBlue.i = CreateMaterial(#PB_Any, TextureID(TextureBlue))


Add3DArchive("scripts/", #PB_3DArchive_FileSystem)
Add3DArchive("shaders/", #PB_3DArchive_FileSystem)
Add3DArchive("textures/", #PB_3DArchive_FileSystem)
Parse3DScripts() ;We need to Parse the Archives when using scripts and shaders
LoadTexture(#RegularTexture1, "Image01.png")

CreateSphere(#Sphere, 1)
CreateSphere(#Plane, 1)

;Load First Shader
GetScriptMaterial(#ShaderMaterial1, "Transparent01")
MaterialFilteringMode(#ShaderMaterial1, #PB_Material_None)
MaterialCullingMode(#ShaderMaterial1, #PB_Material_NoCulling)

;Load Second Shader
GetScriptMaterial(#ShaderMaterial2, "Transparent02")
MaterialFilteringMode(#ShaderMaterial2, #PB_Material_None)
MaterialCullingMode(#ShaderMaterial2, #PB_Material_NoCulling)

;Create First Shader Entity
CreateEntity(#ShaderEntity1, MeshID(#Sphere), MaterialID(#ShaderMaterial1), -4, 0, 0)
RotateEntity(#ShaderEntity1, 0, 180, 0)

;Create Second Shader Entity
CreateEntity(#ShaderEntity2, MeshID(#Plane), MaterialID(#ShaderMaterial2), 4, 0, 0)
RotateEntity(#ShaderEntity2, 0, 180, 0)


;####
;The Materials and Entities Below are not using the shaders.
;They are just for a before and after effect.

CreateMaterial(#RegularMaterial1, TextureID(#RegularTexture1))
MaterialFilteringMode(#RegularMaterial1, #PB_Material_None)

LoadTexture(#RegularTexture2, "Image02.png")
CreateMaterial(#RegularMaterial2, TextureID(#RegularTexture2))
MaterialFilteringMode(#RegularMaterial2, #PB_Material_None)

CreateEntity(#RegularEntity1, MeshID(#Plane), MaterialID(#RegularMaterial1), 4, 0, -4)
RotateEntity(#RegularEntity1, 0, 180, 0)

CreateEntity(#RegularEntity2, MeshID(#Sphere), MaterialID(#RegularMaterial2), -4, 0, -4)
RotateEntity(#RegularEntity2, 0, 180, 0)
;####


CreateCamera(#Camera, 0, 0, 100, 100)
MoveCamera  (#Camera, 0, 0, 20)
CameraLookAt(#Camera, 0, 0, 0)
CameraBackColor(#Camera, RGB(50, 100, 150))

CreateLight(#Light, RGB(255,255,255), 5, 5, 5)

CreateNode(#Node, 0, 0, 0)
AttachNodeObject(#Node, CameraID(#Camera))

Repeat
   
    Event = WindowEvent()
   
    If ExamineKeyboard()
        If KeyboardPushed(#PB_Key_Up)
            MoveCamera(#Camera, 0, 0, -0.2)
        ElseIf KeyboardPushed(#PB_Key_Down)
            MoveCamera(#Camera, 0, 0, 0.2)
        EndIf
        If KeyboardPushed(#PB_Key_Left)
            RotateNode(#Node, 0, -1, 0, #PB_Relative)
            CameraLookAt(#Camera, 0, 0, 0)
        ElseIf KeyboardPushed(#PB_Key_Right)
            RotateNode(#Node, 0, 1, 0, #PB_Relative)
            CameraLookAt(#Camera, 0, 0, 0)
        EndIf
        If KeyboardReleased(#PB_Key_W)
            CameraRenderMode(#Camera, #PB_Camera_Wireframe)
        ElseIf KeyboardReleased(#PB_Key_E)
            CameraRenderMode(#Camera, #PB_Camera_Textured)
        EndIf
    EndIf
   
    If KeyboardReleased(#PB_Key_Space)
        RemoveMaterialLayer(#ShaderMaterial1)
        AddMaterialLayer(#ShaderMaterial1, TextureID(TextureBlue), #PB_Material_Replace)
    EndIf
   
    RenderWorld()
    FlipBuffers()
   
Until Event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)


End


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye