A while ago I came up with the idea to make post processing effects like bloom and dof alot easier. I did this by making a bunch of functions that pretty much can take over any post processing effect. I offcourse don't expect you to understand the functions right away so here is the explanation:
scenerendertargetnumber = make_scene_render_target(sizex,sizey)
This function makes a rendertarget wich outputs a image of the current scene. You might wonder why you need more than one of these. Well useally, you don't. If you are only going to make a bloom effect then you don't need it. But if you are going into more complex effects, like dof for example, you will also need a extra scene with (in case of the dof) a distance shader applied to all the objects in the current viewport. The parameters sizex and sizey are the x and y resolution of the output image.
scene_render_to_target(rnt,srccam)
This function places the rendertarget camera at the position and angles of the source camera (srccam) and renders the scene to the output image of the rendertarget (rnt).
rendertargetnumber = make_render_target(img0,img1,img2,img3,img4,sizex,sizey,shd)
Unlike the make_scene_render_target function this doesn't render the scene but applies a shader to the image(s) specified and renders the result to another image. The img0,img1,img2,img3,img4 are the parameters for the input images. You at least have to specify img0. If the other 4 don't exist just specify a 0. Sizex and sizey are the x and y resolution of the output image. shd is the number of the effect that is going to be applied to the image(s).
render_to_target(srccam,rnt,tech$)
Renders the output images of a previously made rendertarget. srccam is the camera at wich the rendertarget camera will be positioned. rnt is the number of the rendertarget. tech$ is the name of a effect technique in the shader.
comp_final(shd,renderscene,img0,img1,img2,img3,img4,tech$)
This function can be considered as a make_render_target and render_to_target in only one function. Unlike render_to_target this function render to the screen and so is the final step in a post processing effect.
I made a example witch shows how to make a bloom effect. You can also see that I have included a shader in quite an unusual way.
`==========================================================================================================================
`Project: Post Processing Functions
`Created: 13-12-2007 17:28:44
`Author: Toz
`==========================================================================================================================
#constant ITR_OBJ_EXCLUSION 100
type scenerendertarget
img as integer `Output image
cam as integer `Camera
endtype
type rendertarget
img as integer `Output image
img0 as integer `Source image (stage 0)
img1 as integer `Source image (stage 1)
img2 as integer `Source image (stage 2)
img3 as integer `Source image (stage 3)
img4 as integer `Source image (stage 4)
obj as integer `Screen quad
cam as integer `Camera
shd as integer `Shader
endtype
`==========================================================================================================================
vsync = 1
global $screenw
global $screenh
load dll "user32.dll",1
$screenw=call dll(1,"GetSystemMetrics",0)
$screenh=call dll(1,"GetSystemMetrics",1)
delete dll 1
set display mode $screenw,$screenh,32,vsync
autocam off : hide mouse
set global collision off
color backdrop 0 : sync on
sync rate 0
numcubes = 50
for i = 1 to numcubes
cube = free_obj() : make object cube cube,64
position object cube,rnd(512)-256,rnd(512)-256,rnd(512)-256
color object cube,rgb(rnd(255),rnd(255),rnd(255))
next i
blurintens# = 0.12
`Set up bloom
shd_pp1 = shader_pp_t1_sm2()
scenernt = make_scene_render_target(256,256)
highprnt = make_render_target(scn_rnt_image(scenernt),0,0,0,0,256,256,shd_pp1)
hblurrnt = make_render_target(rnt_image(highprnt),0,0,0,0,256,256,shd_pp1)
vblurrnt = make_render_target(rnt_image(hblurrnt),0,0,0,0,256,256,shd_pp1)
hblurrnt2 = make_render_target(rnt_image(vblurrnt),0,0,0,0,256,256,shd_pp1)
vblurrnt2 = make_render_target(rnt_image(hblurrnt2),0,0,0,0,256,256,shd_pp1)
`==========================================================================================================================
do
mx# = mousemovex()/4.0
my# = mousemovey()/4.0
if upkey() then : move camera 1
if downkey() then : move camera -1
rotate camera camera angle x()+my#,camera angle y()+mx#,0
scene_render_to_target(scenernt,0)
render_to_target(0,highprnt,"highpass")
render_to_target(0,hblurrnt,"Hblur")
render_to_target(0,vblurrnt,"Vblur")
render_to_target(0,hblurrnt2,"Hblur")
render_to_target(0,vblurrnt2,"Vblur")
if spacekey() = 1
paste image scn_rnt_image(scenernt),0,0
paste image rnt_image(hblurrnt),256,0
paste image rnt_image(vblurrnt),512,0
paste image rnt_image(hblurrnt2),256,256
paste image rnt_image(vblurrnt2),512,256
paste image rnt_image(highprnt),0,256
endif
center text $screenw/2.0,20,"Use the mouse and arrowkeys to move around."
center text $screenw/2.0,40,"Press space bar to view the images."
center text $screenw/2.0,60,"Press s/a to increase/decrease the blur intensity."
center text $screenw/2.0,80,"Blur intensity: "+str$(blurintens#)
center text $screenw/2.0,100,"Frames per second: "+str$(screen fps())
if keystate(30) = 1 then : dec blurintens#,0.001
if keystate(31) = 1 then : inc blurintens#,0.001
set effect constant float shd_pp1,"blurmultiplier",blurintens#
comp_final(shd_pp1,1,rnt_image(vblurrnt2),0,0,0,0,"blend")
loop
`==========================================================================================================================
end
`==========================================================================================================================
function screen_quad(obj,cam)
`The original method for putting a plain exactly in front of the screen was developed by Dark coder
if object exist(obj) = 0
make object plain obj,200.0,200.0
set object light obj,0
pick screen 0,0,100
rtwidth# = get pick vector x()
rtheight# = get pick vector y()
rtdepth# = get pick vector z()
pixelwidth# = get pick vector y()/(screen height()*0.5)
Scale Limb obj , 0 , rtwidth# , rtheight# , 100.0
Offset Limb obj , 0 , -pixelwidth#*0.5 , pixelwidth#*0.5 , rtdepth#
endif
rotate object obj,camera angle x(cam),camera angle y(cam),camera angle z(cam)
position object obj,camera position x(cam),camera position y(cam),camera position z(cam)
endfunction
`==========================================================================================================================
function make_scene_render_target(sizex,sizey)
if 0 = 1
global $numberofscenerendertargets
global $scenerendertargetsmanagercreated
endif
if $scenerendertargetsmanagercreated = 0
dim scenerendertargets_list(0) as scenerendertarget
$scenerendertargetsmanagercreated = 1
endif
array insert at bottom scenerendertargets_list(0),1
inc $numberofscenerendertargets
img = free_img()
cam = free_cam()
scenerendertargets_list($numberofscenerendertargets).img = img
scenerendertargets_list($numberofscenerendertargets).cam = cam
make camera cam
set camera to image cam,img,sizex,sizey
color backdrop cam,0
endfunction $numberofscenerendertargets
`==========================================================================================================================
function scene_render_to_target(rnt,srccam)
exclude_all_off()
if $numberofrendertargets > 0
for i = 1 to $numberofrendertargets
exclu_obj = rendertargets_list(i).obj
exclude object on exclu_obj
next
endif
`Hide the final rendertarget.
if finalrendertarget.obj > 0
exclude object on finalrendertarget.obj
endif
cam = scn_rnt_camera(rnt)
`Put the camera on the place of the source camera.
rotate camera cam,camera angle x(srccam),camera angle y(srccam),camera angle z(srccam)
position camera cam,camera position x(srccam),camera position y(srccam),camera position z(srccam)
sync mask 2^cam
fastsync
endfunction
`==========================================================================================================================
function make_render_target(img0,img1,img2,img3,img4,sizex,sizey,shd)
`You see five img parameters, they represent the textures that need
`to be post-proccesed. The number behind img is the stage-index.
`Just specify a 0 if they don't exist. You will always have to
`specify img0 though. Note that img is the output image.
if 0 = 1
global $numberofrendertargets
global $rendertargetsmanagercreated
endif
if $rendertargetsmanagercreated = 0
dim rendertargets_list(0) as rendertarget
$rendertargetsmanagercreated = 1
endif
array insert at bottom rendertargets_list(0),1
inc $numberofrendertargets
cam = free_cam()
obj = free_obj()
img = free_img()
rendertargets_list($numberofrendertargets).img = img
rendertargets_list($numberofrendertargets).cam = cam
rendertargets_list($numberofrendertargets).obj = obj
rendertargets_list($numberofrendertargets).shd = shd
rendertargets_list($numberofrendertargets).img0 = img0
rendertargets_list($numberofrendertargets).img1 = img1
rendertargets_list($numberofrendertargets).img2 = img2
rendertargets_list($numberofrendertargets).img3 = img3
rendertargets_list($numberofrendertargets).img4 = img4
make camera cam
set camera to image cam,img,sizex,sizey
screen_quad(obj,0)
texture object obj,0,img0
if img1 > 0 then : texture object obj,1,img1
if img2 > 0 then : texture object obj,2,img2
if img3 > 0 then : texture object obj,3,img3
if img4 > 0 then : texture object obj,4,img4
set object effect rendertargets_list($numberofrendertargets).obj,shd
endfunction $numberofrendertargets
`==========================================================================================================================
function render_to_target(srccam,rnt,tech$) `srccam is meestal 0
`The scene will never have to be rendered while a image is
`post processed.
exclude_all_on()
cam = rendertargets_list(rnt).cam
obj = rendertargets_list(rnt).obj
shd = rendertargets_list(rnt).shd
`Put the camera on the place of the source camera.
rotate camera cam,camera angle x(srccam),camera angle y(srccam),camera angle z(srccam)
position camera cam,camera position x(srccam),camera position y(srccam),camera position z(srccam)
`Put the plain infront of the camera.
screen_quad(obj,srccam)
`Make the plain visible.
exclude object off obj
set effect technique shd,tech$
sync mask 2^cam
fastsync
endfunction
`==========================================================================================================================
function comp_final(shd,renderscene,img0,img1,img2,img3,img4,tech$)
if 0 = 1
global $finalrendertargetcreated
endif
if $finalrendertargetcreated = 0
global finalrendertarget as rendertarget
finalrendertarget.img = 0 `No output image (output is to the screen)
finalrendertarget.cam = 0 `See above
finalrendertarget.obj = free_obj() : screen_quad(finalrendertarget.obj,0)
finalrendertarget.shd = shd
finalrendertarget.img0 = img0
finalrendertarget.img1 = img1
finalrendertarget.img2 = img2
finalrendertarget.img3 = img3
finalrendertarget.img4 = img4
set object effect finalrendertarget.obj,shd
texture object finalrendertarget.obj,0,img0
if img1 > 0 then : texture object finalrendertarget.obj,1,img1
if img2 > 0 then : texture object finalrendertarget.obj,2,img2
if img3 > 0 then : texture object finalrendertarget.obj,3,img3
if img4 > 0 then : texture object finalrendertarget.obj,4,img4
$finalrendertargetcreated = 1
endif
`--------------------------------------------------------------------------------------------------------------------------
if renderscene = 0
exclude_all_on()
else
exclude_all_off()
if $numberofrendertargets > 0
for i = 1 to $numberofrendertargets
exclu_obj = rendertargets_list(i).obj
exclude object on exclu_obj
next
endif
endif
`Put the plain infront of the camera.
screen_quad(finalrendertarget.obj,0)
`Make the plain visible.
exclude object off finalrendertarget.obj
set effect technique shd,tech$
`Update to screen.
sync mask 2^0
fastsync
endfunction
`==========================================================================================================================
function scn_rnt_image(rnt)
img = scenerendertargets_list(rnt).img
endfunction img
`==========================================================================================================================
function scn_rnt_camera(rnt)
cam = scenerendertargets_list(rnt).cam
endfunction cam
`==========================================================================================================================
function rnt_object(rnt)
obj = rendertargets_list(rnt).obj
endfunction obj
`==========================================================================================================================
function rnt_image(rnt)
img = rendertargets_list(rnt).img
endfunction img
`==========================================================================================================================
function rnt_camera(rnt)
cam = rendertargets_list(rnt).cam
endfunction cam
`==========================================================================================================================
function exclude_all_on()
for i = 1 to ITR_OBJ_EXCLUSION
if object exist(i) = 1
exclude object on i
endif
next i
endfunction
`==========================================================================================================================
function exclude_all_off()
for i = 1 to ITR_OBJ_EXCLUSION
if object exist(i) = 1
exclude object off i
endif
next i
endfunction
`==========================================================================================================================
function free_obj()
inc num
while object exist(num) = 1
inc num
endwhile
endfunction num
`==========================================================================================================================
function free_img()
inc num
while image exist(num) = 1
inc num
endwhile
endfunction num
`==========================================================================================================================
function free_cam()
inc num
while camera exist(num) = 1
inc num
endwhile
endfunction num
`==========================================================================================================================
function free_shd()
inc num
while effect exist(num) = 1
inc num
endwhile
endfunction num
`==========================================================================================================================
function free_file()
if 0 = 1
global $files
endif
inc $files
endfunction $files
`==========================================================================================================================
function shader_pp_t1_sm2()
filenum = free_file()
shadnum = free_shd()
open to write filenum,"pp_t1_sm2.fx"
write string filenum,""
write string filenum,""
write string filenum,"//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
write string filenum,"//"
write string filenum,"// Post processing effects for shader model 2.0."
write string filenum,"// By Toz."
write string filenum,"//"
write string filenum,"// The idea to make seperate blur effects for the"
write string filenum,"// horizontal and vertical blur direction was "
write string filenum,"// originaly developed by evolved"
write string filenum,"//"
write string filenum,"//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
write string filenum,""
write string filenum,""
write string filenum,"//Variables========================================================= "
write string filenum,"matrix wvp : WorldViewProjection; "
write string filenum,"float time : time;"
write string filenum,""
write string filenum,"float texinvsize = 0.008f;"
write string filenum,"float blurmultiplier = 0.12f;"
write string filenum,"float contrast = 1.0f;"
write string filenum,"float sharpen = 1.0f;"
write string filenum,""
write string filenum,"//Structs==========================================================="
write string filenum,""
write string filenum,"struct input"
write string filenum,"{"
write string filenum," "
write string filenum," float4 Ipos : POSITION;"
write string filenum," float2 Iuv : TEXCOORD;"
write string filenum,""
write string filenum,"};"
write string filenum,""
write string filenum,"struct output"
write string filenum,"{"
write string filenum,""
write string filenum," float4 Opos : POSITION;"
write string filenum," float2 Ouv : TEXCOORD0;"
write string filenum,""
write string filenum,"};"
write string filenum,""
write string filenum,"//Textures=========================================================="
write string filenum,""
write string filenum,"texture sourcemap"
write string filenum,"< string Name="base.jpg"; >;"
write string filenum,"sampler2D source = sampler_state "
write string filenum,"{"
write string filenum,""
write string filenum," Texture = <sourcemap>; "
write string filenum," MipFilter = linear;"
write string filenum," MinFilter = linear;"
write string filenum," MagFilter = linear;"
write string filenum," Addressu= clamp;"
write string filenum," Addressv= clamp;"
write string filenum," Addressw= clamp;"
write string filenum,""
write string filenum,"};"
write string filenum,""
write string filenum,"//Vertex shader====================================================="
write string filenum,""
write string filenum,"output quad_VS(input IN)"
write string filenum,"{"
write string filenum,""
write string filenum," output Out;"
write string filenum,""
write string filenum," Out.Opos = mul(IN.Ipos,wvp);"
write string filenum," Out.Ouv = IN.Iuv;"
write string filenum,""
write string filenum," return Out;"
write string filenum,""
write string filenum,"}"
write string filenum,""
write string filenum,"//Pixel shaders====================================================="
write string filenum,""
write string filenum,"float4 highpass_PS(output IN) : COLOR"
write string filenum,"{"
write string filenum,""
write string filenum," float3 color = tex2D(source,IN.Ouv);"
write string filenum," float val = max(max(color.r,color.g),color.b);"
write string filenum,""
write string filenum," return float4(color*pow(val,10),1);"
write string filenum," "
write string filenum,"}"
write string filenum,""
write string filenum,"//------------------------------------------------------------------"
write string filenum,""
write string filenum,"float4 invert_PS(output IN) : COLOR"
write string filenum,"{"
write string filenum,""
write string filenum," float4 color = tex2D(source,IN.Ouv);"
write string filenum,""
write string filenum," return (1.0-color);"
write string filenum," "
write string filenum,"}"
write string filenum,""
write string filenum,"//------------------------------------------------------------------"
write string filenum,""
write string filenum,"float4 psycho_PS(output IN) : COLOR"
write string filenum,"{"
write string filenum,""
write string filenum," float4 psych;"
write string filenum," float4 color = tex2D(source,IN.Ouv);"
write string filenum," "
write string filenum," psych.r = sin((time*color.r)); "
write string filenum," psych.g = sin((time*color.g)); "
write string filenum," psych.b = sin((time*color.b)); "
write string filenum," psych.a = 1.0;"
write string filenum,""
write string filenum," return psych;"
write string filenum," "
write string filenum,"}"
write string filenum,""
write string filenum,"//------------------------------------------------------------------"
write string filenum,""
write string filenum,"float4 sharpen_PS(output IN) : COLOR"
write string filenum,"{"
write string filenum,""
write string filenum," float4 color = tex2D(source,IN.Ouv);"
write string filenum,""
write string filenum," float4 difx = color-tex2D(source,IN.Ouv+float2(texinvsize,0));"
write string filenum," float4 dify = color-tex2D(source,IN.Ouv+float2(0,texinvsize));"
write string filenum,""
write string filenum," color += sharpen*difx;"
write string filenum," color += sharpen*dify;"
write string filenum,""
write string filenum," return color; "
write string filenum,""
write string filenum,"}"
write string filenum,""
write string filenum,"//------------------------------------------------------------------"
write string filenum,""
write string filenum,"float4 contrast_PS(output IN) : COLOR"
write string filenum,"{"
write string filenum,""
write string filenum," float4 color = tex2D(source,IN.Ouv);"
write string filenum," color += contrast*(color-0.5);"
write string filenum,""
write string filenum," return color;"
write string filenum," "
write string filenum,"}"
write string filenum,""
write string filenum,"//------------------------------------------------------------------"
write string filenum,""
write string filenum,"float4 Hblur_PS(output IN) : COLOR"
write string filenum,"{"
write string filenum,""
write string filenum," float3 color = float3(0,0,0);"
write string filenum,""
write string filenum," for( int ittr = 0; ittr < 5; ittr++ )"
write string filenum," {"
write string filenum,""
write string filenum," color += tex2D(source,IN.Ouv+(float2(texinvsize,0.0)*ittr));"
write string filenum," color += tex2D(source,IN.Ouv-(float2(texinvsize,0.0)*ittr));"
write string filenum,""
write string filenum," }"
write string filenum,""
write string filenum," return float4(color*blurmultiplier,1.0); "
write string filenum,""
write string filenum,"}"
write string filenum,""
write string filenum,"//------------------------------------------------------------------"
write string filenum,""
write string filenum,"float4 Vblur_PS(output IN) : COLOR"
write string filenum,"{"
write string filenum,""
write string filenum," float3 color = float3(0,0,0);"
write string filenum,""
write string filenum," for( int ittr = 0; ittr < 5; ittr++ )"
write string filenum," {"
write string filenum,""
write string filenum," color += tex2D(source,IN.Ouv+(float2(0.0,texinvsize)*ittr));"
write string filenum," color += tex2D(source,IN.Ouv-(float2(0.0,texinvsize)*ittr));"
write string filenum,""
write string filenum," }"
write string filenum,""
write string filenum," return float4(color*blurmultiplier,1.0); "
write string filenum,""
write string filenum,"}"
write string filenum,""
write string filenum,"//------------------------------------------------------------------"
write string filenum,""
write string filenum,"float4 blend_PS(output IN) : COLOR"
write string filenum,"{"
write string filenum,""
write string filenum," float4 color = tex2D(source,IN.Ouv);"
write string filenum," return color;"
write string filenum," "
write string filenum,"}"
write string filenum,""
write string filenum,"//Techniques========================================================"
write string filenum,""
write string filenum,"technique highpass"
write string filenum,"{"
write string filenum," pass p0"
write string filenum," { "
write string filenum," VertexShader = compile vs_2_0 quad_VS();"
write string filenum," PixelShader = compile ps_2_0 highpass_PS(); "
write string filenum," }"
write string filenum,"}"
write string filenum,""
write string filenum,"technique invert"
write string filenum,"{"
write string filenum," pass p0"
write string filenum," { "
write string filenum," VertexShader = compile vs_2_0 quad_VS();"
write string filenum," PixelShader = compile ps_2_0 invert_PS(); "
write string filenum," }"
write string filenum,"}"
write string filenum,""
write string filenum,"technique psycho"
write string filenum,"{"
write string filenum," pass p0"
write string filenum," { "
write string filenum," VertexShader = compile vs_2_0 quad_VS();"
write string filenum," PixelShader = compile ps_2_0 psycho_PS(); "
write string filenum," }"
write string filenum,"}"
write string filenum,""
write string filenum,"technique sharpen"
write string filenum,"{"
write string filenum," pass p0"
write string filenum," { "
write string filenum," VertexShader = compile vs_2_0 quad_VS();"
write string filenum," PixelShader = compile ps_2_0 sharpen_PS(); "
write string filenum," }"
write string filenum,"}"
write string filenum,""
write string filenum,"technique contrast"
write string filenum,"{"
write string filenum," pass p0"
write string filenum," { "
write string filenum," VertexShader = compile vs_2_0 quad_VS();"
write string filenum," PixelShader = compile ps_2_0 contrast_PS(); "
write string filenum," }"
write string filenum,"}"
write string filenum,""
write string filenum,"technique Hblur"
write string filenum,"{"
write string filenum," pass p0"
write string filenum," { "
write string filenum," VertexShader = compile vs_2_0 quad_VS();"
write string filenum," PixelShader = compile ps_2_0 Hblur_PS(); "
write string filenum," }"
write string filenum,"}"
write string filenum,""
write string filenum,"technique Vblur"
write string filenum,"{"
write string filenum," pass p0"
write string filenum," { "
write string filenum," VertexShader = compile vs_2_0 quad_VS();"
write string filenum," PixelShader = compile ps_2_0 Vblur_PS(); "
write string filenum," }"
write string filenum,"}"
write string filenum,""
write string filenum,"technique blend"
write string filenum,"{"
write string filenum," pass p0"
write string filenum," { "
write string filenum," VertexShader = compile vs_2_0 quad_VS();"
write string filenum," PixelShader = compile ps_2_0 blend_PS(); "
write string filenum," alphablendenable = true;"
write string filenum," zwriteenable = false;"
write string filenum," srcblend = One;"
write string filenum," destblend = One;"
write string filenum," }"
write string filenum,"}"
write string filenum,""
close file filenum
load effect "pp_t1_sm2.fx",shadnum,0
delete file "pp_t1_sm2.fx"
endfunction shadnum
`==========================================================================================================================
Anyway I hope you guys find it most usefull. Have fun!
Don't read this, read the above.