Page 1 of 1

PerPixel Shader

Posted: Wed Dec 25, 2013 12:22 am
by Samuel
# UPDATE #
You can now use textures.
The shader currently has 3 passes. When I get time I 'll cut it down to two.
There's also an issue with OpenGL. So, for the time being it's DirectX only.
##

The standard lighting in Purebasic uses an entites vertices and normals to calculate it's lighting.
If an entity has very few vertices the lighting can be poor quality. To fix this you can use a shader that gives accurate lighting based on pixels.
This will take more power to run compared to the standard lighting, but nowadays most computers should handle this without a problem.

Here's an image of a low poly sphere with PerPixel Lighting. The plane beneath the sphere is also low poly.
Image


EDIT:

I forgot to mention this shader is from the OGRE wiki. This shader is free to use for whatever you like.
http://www.ogre3d.org/tikiwiki/tiki-ind ... ighting+II
The original poster kinda made a mess by adding several different shader possibilities into one.
So, I just grabbed the parts I liked.


Here's a download with everything ready to go.
It also includes the required CG.dll to run this shader.
PerPixel.zip

The CG.dll is from Nvidia's CG Toolkit located here.
https://developer.nvidia.com/cg-toolkit


The files below are the same ones from the download above. I'm just posting them for future reference for when the download is no more.
I'm not really going to explain in great detail how to set up the files.
You can look at my previous shader topics or just ask me if you need more info on how to setup these files.

Save exactly as stated and put them all in the same directory on your computer. You can use notepad or something like Yaose.

PerPixel.cg

Code: Select all

float3 expand(float3 v)
{
     return (v - 0.5) * 2;
}

 void OneTexture_vp(float4 position : POSITION,
           float2 uv          : TEXCOORD0,
 
           out float4 oPosition : POSITION,
           out float2 oUv       : TEXCOORD0, 
 
           uniform float4x4 worldViewProj,
           uniform float scale)
 {
     oPosition = mul(worldViewProj, position);
     oUv = uv * scale;
 }

 void Ambient_vp(
             float4 position : POSITION,
             out float4 oPosition : POSITION,
             out float4 colour    : COLOR,
             uniform float4x4 worldViewProj,
             uniform float4 ambient)
 {
     oPosition = mul(worldViewProj, position);
     colour = ambient;
 }
 
 void Perpixel_Vert(
             float4 position : POSITION, 
             float3 normal   : NORMAL,
             uniform float4 lightPosition,
             uniform float3 eyePosition,
             uniform float4x4 worldviewproj, 
 
             out float4 oClipPos    : POSITION,
             out float4 oPos    : TEXCOORD0,
             out float3 oNorm    : TEXCOORD1,
             out float4 oLightPos    : TEXCOORD2,            
             out float3 oEyePos    : TEXCOORD3
              ) 
 { 
     oClipPos = mul(worldviewproj, position); 
     oPos = position;
     oNorm     = normal; 
     oLightPos = lightPosition;
     oEyePos = eyePosition;

 } 
 
 
 void PerPixel_Frag(
             float4 pos         : TEXCOORD0,
             float3 normal        : TEXCOORD1, 
             float4 lightpos        : TEXCOORD2,
             float3 eyepos        : TEXCOORD3,
             uniform float4 lightDiffuse,
             uniform float4 lightSpecular,
             uniform float exponent,
             out float4 oColor : COLOR 
 ) 
 {
     float3 N = normalize(normal);

     float3 EyeDir = normalize(eyepos - pos.xyz);
     float3 LightDir = normalize(lightpos.xyz -  (pos * lightpos.w));
     float3 HalfAngle = normalize(LightDir + EyeDir);
 
     float NdotL = dot(LightDir, N);
     float NdotH = dot(HalfAngle, N);
     float4 Lit = lit(NdotL,NdotH,exponent);

     oColor = lightDiffuse * Lit.y + lightSpecular * Lit.z;
 }

PerPixel.material

Code: Select all


