Hi, I have tested yours code. it's nice effect.
@Robloch: I use the 0.1.4 source of dof but I don't see cg script but GLSL and HLSL.
I give you cg script which I made from the HLSL file (for me the HLSL file of Dof doesn't work ( I'm in directX9, nvidia Geforce 8800 GT with the driver of NVPerfHUD ) ):
error on HLSL:
Code: Select all
10:38:09: OGRE EXCEPTION(3:RenderingAPIException): Cannot assemble D3D9 high-level shader DoF_Gaussian3x3FP_HLSL Errors:
c:\Developpement\Dev\Ogre\ogre-v1-6-SVN-maintenance_090827\ogre\Samples\Common\bin\Debug\memory(17,14): error X3025: global variables are implicitly constant, enable compatibility mode to allow modification
in D3D9HLSLProgram::loadFromSource at c:\developpement\dev\ogre\ogre-v1-6-svn-maintenance_090827\ogre\rendersystems\direct3d9\src\ogred3d9hlslprogram.cpp (line 199)
10:38:09: High-level program DoF_Gaussian3x3FP_HLSL encountered an error during loading and is thus not supported.
OGRE EXCEPTION(3:RenderingAPIException): Cannot assemble D3D9 high-level shader DoF_Gaussian3x3FP_HLSL Errors:
c:\Developpement\Dev\Ogre\ogre-v1-6-SVN-maintenance_090827\ogre\Samples\Common\bin\Debug\memory(17,14): error X3025: global variables are implicitly constant, enable compatibility mode to allow modification
in D3D9HLSLProgram::loadFromSource at c:\developpement\dev\ogre\ogre-v1-6-svn-maintenance_090827\ogre\rendersystems\direct3d9\src\ogred3d9hlslprogram.cpp (line 199)
10:38:09: OGRE EXCEPTION(3:RenderingAPIException): Cannot assemble D3D9 high-level shader DoF_DepthOfFieldFP_HLSL Errors:
c:\Developpement\Dev\Ogre\ogre-v1-6-SVN-maintenance_090827\ogre\Samples\Common\bin\Debug\memory(24,15): error X3025: global variables are implicitly constant, enable compatibility mode to allow modification
in D3D9HLSLProgram::loadFromSource at c:\developpement\dev\ogre\ogre-v1-6-svn-maintenance_090827\ogre\rendersystems\direct3d9\src\ogred3d9hlslprogram.cpp (line 199)
10:38:09: High-level program DoF_DepthOfFieldFP_HLSL encountered an error during loading and is thus not supported.
OGRE EXCEPTION(3:RenderingAPIException): Cannot assemble D3D9 high-level shader DoF_DepthOfFieldFP_HLSL Errors:
c:\Developpement\Dev\Ogre\ogre-v1-6-SVN-maintenance_090827\ogre\Samples\Common\bin\Debug\memory(24,15): error X3025: global variables are implicitly constant, enable compatibility mode to allow modification
in D3D9HLSLProgram::loadFromSource at c:\developpement\dev\ogre\ogre-v1-6-svn-maintenance_090827\ogre\rendersystems\direct3d9\src\ogred3d9hlslprogram.cpp (line 199)
try this, unless I didn't take the lastest source:
Dof.cg:
Code: Select all
void DoF_DepthVP_cg( float4 worldPos : POSITION,
out float4 viewPos : POSITION,
out float4 viewPos2 : TEXCOORD0,
out float depth : TEXCOORD1,
uniform float4x4 worldViewProj
)
{
viewPos = mul(worldViewProj, worldPos);
viewPos2 = viewPos;
depth = viewPos.z;
}
void DoF_DepthFP_cg( float4 viewPos : TEXCOORD0,
float depth : TEXCOORD1,
out float4 color : COLOR,
uniform float4 dofParams // dofParams coefficients: x = near blur depth; y = focal plane depth; z = far blur depth, w = blurriness cutoff constant for objects behind the focal plane
)
{
float f;
if(depth<dofParams.y)
{
f = (depth - dofParams.y) / (dofParams.y - dofParams.x); // scale depth value between near blur distance and focal distance to [-1, 0] range
}else{
f = (depth - dofParams.y) / (dofParams.z - dofParams.y); // scale depth value between focal distance and far blur distance to [0, 1] range
f = clamp(f, 0.0, dofParams.w); // clamp the far blur to a maximum blurriness
}
f = 0.5f*f + 0.5f; // scale and bias into [0, 1] range
color = float4(f,f,f,1);
}
/*******************************************************************************/
void DoF_Gaussian3x3VP_cg( float4 worldPos : POSITION,
float2 textCoordi : TEXCOORD0,
out float4 viewPos : POSITION,
out float2 textCoordo : TEXCOORD0,
uniform float4x4 worldViewProj
)
{
viewPos = mul(worldViewProj, worldPos);
textCoordo = textCoordi;
}
void DoF_Gaussian3x3FP_cg( float2 tex : TEXCOORD0,
out float4 color : COLOR,
uniform sampler2D source : register(s0),
uniform float3 pixelSize
)
{
#define KERNEL_SIZE 9
float weights[KERNEL_SIZE];
float2 offsets[KERNEL_SIZE];
weights[0] = 1.0/16.0; weights[1] = 2.0/16.0; weights[2] = 1.0/16.0;
weights[3] = 2.0/16.0; weights[4] = 4.0/16.0; weights[5] = 2.0/16.0;
weights[6] = 1.0/16.0; weights[7] = 2.0/16.0; weights[8] = 1.0/16.0;
offsets[0] = float2(-pixelSize.x, -pixelSize.y);
offsets[1] = float2(0, -pixelSize.y);
offsets[2] = float2(pixelSize.x, -pixelSize.y);
offsets[3] = float2(-pixelSize.x, 0);
offsets[4] = float2(0, 0);
offsets[5] = float2(pixelSize.x, 0);
offsets[6] = float2(-pixelSize.x, pixelSize.y);
offsets[7] = float2(0, pixelSize.y);
offsets[8] = float2(pixelSize.x, pixelSize.y);
color = float4(0,0,0,0);
for (int i = 0; i < KERNEL_SIZE; ++i)
color += weights[i] * tex2D(source, tex + offsets[i]);
}
/*******************************************************************************/
void DoF_DepthOfFieldVP_cg( float4 worldPos : POSITION,
float2 textCoordi : TEXCOORD0,
out float4 viewPos : POSITION,
out float2 textCoordo : TEXCOORD0,
uniform float4x4 worldViewProj
)
{
viewPos = mul(worldViewProj, worldPos);
textCoordo = textCoordi;
}
void DoF_DepthOfFieldFP_cg( float2 tex : TEXCOORD0,
out float4 color : COLOR,
uniform sampler2D scene : register(s0), // full resolution image
uniform sampler2D depth : register(s1), // full resolution image with depth values
uniform sampler2D blur : register(s2), // downsampled and blurred image
uniform float3 pixelSizeScene, // pixel size of full resolution image
uniform float3 pixelSizeBlur // pixel size of downsampled and blurred image
)
{
#define NUM_TAPS 12 // number of taps the shader will use
float2 poisson[NUM_TAPS]; // containts poisson-distributed positions on the unit circle
float2 maxCoC; // maximum circle of confusion (CoC) radius and diameter in pixels
float radiusScale; // scale factor for minimum CoC size on low res. image
poisson[ 0] = float2( 0.00, 0.00);
poisson[ 1] = float2( 0.07, -0.45);
poisson[ 2] = float2(-0.15, -0.33);
poisson[ 3] = float2( 0.35, -0.32);
poisson[ 4] = float2(-0.39, -0.26);
poisson[ 5] = float2( 0.10, -0.23);
poisson[ 6] = float2( 0.36, -0.12);
poisson[ 7] = float2(-0.31, -0.01);
poisson[ 8] = float2(-0.38, 0.22);
poisson[ 9] = float2( 0.36, 0.23);
poisson[10] = float2(-0.13, 0.29);
poisson[11] = float2( 0.14, 0.41);
maxCoC = float2(5.0, 10.0);
radiusScale = 0.4;
// Get depth of center tap and convert it into blur radius in pixels
float centerDepth = tex2D(depth, tex).r;
float discRadiusScene = abs(centerDepth * maxCoC.y - maxCoC.x);
float discRadiusBlur = discRadiusScene * radiusScale; // radius on low res. image
float4 sum = float4(0.0,0.0,0.0,0.0);
for (int i = 0; i < NUM_TAPS; ++i)
{
// compute texture coordinates
float2 coordScene = tex + (pixelSizeScene.xy * poisson[i] * discRadiusScene);
float2 coordBlur = tex + (pixelSizeBlur.xy * poisson[i] * discRadiusBlur);
// fetch taps and depth
float4 tapScene = tex2D(scene, coordScene);
float tapDepth = tex2D(depth, coordScene).r;
float4 tapBlur = tex2D(blur, coordBlur);
// mix low and high res. taps based on tap blurriness
float blurAmount = abs(tapDepth * 2.0 - 1.0); // put blurriness into [0, 1]
float4 tap = lerp(tapScene, tapBlur, blurAmount);
// "smart" blur ignores taps that are closer than the center tap and in focus
float factor = (tapDepth >= centerDepth) ? 1.0 : abs(tapDepth * 2.0 - 1.0);
// accumulate
sum.rgb += tap.rgb * factor;
sum.a += factor;
}
color = (sum / sum.a);
}
I modified the Dof.material ( sorry for declarations of shader in Dof.material instead of Dof.program ):
Code: Select all
// "Depth of Field" demo for Ogre
// Copyright (C) 2006 Christian Lindequist Larsen
//
// This code is in the public domain. You may do whatever you want with it.
vertex_program DoF_DepthVP_cg cg
{
source DoF.cg
entry_point DoF_DepthVP_cg
profiles vs_3_0
default_params
{
param_named_auto worldViewProj worldviewproj_matrix
}
}
fragment_program DoF_DepthFP_cg cg
{
source DoF.cg
entry_point DoF_DepthFP_cg
profiles ps_3_0
}
/////////////////////////////////////////////////////////////////////
vertex_program DoF_Gaussian3x3VP_cg cg
{
source DoF.cg
entry_point DoF_Gaussian3x3VP_cg
profiles vs_3_0
default_params
{
param_named_auto worldViewProj worldviewproj_matrix
}
}
fragment_program DoF_Gaussian3x3FP_cg cg
{
source DoF.cg
entry_point DoF_Gaussian3x3FP_cg
profiles ps_3_0
}
/////////////////////////////////////////////////////////////////////
vertex_program DoF_DepthOfFieldVP_cg cg
{
source DoF.cg
entry_point DoF_DepthOfFieldVP_cg
profiles vs_3_0
default_params
{
param_named_auto worldViewProj worldviewproj_matrix
}
}
fragment_program DoF_DepthOfFieldFP_cg cg
{
source DoF.cg
entry_point DoF_DepthOfFieldFP_cg
profiles ps_3_0
}
/*********************************************************************************/
material DoF_Depth
{
technique cg
{
pass
{
vertex_program_ref DoF_DepthVP_cg
{
}
fragment_program_ref DoF_DepthFP_cg
{
//trouver de bonnes valeurs // dofParams coefficients: x = near blur depth; y = focal plane depth; z = far blur depth, w = blurriness cutoff constant for objects behind the focal plane
param_named dofParams float4 0.3 0.3 0.3 0.3
}
}
}
technique GLSL
{
pass
{
vertex_program_ref DoF_DepthVP_GLSL
{
}
fragment_program_ref DoF_DepthFP_GLSL
{
}
}
}
technique HLSL
{
pass
{
vertex_program_ref DoF_DepthVP_HLSL
{
}
fragment_program_ref DoF_DepthFP_HLSL
{
}
}
}
}
/////////////////////////////////////////////////////////////////////
material DoF_Gaussian3x3
{
technique cg
{
pass
{
vertex_program_ref DoF_Gaussian3x3VP_cg
{
}
fragment_program_ref DoF_Gaussian3x3FP_cg
{
param_named pixelSize float3 0.03 0.03 0.03
}
texture_unit source
{
tex_address_mode clamp
}
}
}
technique GLSL
{
pass
{
fragment_program_ref DoF_Gaussian3x3FP_GLSL
{
}
texture_unit source
{
tex_address_mode clamp
}
}
}
technique HLSL
{
pass
{
fragment_program_ref DoF_Gaussian3x3FP_HLSL
{
}
texture_unit source
{
tex_address_mode clamp
}
}
}
}
/////////////////////////////////////////////////////////////////////
material DoF_DepthOfField
{
technique cg
{
pass
{
vertex_program_ref DoF_DepthOfFieldVP_cg
{
}
fragment_program_ref DoF_DepthOfFieldFP_cg
{
param_named pixelSizeScene float3 0.03 0.03 0.03
param_named pixelSizeBlur float3 0.03 0.03 0.03
}
texture_unit scene
{
tex_address_mode clamp
}
texture_unit depth
{
tex_address_mode clamp
texture DoF_Depth
}
texture_unit blur
{
tex_address_mode clamp
}
}
}
technique GLSL
{
pass
{
fragment_program_ref DoF_DepthOfFieldFP_GLSL
{
}
texture_unit scene
{
tex_address_mode clamp
}
texture_unit depth
{
tex_address_mode clamp
texture DoF_Depth
}
texture_unit blur
{
tex_address_mode clamp
}
}
}
technique HLSL
{
pass
{
fragment_program_ref DoF_DepthOfFieldFP_HLSL
{
}
texture_unit scene
{
tex_address_mode clamp
}
texture_unit depth
{
tex_address_mode clamp
texture DoF_Depth
}
texture_unit blur
{
tex_address_mode clamp
}
}
}
}
material DoF_FocusArea
{
technique
{
pass
{
scene_blend alpha_blend
texture_unit
{
texture focus.png
alpha_op_ex modulate src_texture src_manual 0.2
}
}
}
}
material DoF_DepthDebug
{
technique
{
pass
{
texture_unit
{
// This texture needs to be assigned at run-time because
// the debug overlay loads the material, and this would
// create a stand-in texture before the render texture is
// created leading to a crash.
//texture DoF_Depth
}
}
}
}
I also write a Dof.compositor:
Code: Select all
// Anti Flicking blur effect
compositor "DoF_Compositor_test"
{
technique
{
// Temporary textures
texture scene 0 0 PF_X8R8G8B8
texture blur target_width_scaled 0.5 target_height_scaled 0.5 PF_X8R8G8B8
target scene
{
// Render output from previous compositor (or original scene)
input previous
}
target blur
{
input none
pass render_quad
{
material DoF_Gaussian3x3
input 0 scene
identifier 0
}
}
target_output
{
// Blur horizontally
//input none
pass render_quad
{
material DoF_DepthOfField
input 0 scene
input 2 blur
identifier 1
}
}
}
}
I rename to "DoF_Compositor_test" to not make problems with DoF_Compositor in code.
So I'm use:
Code: Select all
//mCompositor = CompositorManager::getSingleton().addCompositor(mViewport, "DoF_Compositor"); // Add the compositor to the viewport
mCompositor = CompositorManager::getSingleton().addCompositor(mViewport, "DoF_Compositor_test"); // Add the compositor to the viewport
(note: I make some changes which you have speaked above:
Code: Select all
//definition->format = PF_X8R8G8B8;
definition->formatList.push_back(PF_X8R8G8B8);
and
Ogre::Vector3 pixelSize = Ogre::Vector3(1.0f / (mViewport->getActualWidth() / BLUR_DIVISOR),1.0f / (mViewport->getActualHeight() / BLUR_DIVISOR));
if((!fragParams.isNull())&&(fragParams->_findNamedConstantDefinition("pixelSize")))
fragParams->setNamedConstant("pixelSize", pixelSize );
//setNamedConstant() dont use Vector2, that why I use vector3 ( same in my shader )
//so, if you want keep pixelSize[2], change in Dof.material param_named pixelSize float3 0.03 0.03 0.03 => param_named pixelSize float2 0.03 0.03
//and in Dof.cg uniform float3 pixelSize => uniform float2 pixelSize
//note: same with pixelSizeScene and pixelSizeBlur
)
I hope it will help you.
If someone see something wrong in this code, please notify. Sorry for my english.