Shield Effects [OpenGL]
I changed my driver to OpenGl and it works now.
I use it to display a shield around the player and all enemies. When i shot at them you can see the bullet hitting the surface of the shield, but the bullet has the same effect on the players shield when leaving it.
How can i change the code to display only shots going into the shield and not going out?
MfG
Scarabol
I use it to display a shield around the player and all enemies. When i shot at them you can see the bullet hitting the surface of the shield, but the bullet has the same effect on the players shield when leaving it.
How can i change the code to display only shots going into the shield and not going out?
MfG
Scarabol
Irrlicht 1.7.2
Eclipse
Boost
Eclipse
Boost
-
- Posts: 226
- Joined: Fri Aug 22, 2008 8:50 pm
- Contact:
ARB is OpenGL too I think.
Adding a global impact means you have your node and add a point on the shields surface. The shader however requires the coordinats to be in the shield node's space. So the point's position is transformed to local space. Using localimpact means you know the local space of the node and add the point in local space.
For the bullet: Check wether the bullets trajectory is towards or out of the shield and add only the impacts you want. The collision detection of the sample does not differ between in or outgoing shots, the method simply returns the first collision point with the shield.
greetings
Adding a global impact means you have your node and add a point on the shields surface. The shader however requires the coordinats to be in the shield node's space. So the point's position is transformed to local space. Using localimpact means you know the local space of the node and add the point in local space.
For the bullet: Check wether the bullets trajectory is towards or out of the shield and add only the impacts you want. The collision detection of the sample does not differ between in or outgoing shots, the method simply returns the first collision point with the shield.
greetings
-
- Posts: 226
- Joined: Fri Aug 22, 2008 8:50 pm
- Contact:
To use this with DirectX you have to write a shader in a directX shader language and add it to the shieldmanager constructor.
As for the direction of the shots, the shieldmanager is merely to display shields and impacts. It is like the scenemanager and 'basic collision' there is something implemented and if you want more advanced/accurate detection you are welcomed to do it yourself
Anyway it would not be so hard to change that. You could either prevent the collisiondetection of outgoing bullet and shield in your game engine in the first place or rewrite the addImpact method like this:
You can of course instead compare the normals.
For round shields this should work, for complex shields with edges or something it might not be accurate enough. Another point, why this detection is not included and should be customized by the user.
greetings
As for the direction of the shots, the shieldmanager is merely to display shields and impacts. It is like the scenemanager and 'basic collision' there is something implemented and if you want more advanced/accurate detection you are welcomed to do it yourself
Anyway it would not be so hard to change that. You could either prevent the collisiondetection of outgoing bullet and shield in your game engine in the first place or rewrite the addImpact method like this:
Code: Select all
core::vector3df CShieldManager::addImpact(const scene::ISceneNode *node, const core::line3df ray, const f32 radius, const u32 duration, const video::SColorf color){
//Check if node pointer is given, otherwise the collision point routine will crash
if(!node)
return ray.end;
//Check if endpoint is closer to shield center than start point
if(node->getAbsolutePosition().getDistanceFrom(ray.start) > node->getAbsolutePosition().getDistanceFrom(ray.end)){
//Check for intersection
core::vector3df colPoint;
core::triangle3df colTris;
const scene::ISceneNode* outNode;
if(smgr->getSceneCollisionManager()->getCollisionPoint(ray,
node->getTriangleSelector(), colPoint,
colTris, outNode))
{
//Intersection found
//Transform position to local space
core::vector3df tmpPoint = core::vector3df(colPoint);
core::matrix4 trans = node->getAbsoluteTransformation();
trans.makeInverse();
trans.transformVect(colPoint);
//Add impact
addLocalImpact(node,colPoint,radius,duration,color);
return tmpPoint;
}
}
//No intersection
return ray.end;
}
For round shields this should work, for complex shields with edges or something it might not be accurate enough. Another point, why this detection is not included and should be customized by the user.
greetings
Thanks for your reply, i made it this way:
Why do you think this would not work with complex mesh?
MfG
Scarabol
Code: Select all
/*...*/
if(smgr->getSceneCollisionManager()->getCollisionPoint(ray,
node->getTriangleSelector(), colPoint,
colTris, outNode))
{
core::vector3df vec1 = colTris.getNormal(), vec2 = ray.getVector();
f32 angle = acos(vec1.dotProduct(vec2) * core::reciprocal_squareroot(vec1.getLengthSQ() * vec2.getLengthSQ()));
angle *= 180 / core::PI; // this could be better i know, just for testing purpose
if (angle >= 90)
{
/*...*/
MfG
Scarabol
Irrlicht 1.7.2
Eclipse
Boost
Eclipse
Boost
-
- Posts: 226
- Joined: Fri Aug 22, 2008 8:50 pm
- Contact:
Here is a screenshot of my current projekt state with your shield effects:
Everytime i use another mesh than ISphereMesh i get these faults u can see on the screenshot. The impact are not displayed on the mesh but next to it.
Im using your original source and my shieldnode is the IAnimatedMeshSceneNode you can see on the screenshot (gray one)
MfG
Scarabol
Everytime i use another mesh than ISphereMesh i get these faults u can see on the screenshot. The impact are not displayed on the mesh but next to it.
Im using your original source and my shieldnode is the IAnimatedMeshSceneNode you can see on the screenshot (gray one)
MfG
Scarabol
Irrlicht 1.7.2
Eclipse
Boost
Eclipse
Boost
-
- Posts: 226
- Joined: Fri Aug 22, 2008 8:50 pm
- Contact:
freetimecoder wrote:Hm looks to me like the impacts would be displayed where the bullets hit, just that the shield itself has a wrong position. How do you create the shield node?
Code: Select all
_shieldnode = smgr->getmesh("station_shield.x");
_shieldnode->setParent(this->getnode());
_shieldnode->setMaterialFlag(EMF_BACK_FACE_CULLING, false);
_shieldnode->setVisible(true);
scene::ITriangleSelector *selector = _gm->getsmgr()->createTriangleSelector(_shieldnode->getMesh(), _shieldnode);
_shieldnode->setTriangleSelector(selector);
selector->drop();
_shieldnode->setMaterialTexture(0, _gm->getdriver()->getTexture("../data/shield_tex.png"));
_shieldnode->setMaterialTexture(1, _gm->getdriver()->getTexture("../data/gradient.png"));
_gm->getshieldmanager()->addShield(_shieldnode);
Console says no errors everything is loaded in right way.
The gray one is my non transparent shield nodefreetimecoder wrote:Did you try using a non transparent impact texture to see the complete shield for debugging?
MfG
Scarabol
Irrlicht 1.7.2
Eclipse
Boost
Eclipse
Boost
-
- Posts: 226
- Joined: Fri Aug 22, 2008 8:50 pm
- Contact:
Sure this is the code you use?
Anyway, have you tried addGlobal impact with a point on the shieldnode's surface? Are those displayed correctly?
I still have no real clue of what could cause this
The sample's shields use parents, too and the transform works there.
greetings
Code: Select all
_shieldnode = smgr->getmesh("station_shield.x");
I still have no real clue of what could cause this
The sample's shields use parents, too and the transform works there.
greetings
-
- Posts: 1
- Joined: Thu Jul 22, 2010 5:54 pm
Hi
I have been messing with the code so it isn't exactly the same but I have almost produced a HLSL version. The main problem with the HLSL version is the impacts start off large and shrink. This is the first time I have messed with HLSL so if anyone wants to point out my errors feel free.
[code]
varying vec3 vertpos;
void main(void)
{
vertpos = gl_Vertex.xyz;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
//Fragment Shader
uniform float radius;
uniform vec4 color;
uniform vec3 current_position;
varying vec3 vertpos;
void main(void)
{
vec3 dif = vertpos - current_position;
float dist = dif.x*dif.x + dif.y*dif.y + dif.z*dif.z;
float intensity=1/dist*radius*0.01; if(intensity>0.9)
intensity=0.9;
if(intensity<0)
intensity=0;
vec4 final_color = color * intensity;
gl_FragColor=final_color;
}
";
[/code]
becomes
[code]
float4x4 mWorld;
float4x4 mView;
float4x4 mProj;
float4x4 worldViewProjection;
struct VS_OUTPUT {
float4 Pos: POSITION;
float2 TexCoords: TEXCOORD0;
float4 vPos: TEXCOORD1;
};
VS_OUTPUT main(float4 Pos: POSITION,
float2 TexCoords : TEXCOORD0)
{
VS_OUTPUT output;
output.vPos = Pos;
worldViewProjection = mul(mul(mWorld, mView), mProj);
output.Pos = mul(Pos, worldViewProjection);
output.TexCoords = TexCoords;
return output;
}
float radius;
float4 color;
float3 current_position;
float4 main(float2 TexCoords: TEXCOORD0, float4 vPos: TEXCOORD1) : COLOR
{
float3 dif;
dif.x = vPos.x;
dif.y = vPos.y;
dif.z = vPos.z;
dif = dif - current_position;
float dist = dif.x*dif.x + dif.y*dif.y + dif.z*dif.z;
float intensity=1/((dist*radius*0.01));
if(intensity>0.9)
intensity=0.9;
if(intensity<0)
intensity=0;
float4 final_color = color * intensity;
return final_color;
}
[/code]
I have been messing with the code so it isn't exactly the same but I have almost produced a HLSL version. The main problem with the HLSL version is the impacts start off large and shrink. This is the first time I have messed with HLSL so if anyone wants to point out my errors feel free.
[code]
varying vec3 vertpos;
void main(void)
{
vertpos = gl_Vertex.xyz;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
//Fragment Shader
uniform float radius;
uniform vec4 color;
uniform vec3 current_position;
varying vec3 vertpos;
void main(void)
{
vec3 dif = vertpos - current_position;
float dist = dif.x*dif.x + dif.y*dif.y + dif.z*dif.z;
float intensity=1/dist*radius*0.01; if(intensity>0.9)
intensity=0.9;
if(intensity<0)
intensity=0;
vec4 final_color = color * intensity;
gl_FragColor=final_color;
}
";
[/code]
becomes
[code]
float4x4 mWorld;
float4x4 mView;
float4x4 mProj;
float4x4 worldViewProjection;
struct VS_OUTPUT {
float4 Pos: POSITION;
float2 TexCoords: TEXCOORD0;
float4 vPos: TEXCOORD1;
};
VS_OUTPUT main(float4 Pos: POSITION,
float2 TexCoords : TEXCOORD0)
{
VS_OUTPUT output;
output.vPos = Pos;
worldViewProjection = mul(mul(mWorld, mView), mProj);
output.Pos = mul(Pos, worldViewProjection);
output.TexCoords = TexCoords;
return output;
}
float radius;
float4 color;
float3 current_position;
float4 main(float2 TexCoords: TEXCOORD0, float4 vPos: TEXCOORD1) : COLOR
{
float3 dif;
dif.x = vPos.x;
dif.y = vPos.y;
dif.z = vPos.z;
dif = dif - current_position;
float dist = dif.x*dif.x + dif.y*dif.y + dif.z*dif.z;
float intensity=1/((dist*radius*0.01));
if(intensity>0.9)
intensity=0.9;
if(intensity<0)
intensity=0;
float4 final_color = color * intensity;
return final_color;
}
[/code]
omg nice!
tho, i found some misses, but at least i could start from somewhere!
here is the code:
vertex:
fragment:
and at onsetconstaints:
it works good, only one bug:
http://blud.freeiz.com/up/glsl.jpg
http://blud.freeiz.com/up/hlsl.jpg
as u see, on the glsl picture, its nice, but the hlsl is pretty pixel'ish
how can i solve it?
tho, i found some misses, but at least i could start from somewhere!
here is the code:
vertex:
Code: Select all
float4x4 worldViewProjection;
struct VS_OUTPUT {
float4 Pos: POSITION;
float2 TexCoords: TEXCOORD0;
float4 vPos: TEXCOORD1;
};
VS_OUTPUT main(float4 Pos: POSITION,
float2 TexCoords : TEXCOORD0)
{
VS_OUTPUT output;
output.vPos = Pos;
output.Pos = mul(Pos, worldViewProjection);
output.TexCoords = TexCoords;
return output;
}
Code: Select all
float radius;
float4 color;
float3 current_position;
sampler2D ColorMap : register(s1);
sampler2D GradientTexture : register(s2);
float4 main(float2 TexCoords: TEXCOORD0, float4 vPos: TEXCOORD1) : COLOR
{
float3 dif = vPos.xyz;
dif = dif - current_position;
float dist = dif.x*dif.x + dif.y*dif.y + dif.z*dif.z;
float intensity=1/dist*radius*0.01;
if(intensity>0.9)
intensity=0.9;
if(intensity<0)
intensity=0;
float4 diffuse = tex2D(ColorMap, TexCoords);
float4 gradient = tex2D(GradientTexture, float2(intensity,1));
float4 final_color = gradient * diffuse * intensity * color;
return final_color;
}
Code: Select all
//This is called for each impact render
void CShieldManager::OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
core::matrix4 worldViewProj;
worldViewProj = driver->getTransform(video::ETS_PROJECTION);
worldViewProj *= driver->getTransform(video::ETS_VIEW);
worldViewProj *= driver->getTransform(video::ETS_WORLD);
services->setVertexShaderConstant("worldViewProjection", worldViewProj.pointer(), 16);
services->setPixelShaderConstant("current_position", (float*)(&tmp_position ), 3);
services->setPixelShaderConstant("radius", (float*)(&tmp_radius ), 1);
services->setPixelShaderConstant("color", (float*)(&tmp_color ), 4);
}
http://blud.freeiz.com/up/glsl.jpg
http://blud.freeiz.com/up/hlsl.jpg
as u see, on the glsl picture, its nice, but the hlsl is pretty pixel'ish
how can i solve it?