abstract material PerPixel
{ 
	technique 
	{

		pass
		{    
			vertex_program_ref Ambient
			{
                		param_named ambient float4 $Ambient
			}
		}
		pass 
		{ 
			iteration once_per_light
			scene_blend add
 
			vertex_program_ref Perpixel_Vert
			{ 
			} 
 
			fragment_program_ref PerPixel_Frag
			{ 
				param_named exponent float $SpecularSize
			} 
		} 
		pass
		{
 
			vertex_program_ref OneTexture
			{
				param_named scale float $Scale
			}   
 
			scene_blend modulate
			texture_unit TextureMap
			{
				filtering trilinear
			}            
		}
	} 
}
material RockPerPixel : PerPixel
{
    set $Ambient "0 0 0 1"
    set $SpecularSize 64
    set $Scale 1
    set_texture_alias TextureMap Rocks.png
}

//material [Script Name] : [Script Template]
//{
//    set $Ambient "0 0 0 1"
//    ["Red Green Blue Alpha" Values Between "0" and "1"]

//    set $SpecularSize 64
//    [Specular Recommended Value Between "32" and "512"]

//    set $Scale 1
//    [Texture Repeat]

//    set_texture_alias TextureMap Rocks.png
//    [Replace "Rocks.png" With Your Texture]
//}
PerPixel.program

Code: Select all

vertex_program OneTexture cg
{
	source PerPixel.cg 
	entry_point OneTexture_vp
	profiles vs_1_1 arbvp1
	default_params
	{
		param_named_auto worldViewProj worldviewproj_matrix
	}
}

vertex_program Ambient cg
{
	source PerPixel.cg 
	entry_point Ambient_vp
	profiles vs_1_1 arbvp1

	default_params
	{
		param_named_auto worldViewProj worldviewproj_matrix
	}
}

vertex_program Perpixel_Vert cg 
{ 
	source PerPixel.cg 
	entry_point Perpixel_Vert 
	profiles vs_1_1 arbvp1 

	default_params 
	{ 
		param_named_auto lightPosition light_position_object_space 0
		param_named_auto eyePosition camera_position_object_space
		param_named_auto worldviewproj worldviewproj_matrix
	} 
} 
 
fragment_program PerPixel_Frag cg 
{ 
	source PerPixel.cg  
	entry_point PerPixel_Frag
	profiles ps_2_0 arbfp1

	default_params 
	{
		param_named_auto lightDiffuse light_diffuse_colour 0
		param_named_auto lightSpecular light_specular_colour 0
	} 
}

Here's the Purebasic code to run the shader.
You'll need to set the Add3DArchive() to the location of the cg and material files.

Code: Select all

;#### Requires Nvidia's CG Toolkit to be installed onto your computer (https://developer.nvidia.com/cg-toolkit)####
;#### or have the required CG.dll in the Root Directory of your app ####

