2 registered members (AndrewAMD, SBGuy),
987
guests, and 3
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
watershader from mtlFX.c problem
#441533
05/26/14 11:37
05/26/14 11:37
|
Joined: Dec 2009
Posts: 82
Denn15
OP
Junior Member
|
OP
Junior Member
Joined: Dec 2009
Posts: 82
|
ive added water to my scene which looks fine the first time the water is loaded, but if i load another a new level without closing my game, it looks very weird and looks like this: water that looks fine: http://prntscr.com/3mpl2awater that looks weird: http://prntscr.com/3mplc2also when moving around the reflection does not follow the screen either.
action snow()
{
wait(2);
ent_create("fog.tga", vector(0, 0, 800), fog);
ent_create("water.hmp",vector(0,0,-5),water);
while(1)
{
ent_create("snowflake.tga", vector(player.x + random(600) - 300, player.y + random(600) - 300, player.z + 250), snowflake);
wait(-0.05);
}
}
action water()
{
set(my, FLAG2);
my.scale_x = 10;
my.scale_y = 10;
fx_mirrorWater();
if (doonce == 0)
{
my.skill43 = floatv(fixv(my.skill43)-40);
my.skill44 = floatv(fixv(my.skill44)+15);
doonce = 1;
}
}
|
|
|
Re: watershader from mtlFX.c problem
[Re: Denn15]
#441536
05/26/14 12:02
05/26/14 12:02
|
Joined: Mar 2011
Posts: 3,150 Budapest
sivan
Expert
|
Expert
Joined: Mar 2011
Posts: 3,150
Budapest
|
I reported it (with a solution) earlier as an issue but has been ignored by the developers. you need to modify this part of mtlfx.c (I left there old code as commented out):
function fx_mirror()
{
// do nothing if mirror is already running
if (bmap_mirrortarget)
{
// my.material.skin2 = bmap_mirrortarget;
// return;
ptr_remove(bmap_mirrortarget); // *** correct mirror shift on multiple level loads
mw_bmap_mirrortarget = NULL;
}
bmap_mirrortarget = bmap_createblack(256,256,888);
...
another issue you can see is the shifted mirror view thanks to bmap_to_uv in mw_mirror_water_init() that can be resolved by using for example mw_bmap_water_uv = bmap_to_normals(bmap_for_entity(my,1), 50); instead, or simply use a fine normal map and comment out bmap_to_uv.
|
|
|
Re: watershader from mtlFX.c problem
[Re: Denn15]
#441572
05/27/14 13:34
05/27/14 13:34
|
Joined: Mar 2011
Posts: 3,150 Budapest
sivan
Expert
|
Expert
Joined: Mar 2011
Posts: 3,150
Budapest
|
that could lead to memory leaks imo. why dont't you just ptr_remove, and set to NULL before creating it again?
if (bmap_mirrortarget)
{
ptr_remove(bmap_mirrortarget);
bmap_mirrortarget = NULL;
}
bmap_mirrortarget = bmap_createblack(256,256,888);
Last edited by sivan; 05/27/14 13:37.
|
|
|
Re: watershader from mtlFX.c problem
[Re: Denn15]
#441636
05/29/14 07:43
05/29/14 07:43
|
Joined: Mar 2011
Posts: 3,150 Budapest
sivan
Expert
|
Expert
Joined: Mar 2011
Posts: 3,150
Budapest
|
in MapBuilder I use this custom version, extracted from mtlfx.c. what it does differently, it requires a water texture as the 1st terrain skin, and it is converted into a normal map, so wave appearance heavily depends on this texture. you can get a few ones from my editor package. MBmwater.h
#ifndef MBmwater_h
#define MBmwater_h
//help: Make mirror view visible by pressing F11
//#define MIRROR_DEBUG
#ifdef MIRROR_DEBUG
VIEW* mw_view_mirror = { layer = 1; }
#else
VIEW* mw_view_mirror = { layer = -1; } // render mirror view before camera view
#endif
BMAP* mw_bmap_mirrortarget = NULL;
var mw_mtlfx_mirrorvisible = 0;
BMAP* mw_bmap_water_uv = NULL;
//////////////////////////////////////////////////////////////////////
// events
function mw_mirror_water_init();
//////////////////////////////////////////////////////////////////////
MATERIAL* mtl_mirrorWaterMB =
{
effect = "mirrorWaterMB.fx"; // ***
event = mw_mirror_water_init;
}
//////////////////////////////////////////////////////////////////////
// functions
function mw_fx_mirror();
function mw_mirror_init();
action mw_fx_mirrorWater();
#endif
MBmwater.c
#ifndef MBmwater_c
#define MBmwater_c
//////////////////////////////////////////////////////////////////////
// code
//Simulate a horizontal mirror by generating
//a camera view from below through the floor
function mw_fx_mirror()
{
// do nothing if mirror is already running
if (mw_bmap_mirrortarget)
{
// my.material.skin2 = mw_bmap_mirrortarget;
// return;
ptr_remove(mw_bmap_mirrortarget); // *** correct mirror shift on multiple level loads
mw_bmap_mirrortarget = NULL;
}
mw_bmap_mirrortarget = bmap_createblack(256,256,888);
my.material.skin2 = mw_bmap_mirrortarget;
mw_view_mirror.bmap = mw_bmap_mirrortarget;
mw_view_mirror.size_x = bmap_width(mw_view_mirror.bmap);
mw_view_mirror.size_y = bmap_height(mw_view_mirror.bmap);
vec_set(mw_view_mirror.pnormal_x,vector(0,0,1.0)); // reflect upwards
set(mw_view_mirror,NOCULL|PORTALCLIP); // *** NOSHADOW| - to get proper decal shadows - engine bug to be fixed
#ifdef ENGINE_BUG_DECAL_A840
if ((shadow_stencil < (var)0 ) || (shadow_stencil > (var)2)) // *** because of an engine bug below A8.45.1
#endif
{
set(mw_view_mirror, NOSHADOW); // *** needed by pssm, not needed by decal/stencil shadows
}
// suppress shadows in the mirror, look through walls, and clip at portal plane
//enable: Suppress FLAG1 in mirror
//help: Don't display FLAG1 objects in the mirror views
//id: 23
set(mw_view_mirror,NOFLAG1); // suppress all entities with flag1 set
//enable: Suppress particles in mirror
//help: Don't display particles in the mirror views
//id: 24
set(mw_view_mirror,NOPARTICLE);
//enable: Suppress shaders in mirror
//help: Don't render material effects in the mirror views
//id: 25
set(mw_view_mirror,NOSHADER);
while ((mw_bmap_mirrortarget) && (me)) // ¤¤¤
{
proc_mode = PROC_LATE; // camera must be moved and mtlfx_mirrorvisible set before
if (mw_mtlfx_mirrorvisible)
{
set(mw_view_mirror,SHOW);
mw_view_mirror.genius = camera.genius;
mw_view_mirror.aspect = (screen_size.x/screen_size.y)*camera.aspect; // screen aspect, independent of render target
mw_view_mirror.arc = camera.arc;
mw_view_mirror.fog_start = camera.fog_start;
mw_view_mirror.fog_end = camera.fog_end;
mw_view_mirror.clip_far = camera.clip_far * 0.5;
mw_view_mirror.clip_near = camera.clip_near * 2;
mw_view_mirror.x = camera.x;
mw_view_mirror.y = camera.y;
mw_view_mirror.z = 2*mw_view_mirror.portal_z - camera.z; // move the camera at its mirror position
mw_view_mirror.pan = camera.pan;
mw_view_mirror.tilt = -camera.tilt; // flip the vertical camera angle
mw_view_mirror.roll = -camera.roll;
}
else
{
// switch rendering off when all mirror objects are outside the frustum
reset(mw_view_mirror,SHOW);
}
mw_mtlfx_mirrorvisible = 0;
#ifdef MIRROR_DEBUG
if (key_f11)
{
// debugging - make mirror visible onscreen
mw_view_mirror.bmap = NULL;
}
else
{
mw_view_mirror.bmap = mw_bmap_mirrortarget;
}
#endif
wait(1);
}
// ¤¤¤
ptr_remove(mw_bmap_mirrortarget); // *** correct mirror shift on multiple level loads
mw_bmap_mirrortarget = NULL;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Section: Mirrors (new)
function mw_mirror_init()
{
mw_fx_mirror(); // create a mirror view, set mirror target to mtl.skin2
while (me) // ¤¤¤
{
if (!is(my,CLIPPED))
{
// place the mirror plane at the topmost entity polygon
vec_for_max(mw_view_mirror.portal_x,my); // without taking into account scale
// vec_mul(view_mirror.portal_x, my.scale_x); // *** multiply with scale
vec_add(mw_view_mirror.portal_x,my.x); // offset by position
// view_mirror.portal_z = my.z; // ***to avoid errors because of vertex movements
mw_mtlfx_mirrorvisible = 1;
}
wait(1);
}
}
function mw_mirror_water_init()
{
if (mw_bmap_water_uv)
{
ptr_remove(mw_bmap_water_uv); // *** correct mirror shift on multiple level loads
mw_bmap_water_uv = NULL;
}
// if (!mw_bmap_water_uv)
{
// mw_bmap_water_uv = bmap_to_uv(bmap_create("water.dds")); // orig - results in mirror offset
// mw_bmap_water_uv = bmap_to_normals(bmap_create("water.dds"), 50); // *** - no mirror offset error !
mw_bmap_water_uv = bmap_to_normals(bmap_for_entity(my,1), 50); // *** use 1st skin, okay
}
mtl.skin1 = mw_bmap_water_uv;
mtl.flags |= TRANSLUCENT;
mw_mirror_init(); // activate mirror view
}
//Variable1: xWind
//Variable2: yWind
//Variable3: Ripples
//Variable4: Scale
action mw_fx_mirrorWater()
{
my.material = mtl_mirrorWaterMB;
mtl_setup(50,50,50,50);
}
#endif
include MBmwater.h and MBmwater.c in your game, declare some global variables to have real-time tweakable parameters:
var material_mwater_speedx = 10;
var material_mwater_speedy = 25;
var material_mwater_ripple = 50;
var material_mwater_scale = 100;
put this into your water terrain action:
reset(my,TRANSLUCENT); // only if entity alpha is 100! requires OVERLAY flag to be used for 32b textured entities placed under water
// OR:
// set(my,TRANSLUCENT); // only if entity alpha < 100!
my.alpha = 100;
mw_fx_mirrorWater(); // results in strange individual decal shadow behaviour in A7 and A8.40 - do not set NOSHADOW for any mirror VIEW to avoid it
my.red = 80;
my.green = 90;
my.blue = 90;
my.skill41 = floatv(material_mwater_speedx); // 10 speed x 0..255
my.skill42 = floatv(material_mwater_speedy); // 25 speed y 0..255
my.skill43 = floatv(material_mwater_ripple); // 25 ripples 1..255
my.skill44 = floatv(material_mwater_scale); // 100 scale 1..255
and use the shader mirrorWaterMB.fx:
bool AUTORELOAD;
#include <transform>
#include <fog>
#include <pos>
#include <normal>
//#include <vecskill> // use global variables instead of skills
float4 vecTime;
float4 vecSunColor;
float4 vecColor;
float fAlbedo;
float fAlpha;
/////////////////////////////////////////////////////////////////////////////
texture entSkin1;
texture mtlSkin1;
texture mtlSkin2;
// my.skill41 = floatv(10); // 10 speed x
// my.skill42 = floatv(25); // 25 speed y
// my.skill43 = floatv(25); // 25 ripple - waves
// my.skill44 = floatv(75); // 100 scale
float material_mwater_speedx_var = 10.0;
float material_mwater_speedy_var = 25.0;
float material_mwater_ripple_var = 50.0;
float material_mwater_scale_var = 100.0;
/////////////////////////////////////////////////////////////////////////////
sampler sBumpTex = sampler_state
{
Texture = <mtlSkin1>;
MipFilter = Linear;
MinFilter = Linear;
MagFilter = Linear;
AddressU = Wrap;
Addressv = Wrap;
};
sampler sMirrorTex = sampler_state
{
Texture = <mtlSkin2>;
MipFilter = Linear;
MinFilter = Linear;
MagFilter = Linear;
AddressU = Clamp;
Addressv = Clamp;
};
/////////////////////////////////////////////////////////////////////////////
struct out_mirror // Output to the pixelshader fragment
{
float4 Pos : POSITION;
float Fog : FOG;
float4 Color: COLOR0;
float2 Tex0 : TEXCOORD0;
float3 Tex1 : TEXCOORD1;
float3 Albedo: TEXCOORD2;
};
/////////////////////////////////////////////////////////////////////////////
out_mirror vs_water_mirror
(
in float4 inPos : POSITION,
in float3 inNormal : NORMAL,
in float4 inTex0 : TEXCOORD0
)
{
out_mirror Out;
Out.Pos = DoTransform(inPos); // transform to screen coordinates
Out.Fog = DoFog(inPos);
// bump and reflection coordinates
float2 Speed;
Speed.x = (material_mwater_speedx_var * 0.000002);
Speed.y = (material_mwater_speedy_var * 0.000002);
Out.Tex0 = (inTex0 + Speed*vecTime.w) * (material_mwater_scale_var*0.05);
Out.Tex1 = Out.Pos.xyw;
// color and transparency
Out.Albedo.x = fAlbedo;
Out.Albedo.y = 1.0 - fAlbedo;
Out.Albedo.z = (material_mwater_ripple_var*0.001); // ripple
Out.Color = float4(vecColor.xyz+vecSunColor.xyz,fAlpha);
#ifdef MIRROR_FRESNEL
float4 P = DoPos(inPos); // vector world position
float3 vecToView = normalize(vecViewPos-P); // direction towards camera
float3 N = DoNormal(inNormal); // normal world orientation
Out.Color.a = 0.5 + fAlpha * (1.0 - dot(vecToView,N));
#endif
return Out;
}
/////////////////////////////////////////////////////////////////////////////
float4 ps_water_mirror20(out_mirror In): COLOR
{
float4 Bump = tex2D(sBumpTex,In.Tex0)*2-1;
float2 Coord = 0.5 * (1.0 + In.Tex1.xy/In.Tex1.z) + Bump.xy*In.Albedo.z; // ***
float4 ColorMod = In.Color;
// ColorMod.r = In.Color.r;
// ColorMod.g = In.Color.g;
// ColorMod.b = In.Color.b;
ColorMod.a = 1; //(1-In.Color.w)*0.5 + In.Color.w;
return tex2D(sMirrorTex,Coord) * In.Color * ColorMod; // ***
//return float4(0,0,1,0.5);
}
//////////////////////////////////////////////////////////////////
technique water_mirror
{
pass one
{
AlphaBlendEnable = True;
VertexShader = compile vs_2_0 vs_water_mirror();
PixelShader = compile ps_2_0 ps_water_mirror20();
}
}
technique fallback { pass one { } }
now you can tweak entity rgb and alpha (if alpha <100 set the entity TRANSLUCENT flag!), and material parameters too to get an acceptable result.,
Last edited by sivan; 05/29/14 07:51.
|
|
|
Moderated by mk_1, Perro, rayp, Realspawn, Rei_Ayanami, rvL_eXile, Spirit, Superku, Tobias, TSG_Torsten, VeT
|