Quote: "What do you think the "camera view" vector is in view space if not simply the vector (0,0,1)?"
Yes, well I was to ask you if the world z normal was in the same XYZ frame of reference that the camera viewing direction, because that was the only explanation for being equal to the dot product.
Anyway glad that you made a revision, because I was starting to feel confused again
Quote: "...describe in words the effect you're after."
I'm sorry that I have not explained myself, here is another sample of what the improvement is about.
Imagine that the effect is the black area:
So what I would like is to use a 3d mesh instead of a plane, while keeping the 'fade away' of the effect at the edges. I have tried to do that with the 'dot(normal, camera_view) technique', glad to know that it was a good approach
Quote: "I still don't know why you want both the mask and this method though."
Yes I think you are right. Now the normal map should be enough to create the haze effect, shouldn't it?
So here is the most advanced version, I moved the operations in the pixel shader to the vertex shader, as you suggested.
DBPro code:
Rem Project: Bloom and HeatHaze
Rem Created: 17/10/2010 18:00:15
Rem ***** Main Source File *****
Rem variables
Global HeatFX as integer
Global HeatCam as integer
Global HeatCamIMG as integer
Global HeatXScroll,HeatYScroll as float
Global MainCam as integer
Global FXVector as integer
MainCam = 0 Rem This is your main camera (the camera you use for your game). Change it if you're using another camera.
FXVector = 1
Rem --heat haze
HeatFX = 1
HeatCam = 1
HeatCamIMG = 3
HeatQuad = 2
Rem --Bloom
BloomFX = 2
BloomCam = 2
BloomCamIMG = 4
BloomQuad = 3
BloomQuadFX = 3
Rem --Level
LevelObj = 1
Rem Setup the camera variables (unrelated to heat haze)
CamAngX#=25
CamAngY#=0
CamDist#=250
mmx# = 0
mmy# = 0
mmz# = 0
Set Display Mode Desktop Width(), Desktop Height(),32
reload display pointer
Sync On
Sync Rate 60
AutoCam Off
Set Window On
Maximize Window
Set Window Layout 0, 0, 0
Rem Make the vector
Make Vector4 FXVector
Rem Load the level object
Load Object "Level/Level.dbo", LevelObj
Rem /HEAT HAZE SETUP:
Rem Load the heat haze effect and make the camera
Load Effect "FX/HeatHaze6c.fx", HeatFX, 0
Make Camera HeatCam
REM Set Camera To Image HeatCam, HeatCamIMG, 512, 512
REM For a perfect match, use screen size
Set Camera To Image HeatCam, HeatCamIMG, Screen Width(), Screen Height()
Rem Load the heat haze textures.
Rem NormalMap: Defines the bumpiness of the heat haze. This texture will scroll along the heat haze to create the distortion effect.
Rem Mask: (GG change) Defines the amount of distortion. Black = 0 no distortion, White = 100% full distortion.
Load Image "Textures/HeatHazeNormalMap.bmp", 1
REM Not needed for "FX/HeatHaze6c.fx": Load Image "Textures/HeatHazeMask.bmp", 2
Rem Make a heat haze object and position it this object can be whatever shape you want. I just chose a plain.
rem Make Object Plain HeatQuad, 130, 130
Make Object Sphere HeatQuad, 130, 64, 64
Position Object HeatQuad, 0, 70, 0
Rem Turn the heat haze effect on. [ Syntax is: SetHeatHazeOn object , effect , Normal Map Image, Mask Image ]. Specifying an effect number less than or equal to 0 will use the default effect.
SetHeatHazeOn(HeatQuad,HeatFX,1,2)
Rem Rem Rem /BLOOM SETUP:
REM START
REm ShaderDataStart
Color Backdrop 0, 0
Make Camera BloomCam
Color Backdrop BloomCam, 0
Load Camera Effect "FX/Bloom.dbs", BloomFX, 0
Set Camera Effect BloomCam, BloomFX, BloomCamIMG
Rem Make second quad
Make Object Plain BloomQuad, 2, 2
Load Effect "FX/quad.fx", BloomQuadFX, 0
Set Object Effect BloomQuad, BloomQuadFX
Set Vector4 FXVector, 1.0/Screen Width(), 1.0/Screen Height(), 0 , 0
Set Effect Constant Vector BloomQuadFX, "InvViewSize", FXVector
Texture Object BloomQuad, 0, BloomCamIMG
Rem To do not depend on hide/show
REM Set Object Mask BloomQuad, 1 << MainCam
Set Camera Effect Constant Float BloomFX, "BloomPower", 1.0
Set Camera Effect Constant Float BloomFX, "BloomScale", 1.0
REM END
do
`Print the FPS (unrelated to heat haze)
set cursor 0,0
print "FPS: ",screen fps()
`Control the camera (unrelated to heat haze)
mmx#=mousemovex()/8.0
mmy#=mousemovey()/8.0
mmz#=mousemovez()/-4.0
inc CamAngX#,mmy#
inc CamAngY#,mmx#
inc CamDist#,mmz#
position camera 0,20,0
rotate camera CamAngX#,CamAngY#,0
move camera -CamDist#
if camera position y()<20 then position camera camera position x(MainCam),20,camera position z(MainCam)
Rem Rem Rem /HEAT HAZE:
Rem Point the heat haze object at the camera (not needed, I just did this because I thought it might look better)
Point Object HeatQuad, Camera Position X(MainCam), Camera Position Y(MainCam), Camera Position Z(MainCam)
Rem Update the heat haze, scrolling the texture by 0 on the X axis and 0.005 on the Y axis. (Works just like SCROLL OBJECT TEXTURE.)
show object LevelObj
hide object HeatQuad
hide object BloomQuad
UpdateHeatHaze( 0.0, 0.01 )
Rem Rem Rem /BLOOM
REM START
Position Camera BloomCam, Camera Position X(MainCam),Camera Position Y(MainCam),Camera Position Z(MainCam)
Rotate Camera BloomCam, Camera Angle X(MainCam) ,Camera Angle Y(MainCam), Camera Angle Z(MainCam)
Rem Sync Bloom Cam
Hide Object BloomQuad
Show Object LevelObj
show object HeatQuad
Sync Camera BloomCam
Show Object BloomQuad
Hide Object LevelObj
Sync Mask %01
if ShiftKey()
Hide Object BloomQuad
else
Show Object BloomQuad
endif
REM END
Sync
loop
`Turns the heat haze effect on for an object. Specifying an effect number less than or equal to zero will cause the object to use the default effect.
`If you want to use a non-default effect, then you should load it yourself and specify its effect number here.
Function SetHeatHazeOn(obj,effect,NormalMapIMG,MaskIMG)
set object effect obj,effect
texture object obj,0,HeatCamIMG
texture object obj,1,NormalMapIMG
texture object obj,2,MaskIMG
null = make vector4(1)
set effect constant float effect, "bumpiness", 0.1
set effect constant float effect, "bumpScale", 1.0
Endfunction
`Updates the heat haze camera and scrolls the default heat haze effect by the amount you specify. If you don't want to scroll the default effect, then set this to 0. Works just like SCROLL OBJECT TEXTURE.
Function UpdateHeatHaze(ScrollU#,ScrollV#)
inc HeatXScroll,ScrollU#
inc HeatYScroll,ScrollV#
set vector4 1, HeatXScroll, HeatYScroll, 0.0, 0.0
set effect constant vector HeatFX, "offset", 1
position camera HeatCam,Camera Position x(MainCam),Camera Position Y(MainCam),Camera Position z(MainCam)
rotate camera HeatCam,Camera Angle x(MainCam),Camera Angle Y(MainCam),Camera Angle Z(MainCam)
sync mask 2^HeatCam
fastsync
sync mask 2^MainCam
Endfunction
Shader file 'HeatHaze6c.fx' code:
//==================================================================
// Heat Haze
//==================================================================
// Original Refraction Shader by EVOLVED. (www.evolved-software.com)
// Modified to support texture scrolling + mask by Sixty Squares
// Simplified and re-written by Green Gandalf 19 October 2010
// MPL3D mod, 13-nov-2010, dot product eye view and normal instead
// mask texture, to fade 3d object edges
//==================================================================
//--------------
// un-tweaks
//--------------
matrix mWVP : WorldViewProjection;
matrix mW : World;
matrix mVI : ViewInverse;
//MPL3D mod, 13-nov-2010
float4 cameraPosition : EyePosition;
//--------------
// tweaks
//--------------
float4 colour = {1.0, 1.0, 1.0, 1.0};
float bumpiness = 0.3;
float bumpScale = 3.0;
float2 offset = {0.0, 0.0};
//--------------
// textures
//--------------
texture screenTexture <string Name = "";>;
sampler2D screenSample = sampler_state
{ texture = <screenTexture>;
addressU = clamp;
addressV = clamp;
};
texture normalMap <string Name = "";>;
sampler2D normalMapSample = sampler_state
{ texture = <normalMap>;
addressU = wrap;
addressV = wrap;
};
//--------------
// structs
//--------------
struct VSInput
{ float4 pos : position;
float2 UV : texcoord0;
float3 normal : normal;
};
struct VSOutput
{ float4 pos : position;
float2 UV0 : texcoord0;
float2 UV1 : texcoord1;
float4 proj : texcoord2;
//MPL3D mod, 13-nov-2010
float3 wNormal : texcoord3;
float4 view : texcoord4;
};
struct PSOutput { float4 colour : color; };
//--------------
// vertex shader
//--------------
VSOutput VS(VSInput In, VSOutput Out)
{ Out.pos = mul(In.pos, mWVP);
Out.UV0 = In.UV;
Out.UV1 = In.UV * bumpScale + offset;
Out.proj = float4(Out.pos.x*0.5+0.5*Out.pos.w, 0.5*Out.pos.w-Out.pos.y*0.5, Out.pos.w, Out.pos.w);
//MPL3D mod, 13-nov-2010
float4 wPos = mul( In.pos, mW );
float3 wNormal = mul( In.normal, (float3x3)mW );
Out.wNormal = normalize(wNormal);
//calculate the angle between the normal and the camera
Out.view = normalize(cameraPosition - wPos);
return Out;
}
//--------------
// pixel shader
//--------------
PSOutput PS(VSOutput In, PSOutput Out)
{ float2 distort = tex2D(normalMapSample, In.UV1).xy * 2 - 1;
distort = distort * bumpiness;
//MPL3D mod, 13-nov-2010
float3 viewDir = normalize(In.view);
float angle = saturate( dot( In.wNormal, viewDir ) );
//limit the angle
angle = smoothstep( 0.0, 1.0, angle );
//MPL3D mod, 13-nov-2010
float2 UV = In.proj.xy/In.proj.z + distort * angle ;
Out.colour = tex2D(screenSample, UV) * colour;
return Out;
}
//--------------
// techniques
//--------------
technique haze
{ pass p1
{ VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_0 PS();
}
}
It works quite neat now, the fade away of the effect is perfect, however now I see a 'seam' from pole to pole
I'll upload a picture in the next post.