If InitEngine3D(#PB_Engine3D_EnableCG | #PB_Engine3D_DebugLog)=0
  End
EndIf
If InitSprite()=0
  End
EndIf
If InitKeyboard()=0
  End
EndIf

Enumeration
  #Window
  #Font
  #Help
  #Camera
  #LowPolySphere
  #Plane
  #SphereMesh
  #Sphere1
  #Sphere2
  #Sphere3
  #Sphere4
  #Mat1
  #Mat2
  #Mat3
  #Mat4
  #Light1
  #Light2
  #Light3
  #Light4
  #Node1
  #Node2
  #PerPixelMat
  #RockMat
EndEnumeration

ExamineDesktops()
DeskTopW = DesktopWidth(0)
DeskTopH = DesktopHeight(0)

Wireframe=0
Material=0
ShowHelp=0

If LoadFont(#Font, "Courier New", 10,#PB_Font_Bold)
  SetGadgetFont(#PB_Default, FontID(#Font))
EndIf

CPU$ = CPUName()

If OpenWindow(#Window, 0, 0, DeskTopW, DeskTopH, "Per Pixel Lighting. Have a Merry Christmas and a Happy New Year!")
  If OpenWindowedScreen(WindowID(#Window), 0, 0, DeskTopW, DeskTopH, 0, 0, 0)
    
    ;#### Set Archive To Root Location ####
    Add3DArchive("/", #PB_3DArchive_FileSystem)
    Parse3DScripts()
    
    ;#### Create Sprite For Information ####
    CreateSprite(#Help, 300, 200)
    StartDrawing(SpriteOutput(#Help))
      Box(0,0,300,200,RGB(20,20,20))
    StopDrawing()
    
    ;#### Create Lights ####
    CreateLight(#Light1, RGB( 0, 0, 0), 5, 5, 5)
    SetLightColor(#Light1,#PB_Light_DiffuseColor,RGB(200,0,0))
    SetLightColor(#Light1,#PB_Light_SpecularColor,RGB(255,100,0))
    CreateLight(#Light2, RGB( 0, 0, 0), -5, 5, 5)
    SetLightColor(#Light2,#PB_Light_DiffuseColor,RGB(0,200,0))
    SetLightColor(#Light2,#PB_Light_SpecularColor,RGB(0,255,100))
    CreateLight(#Light3, RGB( 0, 0, 0), 0, 5, -7.5)
    SetLightColor(#Light3,#PB_Light_DiffuseColor,RGB(0,0,200))
    SetLightColor(#Light3,#PB_Light_SpecularColor,RGB(0,100,255))
    CreateLight(#Light4, RGB( 0, 0, 0), 0, -4.5, 0)
    SetLightColor(#Light4,#PB_Light_DiffuseColor,RGB(200,200,200))
    SetLightColor(#Light4,#PB_Light_SpecularColor,RGB(255,255,255))
    
    ;#### Load The Script For The Per Pixel Lighting ####
    GetScriptMaterial(#PerPixelMat,"RockPerPixel")
    LoadTexture(#RockMat,"Rocks.png")
    CreateMaterial(#RockMat,TextureID(#RockMat))
    
    ;#### Create Textures And Materials ####
    CreateTexture(#Mat1,32,32)
    CreateTexture(#Mat2,32,32)
    CreateTexture(#Mat3,32,32)
    CreateTexture(#Mat4,32,32)
    StartDrawing(TextureOutput(#Mat1))
      Box(0,0,32,32,RGB(200,0,0))
    StopDrawing()
    StartDrawing(TextureOutput(#Mat2))
      Box(0,0,32,32,RGB(0,200,0))
    StopDrawing()
    StartDrawing(TextureOutput(#Mat3))
      Box(0,0,32,32,RGB(0,0,200))
    StopDrawing()
    StartDrawing(TextureOutput(#Mat4))
      Box(0,0,32,32,RGB(200,200,200))
    StopDrawing()
    
    CreateMaterial(#Mat1,TextureID(#Mat1))
    CreateMaterial(#Mat2,TextureID(#Mat2))
    CreateMaterial(#Mat3,TextureID(#Mat3))
    CreateMaterial(#Mat4,TextureID(#Mat4))
    SetMaterialColor(#RockMat,#PB_Material_SpecularColor,RGB(255,255,255))
    SetMaterialColor(#RockMat,#PB_Material_AmbientColor,RGB(0,0,0))
    MaterialShininess(#RockMat,64)
    
    ;#### Create Nodes, Meshes, And Entities ####
    CreateNode(#Node1, 0, 0, 0)
    CreateNode(#Node2, 0, 0, 0)
    
    CreateSphere(#SphereMesh,0.25)
    CreatePlane(#Plane,200,200,1,1,10,10)
    CreateSphere(#LowPolySphere,3,12,6)
    
    CreateEntity(#LowPolySphere, MeshID(#LowPolySphere), MaterialID(#PerPixelMat))
    CreateEntity(#Plane, MeshID(#Plane), MaterialID(#PerPixelMat),0,-5,0)
    CreateEntity(#Sphere1, MeshID(#SphereMesh), MaterialID(#Mat1),LightX(#Light1),LightY(#Light1),LightZ(#Light1))
    CreateEntity(#Sphere2, MeshID(#SphereMesh), MaterialID(#Mat2),LightX(#Light2),LightY(#Light2),LightZ(#Light2))
    CreateEntity(#Sphere3, MeshID(#SphereMesh), MaterialID(#Mat3),LightX(#Light3),LightY(#Light3),LightZ(#Light3))
    CreateEntity(#Sphere4, MeshID(#SphereMesh), MaterialID(#Mat4),LightX(#Light4),LightY(#Light4),LightZ(#Light4))
    
    ;#### Setup Camera ####
    CreateCamera(#Camera, 0,0,100,100)
    MoveCamera(#Camera, 0, 0, 20)
    CameraLookAt(#Camera, 0, 0, 0)
    CameraBackColor(#Camera, RGB(40, 40, 40))
    
    ;#### Attach Objects To Nodes ####
    AttachNodeObject(#Node1,CameraID(#Camera))
    AttachNodeObject(#Node2,LightID(#Light1))
    AttachNodeObject(#Node2,LightID(#Light2))
    AttachNodeObject(#Node2,LightID(#Light3))
    AttachNodeObject(#Node2,LightID(#Light4))
    AttachNodeObject(#Node2,EntityID(#Sphere1))
    AttachNodeObject(#Node2,EntityID(#Sphere2))
    AttachNodeObject(#Node2,EntityID(#Sphere3))
    AttachNodeObject(#Node2,EntityID(#Sphere4))

    Repeat
      ;#### Examine Keyboard For Key Presses ####
      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(#Node1,0,-1,0,#PB_Relative)
          CameraLookAt(#Camera, 0, 0, 0)
        ElseIf KeyboardPushed(#PB_Key_Right)
          RotateNode(#Node1,0,1,0,#PB_Relative)
          CameraLookAt(#Camera, 0, 0, 0)
        EndIf
        If KeyboardReleased(#PB_Key_W)
          If Wireframe=0
            CameraRenderMode(#Camera, #PB_Camera_Wireframe)
            Wireframe=1
          Else
            CameraRenderMode(#Camera, #PB_Camera_Textured)
            Wireframe=0
          EndIf
        EndIf
        If KeyboardReleased(#PB_Key_E)
          If Material=0
            SetEntityMaterial(#LowPolySphere, MaterialID(#RockMat))
            Material=1
          Else
            SetEntityMaterial(#LowPolySphere, MaterialID(#PerPixelMat))
            Material=0
          EndIf
        EndIf
        If KeyboardReleased(#PB_Key_H)
          If ShowHelp=0
            ShowHelp=1
          Else
            ShowHelp=0
          EndIf
        EndIf
      EndIf
      
      ;#### Rotate The Node That Has Lights Attached ####
      RotateNode(#Node2,0,1,0,#PB_Relative)
      
      RenderWorld()
      
      ;#### Update Sprite Information ####
      If ShowHelp = 0
        CurrentFPS = Engine3DFrameRate(#PB_Engine3D_Current)
        AverageFPS = Engine3DFrameRate(#PB_Engine3D_Average)
        MaximumFPS = Engine3DFrameRate(#PB_Engine3D_Maximum)
        MinimumFPS = Engine3DFrameRate(#PB_Engine3D_Minimum)
        CountTris = CountRenderedTriangles()
        StartDrawing(SpriteOutput(#Help))
          Box(0,0,300,200,RGB(20,20,20))
          DrawingFont(FontID(#Font)) 
          DrawText(2,2,CPU$,RGB(255,0,0),RGB(20,20,20))
          DrawText(2,22,"Current FPS : "+Str(CurrentFPS),RGB(0,255,255),RGB(20,20,20))
          DrawText(2,42,"Average FPS : "+Str(AverageFPS),RGB(0,255,255),RGB(20,20,20))
          DrawText(2,62,"Maximum FPS : "+Str(MaximumFPS),RGB(0,255,255),RGB(20,20,20))
          DrawText(2,82,"Minimum FPS : "+Str(MinimumFPS),RGB(0,255,255),RGB(20,20,20))
          DrawText(2,102,"Rendered Triangles : "+Str(CountTris),RGB(0,255,0),RGB(20,20,20))
          DrawText(2,122,"(Press W To Swap CameraRenderMode)",RGB(255,255,255),RGB(20,20,20))
          DrawText(2,142,"(Press E To Swap Sphere's Lighting",RGB(255,255,0),RGB(20,20,20))
          DrawText(2,162," Type From PerPixel To Standard)",RGB(255,255,0),RGB(20,20,20))
          DrawText(2,182,"(Press H To Toggle Help)",RGB(255,155,255),RGB(20,20,20))
        StopDrawing()
        DisplayTransparentSprite(#Help,20,20)
        If FirstFrame = 0
          Engine3DFrameRate(#PB_Engine3D_Reset)
          FirstFrame = 1
        EndIf
      EndIf
      FlipBuffers()

    Until WindowEvent() = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
    
  EndIf
EndIf

End
That's all there is to it. Just ask if you have any questions and let me know if you see any errors.
If anyone wants to make improvements or additions to this shader. Please post your changes for us all to see and try.
You don't have too, but it's a nice treat for us all.

I wish everyone a Merry Christmas and a Happy New Year! :D

Re: PerPixel Shader

Posted: Wed Dec 25, 2013 2:06 am
by rsts
Wow. A most impressive holiday treat.

Merry Christmas to you too. :D

Re: PerPixel Shader

Posted: Wed Dec 25, 2013 5:28 am
by AtomUpgrader
Is it possible to also use custom generated cube maps, refraction, deferred shading? :)

Re: PerPixel Shader

Posted: Wed Dec 25, 2013 6:27 am
by applePi
there are too much goodies today i can't tolerate.
thanks Samuel very much

Re: PerPixel Shader

Posted: Wed Dec 25, 2013 9:11 am
by Samuel
AtomUpgrader wrote:Is it possible to also use custom generated cube maps, refraction, deferred shading? :)
It's not possible as the shader is now. You would need to add them into it.
I believe cube maps are pretty easy to implement. I might be able to look into it after the holidays.

Deferred shading is mainly for a performance increase. It's complex and usually requires other shaders and compositors to be involved in order to work properly.
In other words it's a bit of a pain to work with.

I've never really worked with a Refraction shader before, but I have seen some examples.
From what I can tell it would also be a complex addition to this shader.

Pretty much any graphic effect can be included in a shader.
The only problem is making a customized shader like that is time consuming and can be a lot of hard work.
Not exactly the most enjoyable thing to do when you only have a little spare time each day to work on it.

So, while I may not be able to help you much.
You may be able to help yourself by picking up a book about shaders and start the learning process.

The forums are in need of some more Purebasic users with shader experience. :wink:
I'd guess there's been no more then 20 topics about shaders in Purebasic's life time.
I would like to see that change though. So, if your interested pick up that book and maybe post some examples.

Sorry about the rambling. :oops:
You had one sentence and I respond with this massive hunk of junk.

Re: PerPixel Shader

Posted: Wed Dec 25, 2013 7:04 pm
by Samuel
The shader will have texture support in the next day or so.
It's all ready working, but I don't have enough spare time to update my original post yet.

Image

Re: PerPixel Shader

Posted: Wed Dec 25, 2013 8:18 pm
by applePi
Samuel, thats too much beautiful, i have tried to light the glass in my previous demo, i have assign it to the #LowPolySphere, so the phenomena is there is lines of color along the glass walls so this is like reality
Image
thats great so we can use the shader to cast color on materials who are not thick and to show lines of light, but the glass base are hidden from this viewpoint. just i want to show you this interesting phenomena. if you want to see the full cup uncomment tex ans mat in the glass procedure and assign mat to the glass cup but it is not interesting like these lines of color .
below is your shader to cast color on my cup

Code: Select all

;#### Requires Nvidia's CG Toolkit to be installed onto your computer (https://developer.nvidia.com/cg-toolkit)####
;#### or have the required CG.dll in the Root Directory of your app ####
Declare glass(k.f)
If InitEngine3D(#PB_Engine3D_EnableCG | #PB_Engine3D_DebugLog)=0
  End
EndIf
If InitSprite()=0
  End
EndIf
If InitKeyboard()=0
  End
EndIf
Global Mat
Enumeration
  #Window
  #Font
  #Help
  #Camera
  #LowPolySphere
  #Plane
  #SphereMesh
  #Sphere1
  #Sphere2
  #Sphere3
  #Mat0
  #Mat1
  #Mat2
  #Mat3
  #Light1
  #Light2
  #Light3
  #Node1
  #Node2
  #PerPixelMat
EndEnumeration

ExamineDesktops()
DeskTopW = DesktopWidth(0)
DeskTopH = DesktopHeight(0)

Wireframe=0
Material=0
ShowHelp=0

If LoadFont(#Font, "Courier New", 10,#PB_Font_Bold)
  SetGadgetFont(#PB_Default, FontID(#Font))
EndIf

CPU$ = CPUName()

If OpenWindow(#Window, 0, 0, DeskTopW, DeskTopH, "Per Pixel Lighting. Have a Merry Christmas and a Happy New Year!")
  If OpenWindowedScreen(WindowID(#Window), 0, 0, DeskTopW, DeskTopH, 0, 0, 0)
    
    ;#### Set Archive To Root Location ####
    Add3DArchive("/", #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)
    Parse3DScripts()
    
    ;#### Create Sprite For Information ####
    CreateSprite(#Help, 300, 200)
    StartDrawing(SpriteOutput(#Help))
      Box(0,0,300,200,RGB(20,20,20))
    StopDrawing()
    
    ;#### Create Lights ####
    CreateLight(#Light1, RGB( 0, 0, 0), 5, 5, 5)
    SetLightColor(#Light1,#PB_Light_DiffuseColor,RGB(200,0,0))
    SetLightColor(#Light1,#PB_Light_SpecularColor,RGB(255,100,0))
    CreateLight(#Light2, RGB( 0, 0, 0), -5, 5, 5)
    SetLightColor(#Light2,#PB_Light_DiffuseColor,RGB(0,200,0))
    SetLightColor(#Light2,#PB_Light_SpecularColor,RGB(0,255,100))
    CreateLight(#Light3, RGB( 0, 0, 0), 0, 5, -7)
    SetLightColor(#Light3,#PB_Light_DiffuseColor,RGB(0,0,200))
    SetLightColor(#Light3,#PB_Light_SpecularColor,RGB(0,100,255))
    
    ;#### Load The Script For The Per Pixel Lighting ####
    GetScriptMaterial(#PerPixelMat,"PerPixel")
    
    ;#### Create Textures And Materials ####
    CreateTexture(#Mat0,32,32)
    CreateTexture(#Mat1,32,32)
    CreateTexture(#Mat2,32,32)
    CreateTexture(#Mat3,32,32)
    StartDrawing(TextureOutput(#Mat0))
      Box(0,0,32,32,RGB(100,100,100))
    StopDrawing()
    StartDrawing(TextureOutput(#Mat1))
      Box(0,0,32,32,RGB(200,0,0))
    StopDrawing()
    StartDrawing(TextureOutput(#Mat2))
      Box(0,0,32,32,RGB(0,200,0))
    StopDrawing()
    StartDrawing(TextureOutput(#Mat3))
      Box(0,0,32,32,RGB(0,0,200))
    StopDrawing()
    
    CreateMaterial(#Mat0,TextureID(#Mat0))
    CreateMaterial(#Mat1,TextureID(#Mat1))
    CreateMaterial(#Mat2,TextureID(#Mat2))
    CreateMaterial(#Mat3,TextureID(#Mat3))
    SetMaterialColor(#Mat0,#PB_Material_SpecularColor,RGB(255,255,255))
    MaterialShininess(#Mat0,127)
    
    ;#### Create Nodes, Meshes, And Entities ####
    CreateNode(#Node1, 0, 0, 0)
    CreateNode(#Node2, 0, 0, 0)
    
    CreateSphere(#SphereMesh,0.25)
    CreatePlane(#Plane,200,200,1,1,1,1)
    ;CreateSphere(#LowPolySphere,3,16,16)
    
    CreateMesh(#LowPolySphere, #PB_Mesh_TriangleList, #PB_Mesh_Static)
glass(0.4) ; glass cup
;CreateEntity(#LowPolySphere, MeshID(#LowPolySphere), MaterialID(Mat))  
;ScaleEntity(#LowPolySphere,0.6, 0.6, 0.6)
;MoveEntity(#LowPolySphere,0,42,50,#PB_Absolute)
;RotateEntity(1,-90,0,0,#PB_Relative)
    
    CreateEntity(#LowPolySphere, MeshID(#LowPolySphere), MaterialID(#PerPixelMat))
    CreateEntity(#Plane, MeshID(#Plane), MaterialID(#PerPixelMat),0,-5,0)
    CreateEntity(#Sphere1, MeshID(#SphereMesh), MaterialID(#Mat1),LightX(#Light1),LightY(#Light1),LightZ(#Light1))
    CreateEntity(#Sphere2, MeshID(#SphereMesh), MaterialID(#Mat2),LightX(#Light2),LightY(#Light2),LightZ(#Light2))
    CreateEntity(#Sphere3, MeshID(#SphereMesh), MaterialID(#Mat3),LightX(#Light3),LightY(#Light3),LightZ(#Light3))
    
    ScaleEntity(#LowPolySphere,0.15, 0.15, 0.15)
    RotateEntity(#LowPolySphere,-90,0,0,#PB_Relative)
    MoveEntity(#LowPolySphere,0,-1,0,#PB_Absolute)
    ;#### Setup Camera ####
    CreateCamera(#Camera, 0,0,100,100)
    MoveCamera(#Camera, 0, 15, 20)
    CameraLookAt(#Camera, 0, 0, 0)
    CameraBackColor(#Camera, RGB(40, 40, 40))
    
    ;#### Attach Objects To Nodes ####
    AttachNodeObject(#Node1,CameraID(#Camera))
    AttachNodeObject(#Node2,LightID(#Light1))
    AttachNodeObject(#Node2,LightID(#Light2))
    AttachNodeObject(#Node2,LightID(#Light3))
    AttachNodeObject(#Node2,EntityID(#Sphere1))
    AttachNodeObject(#Node2,EntityID(#Sphere2))
    AttachNodeObject(#Node2,EntityID(#Sphere3))
    

    Repeat
      ;#### Examine Keyboard For Key Presses ####
      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(#Node1,0,-1,0,#PB_Relative)
          CameraLookAt(#Camera, 0, 0, 0)
        ElseIf KeyboardPushed(#PB_Key_Right)
          RotateNode(#Node1,0,1,0,#PB_Relative)
          CameraLookAt(#Camera, 0, 0, 0)
        EndIf
        If KeyboardReleased(#PB_Key_W)
          If Wireframe=0
            CameraRenderMode(#Camera, #PB_Camera_Wireframe)
            Wireframe=1
          Else
            CameraRenderMode(#Camera, #PB_Camera_Textured)
            Wireframe=0
          EndIf
        EndIf
        If KeyboardReleased(#PB_Key_E)
          If Material=0
            SetEntityMaterial(#LowPolySphere, MaterialID(#Mat0))
            Material=1
          Else
            SetEntityMaterial(#LowPolySphere, MaterialID(#PerPixelMat))
            Material=0
          EndIf
        EndIf
        If KeyboardReleased(#PB_Key_H)
          If ShowHelp=0
            ShowHelp=1
          Else
            ShowHelp=0
          EndIf
        EndIf
      EndIf
      
      ;#### Rotate The Node That Has Lights Attached ####
      RotateNode(#Node2,0,1,0,#PB_Relative)
      
      RenderWorld()
      
      ;#### Update Sprite Information ####
      If ShowHelp = 0
        CurrentFPS = Engine3DFrameRate(#PB_Engine3D_Current)
        AverageFPS = Engine3DFrameRate(#PB_Engine3D_Average)
        MaximumFPS = Engine3DFrameRate(#PB_Engine3D_Maximum)
        MinimumFPS = Engine3DFrameRate(#PB_Engine3D_Minimum)
        CountTris = CountRenderedTriangles()
        StartDrawing(SpriteOutput(#Help))
          Box(0,0,300,200,RGB(20,20,20))
          DrawingFont(FontID(#Font)) 
          DrawText(2,2,CPU$,RGB(255,0,0),RGB(20,20,20))
          DrawText(2,22,"Current FPS : "+Str(CurrentFPS),RGB(0,255,255),RGB(20,20,20))
          DrawText(2,42,"Average FPS : "+Str(AverageFPS),RGB(0,255,255),RGB(20,20,20))
          DrawText(2,62,"Maximum FPS : "+Str(MaximumFPS),RGB(0,255,255),RGB(20,20,20))
          DrawText(2,82,"Minimum FPS : "+Str(MinimumFPS),RGB(0,255,255),RGB(20,20,20))
          DrawText(2,102,"Rendered Triangles : "+Str(CountTris),RGB(0,255,0),RGB(20,20,20))
          DrawText(2,122,"(Press W To Swap CameraRenderMode)",RGB(255,255,255),RGB(20,20,20))
          DrawText(2,142,"(Press E To Swap Sphere's Lighting",RGB(255,255,0),RGB(20,20,20))
          DrawText(2,162," Type From PerPixel To Standard)",RGB(255,255,0),RGB(20,20,20))
          DrawText(2,182,"(Press H To Toggle Help)",RGB(255,155,255),RGB(20,20,20))
        StopDrawing()
        DisplayTransparentSprite(#Help,20,20)
        If FirstFrame = 0
          Engine3DFrameRate(#PB_Engine3D_Reset)
          FirstFrame = 1
        EndIf
      EndIf
      FlipBuffers()

    Until WindowEvent() = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
    
  EndIf
EndIf


End

Procedure glass(incr.f)
;Tex  = LoadTexture(#PB_Any, "clouds.jpg")
;Mat = CreateMaterial(#PB_Any, TextureID(Tex))
;MaterialBlendingMode(Mat, #PB_Material_AlphaBlend)
;SetMaterialColor(Mat, #PB_Material_DiffuseColor, RGBA(255, 255, 255, 150))
;MaterialCullingMode(Mat, #PB_Material_NoCulling)
x.f: y.f :z.f : u.f: v.f: r.f
      majorOrbit.l = 100 : minorOrbit.l = 20
      majorStep.f   = 2 * #PI / majorOrbit
      minorStep.f   = 2 * #PI / minorOrbit
      i.l: j.l: txu.f : txv.f
      Zincr.f 
       
      Nozzle.f = -15  ; determine the radius of the smaller nozzle of the funnel
      Nozzle2.f = 4
      
      For i = 0 To majorOrbit
        
        If i <= 20
          Nozzle.f  + incr
          
          Zincr = 0.3 ; Zincr determine the rate of increase/decrease the circles radius over time
        EndIf
        
        If i <= 60 And i > 20
         
          Zincr = 0.45
          Nozzle = 4
        EndIf 
                
            If i = 61     ; the end of the cup handle and the begening of its big cone (which contains the Liquid)
           
              Nozzle = 0  ; to close the cup handle, it will close the big cone bottom
            EndIf 
       
        If i > 61  ; the begening of the big cone (which contains the Liquid)
          
         ; Zincr = 0.45
                     
          Nozzle2.f  + incr  ; incr determines the radius of the bigger nozzle
          Nozzle = Nozzle2
        EndIf 
        
        v = i * majorStep
        For j = 0 To minorOrbit
          u = j * minorStep
          
          x = Cos(u)*Nozzle 
          y = Sin(u)*Nozzle
         
          ;===========================================
          MeshVertexPosition(x, y, z);
          MeshVertexTextureCoordinate(txu, txv)
          MeshVertexNormal(x, y, z)
          ; texture the whole mesh with one picture stretched
          txv = txv + 1/minorOrbit ; texture coordinates
          
        Next
        
        If i > 61
            y2.f = 0.25 * x * x - 1.5 * x + 0.25 ;parabola curve
            Zincr = y2/40
          EndIf
        z + Zincr
        
        
        txv = 0
        txu = txu + 1/majorOrbit 
      Next
      For i = 0 To majorOrbit-1
      For j = 0 To minorOrbit
         
        MeshFace(t,t + minorOrbit+1,t+1)
        MeshFace(t + minorOrbit+1,t + minorOrbit+2,t+1 )
        
          If i=majorOrbit-1 And j=minorOrbit-1 ;bypass the last triangle
            minorOrbit-1
          EndIf 
          t + 1   
          
     Next
     
   Next  
   NormalizeMesh(#LowPolySphere)
    FinishMesh(#True)
    
  EndProcedure
  

Re: PerPixel Shader

Posted: Thu Dec 26, 2013 9:53 am
by Bananenfreak
What? Your shader have possibilities for ambient lightning and transparent realistic light?

Good work Samuel, as always :D

Re: PerPixel Shader

Posted: Mon Dec 30, 2013 10:18 am
by Samuel
Sorry for the late reply, guys.
I've been a little under the weather these last few days. So, I've just been relaxing and being lazy. :D
I finally updated the download. So, you can now use textures in the shader.
To use your own texture just change "Rocks.png" in the .material file to your texture.
applePi wrote:Samuel, thats too much beautiful i have tried to light the glass in my previous demo, i have assign it to the #LowPolySphere, so the phenomena is there is lines of color along the glass walls so this is like reality
Thanks and nice example, applePi.
I changed the lighting a little bit in the shader. So, hopefully it will still work nicely for you.
The problem was the specular on the ground. It didn't seem to be reacting properly when the camera and lights moved around.
Bananenfreak wrote: Good work Samuel, as always :D
Thanks, but I didn't do much. I just experimented with an example until it started working.
I'm learning a little each day so hopefully soon I'll be able to post some of my own original shaders.

Re: PerPixel Shader

Posted: Mon Dec 30, 2013 1:56 pm
by applePi
a reflected moon light or a beacon from a rocky road is a romantic scene
Image
it is still working with my cup also
Thanks