For now here's the Fresnel shader.
When I've implemented it into the toon shader I'll PM it to you, Alexi.
First, here's a little sample picture for those who want to see the effect.
At the moment the Fresnel is set to white, but you can change it to whatever you like just by editing the variables in the material script.
For those of you who just want to jump right into it here's a download link.
Fresnel Shader
I'll post the code too. Since the download link will eventually die.
If someone down the line needs the download version let me know and I'll re upload it for you.
For those of you who are new to cg shaders. You need to download
Nvidia's cg toolkit.
Here you go.
https://developer.nvidia.com/cg-toolkit-download
The downloads at the bottom of their page.
You'll also need to include the
cg.dll (with your app) if you intend to release it to others.
I guess I could have just included the
cg.dll with my demo download above. Then you wouldn't need to download it........
I'll try to remember to include it next time I create a shader demo.
EDIT:
I re uploaded the download with the required cg.dll. So, the shader should run even if you haven't downloaded
Nvidia's cg toolkit.
OK, let's get into the code.
You can save them in pretty much any text editor.
First the material script.
fresnel.material
Code: Select all
//Lines like this one are commented out.
abstract material FresnelTemplate
{
technique
{
pass
{
ambient $ambient
diffuse $diffuse
//#### Comment out these next five lines to exclude textures. ####
texture_unit
{
texture $Texture
filtering linear linear linear
}
//#### ####
}
pass
{
scene_blend add
depth_check on
lighting on
vertex_program_ref fresnel_vs
{
}
fragment_program_ref fresnel_ps
{
param_named GlowColor float3 $GlowColor
param_named GlowExpon float $GlowExpon
param_named Alpha float $Alpha
}
}
}
}
material FresnelWhite : FresnelTemplate
{
set $ambient "1.0 1.0 1.0" //#### Ambient Color. 1.0 equals 255 compared to RGB format. ####
set $diffuse "1.0 1.0 1.0" //#### Diffuse Color. 1.0 equals 255 compared to RGB format. ####
set $GlowColor "1.0 1.0 1.0"//#### Glow Color. 1.0 equals 255 compared to RGB format. ####
set $GlowExpon 3.0 //#### The smaller the exponent the thicker the effect. ####
set $Alpha 0.8 //#### Value can be greater then 1, but around 10 it starts to engulf your entities. ####
set $Texture grass.jpg //#### Alexi, Comment out this line with the texture unit above to disable textures. ####
}
Now the program file.
fresnel.program
Code: Select all
vertex_program fresnel_vs cg {
source fresnel.cg
entry_point main_vs
profiles vs_2_0 arbvp1 vs_2_x vs_3_0 vp40
default_params {
// Leave these
param_named_auto WorldITXf inverse_transpose_world_matrix
param_named_auto WorldXf world_matrix
param_named_auto ViewIXf inverse_view_matrix
param_named_auto WvpXf worldviewproj_matrix
}
}
fragment_program fresnel_ps cg {
source fresnel.cg
entry_point main_ps
profiles ps_2_0 arbfp1 ps_2_x ps_3_0 ps_3_x fp40
default_params {
//These are default values. No need to change them.
// Default is white (rgb)
param_named GlowColor float3 1.0 1.0 1.0
// Bigger exponent, thinner edges
param_named GlowExpon float 2.5
// Set transparency of the fresnel
param_named Alpha float 1.0
}
}
Here's the shader itself.
fresnel.cg
Code: Select all
void main_vs(float4 Position : POSITION,
float4 Normal : NORMAL,
out float4 HPosition : POSITION,
out float3 WorldNormal : TEXCOORD0,
out float3 WorldView : TEXCOORD1,
uniform float4x4 WorldITXf, // our four standard "untweakable" xforms
uniform float4x4 WorldXf,
uniform float4x4 ViewIXf,
uniform float4x4 WvpXf
) {
WorldNormal = mul(WorldITXf, Normal).xyz;
float4 Po = Position;
// This just inflates it a tiny bit so we don't get depth fighting
Po.xyz += 0.01 * Normal;
float4 Pw = mul(WorldXf, Po);
WorldView = normalize(float3(ViewIXf[0].w, ViewIXf[1].w, ViewIXf[2].w) - Pw.xyz);
HPosition = mul(WvpXf, Po);
}
float4 main_ps(float3 WorldNormal : TEXCOORD0,
float3 WorldView : TEXCOORD1,
uniform float3 GlowColor,
uniform float GlowExpon,
uniform float Alpha
) : COLOR
{
float3 Nn = normalize(WorldNormal);
float3 Vn = normalize(WorldView);
float edge = 1.0 - dot(Nn, Vn);
edge = pow(edge, GlowExpon) * Alpha;
float3 result = edge * GlowColor.rgb;
return float4(result, edge);
}
And last, but not least is the Purebasic code.
You'll need to set the archive to the files you previously saved.
Code: Select all
If InitEngine3D(#PB_Engine3D_EnableCG | #PB_Engine3D_DebugLog)
Else
End
EndIf
InitSprite()
InitKeyboard()
InitMouse()
Enumeration
#FPS
EndEnumeration
ExamineDesktops()
screenWidth = DesktopWidth(0)
screenHeight = DesktopHeight(0)
If LoadFont(0, "", 10,#PB_Font_Bold)
SetGadgetFont(#PB_Default, FontID(0))
EndIf
If OpenWindow(0, 0, 0, screenWidth, screenHeight, "Fresnel Effect")
AntialiasingMode(#PB_AntialiasingMode_x6)
If OpenWindowedScreen(WindowID(0), 0, 0, screenWidth, screenHeight, 0, 0, 0)
;#### Set this path to the previously saved shader files ####
Add3DArchive("\", #PB_3DArchive_FileSystem)
;#### ####
Add3DArchive(#PB_Compiler_Home+"\Examples\3D\Data\Packs\Sinbad.zip",#PB_3DArchive_Zip)
Add3DArchive(#PB_Compiler_Home+"\Examples\3D\Data\Textures",#PB_3DArchive_FileSystem)
Parse3DScripts()
CPU$ = CPUName()
CreateSprite(#FPS, 280, 210)
StartDrawing(SpriteOutput(#FPS))
Box(0,0,280,120,RGB(0,0,0))
StopDrawing()
LoadMesh(0,"Sinbad.mesh")
LoadTexture(0,"ground_diffuse.png")
CreateMaterial(1,TextureID(0))
;#### Load Shader Material ####
GetScriptMaterial(0,"FresnelWhite")
CreateNode(1,0,0,0)
CreatePlane(4,60,60,1,1,10,10)
CreateEntity(0, MeshID(0),MaterialID(0),0,5,0)
CreateEntity(4,MeshID(4),MaterialID(1),0,0,0)
CreateCamera(0, 0,0,100,100)
MoveCamera(0, 0, 5, 20)
CameraLookAt(0, 0, 5, 0)
CameraBackColor(0, RGB(10, 10, 10))
AttachNodeObject(1,CameraID(0))
CreateLight(0, RGB(0,0,0), -5,10,4)
SetLightColor(0, #PB_Light_DiffuseColor, RGB(200,100,0))
SetLightColor(0, #PB_Light_SpecularColor, RGB(255,155,255))
StartEntityAnimation(0, "IdleTop", #PB_EntityAnimation_Manual)
StartEntityAnimation(0, "IdleBase", #PB_EntityAnimation_Manual)
Repeat
If ExamineKeyboard()
If KeyboardPushed(#PB_Key_Up)
MoveCamera(0, 0, 0, -0.2)
ElseIf KeyboardPushed(#PB_Key_Down)
MoveCamera(0, 0, 0, 0.2)
EndIf
If KeyboardPushed(#PB_Key_Left)
RotateNode(1,0,-1,0,#PB_Relative)
CameraLookAt(0, 0, 5, 0)
ElseIf KeyboardPushed(#PB_Key_Right)
RotateNode(1,0,1,0,#PB_Relative)
CameraLookAt(0, 0, 5, 0)
EndIf
If KeyboardReleased(#PB_Key_W)
CameraRenderMode(0, #PB_Camera_Wireframe)
ElseIf KeyboardReleased(#PB_Key_E)
CameraRenderMode(0, #PB_Camera_Textured)
EndIf
EndIf
AddEntityAnimationTime(0, "IdleTop", LastFrame * 2)
AddEntityAnimationTime(0, "IdleBase", LastFrame * 2)
LastFrame=RenderWorld()
ShowFPS=1
If ShowFPS=1
CurrentFPS = Engine3DFrameRate(#PB_Engine3D_Current)
AverageFPS = Engine3DFrameRate(#PB_Engine3D_Average)
MaximumFPS = Engine3DFrameRate(#PB_Engine3D_Maximum)
MinimumFPS = Engine3DFrameRate(#PB_Engine3D_Minimum)
CountTris=CountRenderedTriangles()
StartDrawing(SpriteOutput(#FPS))
Box(0,0,280,120,RGB(40,40,40))
DrawingFont(FontID(0))
DrawText(2,2,CPU$,RGB(255,0,0),RGB(40,40,40))
DrawText(2,22,"Current FPS : "+Str(CurrentFPS),RGB(0,255,255),RGB(40,40,40))
DrawText(2,42,"Average FPS : "+Str(AverageFPS),RGB(0,255,255),RGB(40,40,40))
DrawText(2,62,"Maximum FPS : "+Str(MaximumFPS),RGB(0,255,255),RGB(40,40,40))
DrawText(2,82,"Minimum FPS : "+Str(MinimumFPS),RGB(0,255,255),RGB(40,40,40))
DrawText(2,102,"Rendered Triangles : "+Str(CountTris),RGB(0,255,0),RGB(40,40,40))
StopDrawing()
DisplayTransparentSprite(#FPS,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 about all there is. If you have any questions or are having trouble let me know and I'll try to help.
Also, if anyone spots any errors let me know and I'll try to fix them.
Good luck.
