Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

need some help with HLSL. Each charater in my game shows a fire range arc (which is a textured model) which show how far the guy can shoot, see

screen shot of firing range

It looks ok, but I hate the fact that it shows even behing buildings. Now I already have a shader for rendering the Arc (where I only manipulate the u coordinate to achive oscilating effect) and I'm pretty sure that I can use the Shadow map approach for that - generate Shadow map as seen by the camera (my deferred renderer takes care of that), then when rendering the arc, compare current Depth to the one stored in shadow map and voila..

But I just can't get it to work. I know the theory, but I'm no expert in HLSL and shadow mapping...

Here is the code I have

...
float4x4 World;
float4x4 View;
float4x4 Projection;

float4x4 ObserverWVP; // of the character casting the arc

texture DepthMap; // as seen by the camera
...
struct VertexShaderInput
{
    float4 Position : POSITION0;
    float2 TextureCoordinates : TEXCOORD0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float2 TextureCoordinates : TEXCOORD0;
    float4 Observer : TEXCOORD1;
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);

    output.Observer = mul(input.Position, ObserverWVP);

    output.TextureCoordinates = input.TextureCoordinates;   

    return output;
}

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{    
    ...

    float2 temp = (input.Observer.xy / input.Observer.w) * 0.5 + 1; // half pixel
    float depth2 = tex2D(DepthSampler, temp);
    float depth = input.Observer.z / input.Observer.w;

    if (depth < depth2) 
    {
        discard;
    }

    return c;
}

And the ObserverWVP calculated in XNA

Matrix ObserverWVP = boneTransforms[mesh.ParentBone.Index] * worldMatrix // world
                        * Matrix.CreateLookAt(pos, pos + direction, Vector3.Up) // view
                        * Camera.Instance.ProjectionMatrix; // projection

Note that the direction vector is not normalized - it signifies the entire vector from the source (the character) to the outter edge of the arc.

I'm guessing the pixel shader is wrong. But I have no idea how to modify it. Any suggestions?

share|improve this question

2 Answers 2

It seems a problem to be solved with raycasting

share|improve this answer
    
Seems rather expensive having to cast a tray for each pixel of the model.. Or am I missing something? –  Tomáš Bezouška Dec 2 '11 at 21:24
    
you don't have to cast for each pixel of the model... you have to think in 2D, you only need the base of your buildings... and you don't need it as a texture, you can precalculate rectangles or lines to calcultate intersection with your cone (made of rays), in a vectorial way. –  Blau Dec 3 '11 at 17:53

I would represent the range arc as a spotlight model, since these types of lights stop right when they hit a wall and don't shine through. They have a set lighting angle and attenuation distance which would correspond to the characters' fire range.

As you have a deferred lighting system in place already, this shouldn't be too hard to apply. Spotlights are usually represented as a mesh, so you can make it either conical or pyramid-shaped, whatever suits your needs for the game. All you gotta add are the textures.

The Cansin Deferred Renderer has a spotlight rendering feature- it would probably be a good idea to see the code behind it.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.