之前寫折射的時候沒有記錄, 所以完全忘了怎麼寫了…
重新開始寫吧
To do list:
- 整理 RzMaterial
- 寫成 Compositor
- Refraction ? Distortion?
RzApp::switchCompositor 為目前可以開關的機制
目前可用的 Compositor為
Example.compositor
- Bloom
- Glass
- “Old TV"
- B&W
- Embossed
- “Sharpen Edges"
- Invert
- Posterize
- Laplace
- Tiling
- “Old Movie"
- HDR
- “Gaussian Blur"
- TestMRT
- “Radial Blur"
- ASCII
- Halftone
- “Night Vision"
- Dither
Rz.compositor
- Rz/Compositor/GaussianBlurNoBG
其中HeatVision是完全寫在Code裏的
從Ogre Manual上看來的一些基礎知識做個筆記:
3.2.1 Techniques
compositor_logic 可以放一個名字 比如說 HDR, 到了程式中再把這個名字代換成真正物件的名稱
Ogre::CompositorManager& compMgr = Ogre::CompositorManager::getSingleton();
compMgr.registerCompositorLogic("HDR", new HDRLogic);
class HDRLogic : public ListenerFactoryLogic
{
protected:
virtual Ogre::CompositorInstance::Listener* createListener(Ogre::CompositorInstance* instance);
};
Target Pass 是一個Compositor中最重要的元件, 它可以有以下東西:
- input
- only_initial
- visibility_mask
- lod_bias
- material_scheme
- shadows
- pass
其中最重要的, 又是這個叫pass的東西, 由先它的格式為:
‘pass’ (render_quad | clear | stencil | render_scene | render_custom) [custom name] { }
這裏來個最最簡單的compositor示範compositor Rz/Compositor/SimplePixel
{
technique
{
texture rt0 target_width target_height PF_A8R8G8B8
target rt0
{
input previous
}
target_output
{
input none
pass render_quad
{
material Rz/Compositor/Material/Invert
input 0 rt0
}
}
}
}
這裏用了一個material Rz/Compositor/Material/SimplePixel
讓我們繼續追踪下去:
material Rz/Compositor/Material/Invert
{
technique
{
pass
{
cull_hardware none
cull_software none
depth_func always_pass
vertex_program_ref Ogre/Compositor/StdQuad_Tex2a_vp
{
}
fragment_program_ref Rz/Compositor/InvertFP
{
}
texture_unit RT
{
tex_coord_set 0
tex_address_mode clamp
filtering trilinear
}
}
}
}
這個vertex shader很簡單, 是個公版
void StdQuad_Tex2a_vp
(
in float4 inPos : POSITION,
out float4 pos : POSITION,
out float2 uv0 : TEXCOORD0,
out float2 uv1 : TEXCOORD1,
uniform float4x4 worldViewProj
)
{
// Use standardise transform, so work accord with render system specific (RS depth, requires texture flipping, etc)
pos = mul(worldViewProj, inPos);
// The input positions adjusted by texel offsets, so clean up inaccuracies
inPos.xy = sign(inPos.xy);
// Convert to image-space
uv0 = (float2(inPos.x, -inPos.y) + 1.0f) * 0.5f;
uv1 = inPos.xy;
}
回到material來, 它的fragment program 是主要的shader程式
fragment_program Rz/Compositor/InvertFP cg
{
source RzInvertFP.cg
entry_point Invert_ps
profiles ps_2_0 arbfp1
}
裏面是長這樣的
sampler RT : register(s0);
float4 Invert_ps (float2 iTexCoord : TEXCOORD0) : COLOR
{
return 1 - tex2D(RT, iTexCoord);
}
今天我們來試試其他簡單的pixel shader, 以下是參考網站(Facewound)
首先來個3倍亮度:
把 compositor裏的material
material Rz/Compositor/Material/Invert改成
material Rz/Compositor/Material/TrippleColor那麼我們也要新增一個相對應的material script (TrippleColor.material)給它:fragment_program Rz/TrippleColorFP cg { source TrippleColorFP.cg entry_point TrippleColor_ps profiles ps_2_0 arbfp1 } material Rz/Compositor/Material/TrippleColor { technique { pass { cull_hardware none cull_software none depth_func always_pass vertex_program_ref Ogre/Compositor/StdQuad_Tex2a_vp { } fragment_program_ref Rz/TrippleColorFP { } texture_unit RT { tex_coord_set 0 tex_address_mode clamp filtering trilinear } } } }這麼一來, 又要新增一個 fragment_program (trippleColorFP.cg)給它sampler RT : register(s0); float4 TrippleColor_ps (float2 iTexCoord : TEXCOORD0) : COLOR { return tex2D(RT, iTexCoord) * 3; } 結果變成
同樣的原理, 我們可以嚐試很多不一樣的東西
比如改成 material Rz/Compositor/Material/GradientY
新增 GradientYFP.cg
sampler RT : register(s0);
float4 GradientY_ps (float2 iTexCoord : TEXCOORD0) : COLOR
{
return tex2D(RT, iTexCoord) * iTexCoord.y;
}
畫面就會變成根據Y從0到1的漸層
再來, 試試將紅色變成2倍, 過程和細節就不再重覆
只寫出 pixel shader的部份
sampler RT : register(s0);
float4 DoubleRed_ps (float2 iTexCoord : TEXCOORD0) : COLOR
{
float4 Color=tex2D(RT, iTexCoord);
Color.r = Color.r * 2.0;
return Color;
}
結果如下:
哈哈
再試一個
- CrazySin的效果吧
sampler g_samSrcColor : register(s0);
float4 CrazySin_ps (float2 Tex : TEXCOORD0) : COLOR
{
float4 Color = tex2D( g_samSrcColor, Tex.xy);
Color.r = Color.r*sin(Tex.y*100)*2;
Color.g = Color.g*cos(Tex.y*200)*2;
Color.b = Color.b*sin(Tex.y*300)*2;
return Color;
}
是不是很Crazy
- HalfU
sampler g_samSrcColor : register(s0);
float4 HalfU_ps (float2 Tex : TEXCOORD0) : COLOR
{
Tex.x = Tex.x * 0.5;
float4 Color = tex2D( g_samSrcColor, Tex.xy);
return Color;
}
雖然名為HalfU 但圖看起變成橫幅兩倍大
- SinusoidV
sampler g_samSrcColor : register(s0);
float4 SinusoidV_ps (float2 Tex : TEXCOORD0) : COLOR
{
Tex.y = Tex.y + (sin(Tex.x * 200) * 0.01);
float4 Color = tex2D( g_samSrcColor, Tex.xy);
return Color;
}






沒有留言:
張貼留言