XNA Creators Club Online
Page 1 of 1 (2 items)
Sort Posts: Previous Next

XNA Billboard Sample, adding fog to .fx

Last post 11/20/2009 12:24 PM by Achilleterzo. 1 replies.
  • 11/20/2009 12:21 PM

    XNA Billboard Sample, adding fog to .fx

    Hi all, i have tried a lot to setup decent fog in the basic .fx coming with that example...

    My goal is adding this fog alghoritm to the billboard shader:

    float fogNear = 10; 
    float fogFar = 100; 
    float fogAltitudeScale = 10; 
    float fogThinning = 100; 
    float4 fogColor = {0.5, 0.5, 0.5, 1.0}; 


        float l = saturate((d - fogNear) / (fogFar - fogNear) / clamp(Input.Position.y / fogAltitudeScale + 1, 1, fogThinning)); 
        return lerp(C, fogColor, l);     
     


    here:

    //----------------------------------------------------------------------------- 
    // Billboard.fx 
    // 
    // Microsoft Game Technology Group 
    // Copyright (C) Microsoft Corporation. All rights reserved. 
    //----------------------------------------------------------------------------- 
     
     
    // Camera parameters. 
    float4x4 View; 
    float4x4 Projection; 
     
     
    // Lighting parameters. 
    float3 LightDirection; 
    float3 LightColor = 0.8; 
    float3 AmbientColor = 0.4; 
     
     
    // Parameters controlling the wind effect. 
    float3 WindDirection = float3(1, 0, 0); 
    float WindWaveSize = 0.1; 
    float WindRandomness = 1; 
    float WindSpeed = 4; 
    float WindAmount; 
    float WindTime; 
     
     
    // Parameters describing the billboard itself. 
    float BillboardWidth; 
    float BillboardHeight; 
     
    texture Texture; 
     
     
    struct VS_INPUT 
        float3 Position : POSITION0; 
        float3 Normal : NORMAL0; 
        float2 TexCoord : TEXCOORD0; 
        float Random : TEXCOORD1; 
    }; 
     
     
    struct VS_OUTPUT 
        float4 Position : POSITION0; 
        float2 TexCoord : TEXCOORD0; 
        float4 Color : COLOR0; 
    }; 
     
     
    VS_OUTPUT VertexShader(VS_INPUT input) 
        VS_OUTPUT output; 
     
        // Apply a scaling factor to make some of the billboards 
        // shorter and fatter while others are taller and thinner. 
        float squishFactor = 0.75 + abs(input.Random) / 2; 
     
        float width = BillboardWidth * squishFactor; 
        float height = BillboardHeight / squishFactor; 
     
        // Flip half of the billboards from left to right. This gives visual variety 
        // even though we are actually just repeating the same texture over and over. 
        if (input.Random < 0) 
            width = -width; 
     
        // Work out what direction we are viewing the billboard from. 
        float3 viewDirection = View._m02_m12_m22; 
     
        float3 rightVector = normalize(cross(viewDirection, input.Normal)); 
     
        // Calculate the position of this billboard vertex. 
        float3 position = input.Position; 
     
        // Offset to the left or right. 
        position += rightVector * (input.TexCoord.x - 0.5) * width; 
         
        // Offset upward if we are one of the top two vertices. 
        position += input.Normal * (1 - input.TexCoord.y) * height; 
     
        // Work out how this vertex should be affected by the wind effect. 
        float waveOffset = dot(position, WindDirection) * WindWaveSize; 
         
        waveOffset += input.Random * WindRandomness; 
         
        // Wind makes things wave back and forth in a sine wave pattern. 
        float wind = sin(WindTime * WindSpeed + waveOffset) * WindAmount; 
         
        // But it should only affect the top two vertices of the billboard! 
        wind *= (1 - input.TexCoord.y); 
         
        position += WindDirection * wind; 
     
        // Apply the camera transform. 
        float4 viewPosition = mul(float4(position, 1), View); 
     
        output.Position = mul(viewPosition, Projection); 
     
        output.TexCoord = input.TexCoord; 
         
        // Compute lighting. 
        float diffuseLight = max(-dot(input.Normal, LightDirection), 0); 
         
        output.Color.rgb = diffuseLight * LightColor + AmbientColor; 
        output.Color.a = 1; 
         
        return output; 
     
     
    sampler TextureSampler = sampler_state 
        Texture = (Texture); 
     
        MinFilter = Linear; 
        MagFilter = Linear; 
        MipFilter = Linear; 
         
        AddressU = Clamp; 
        AddressV = Clamp; 
    }; 
     
     
    float4 PixelShader(float2 texCoord : TEXCOORD0, float4 color : COLOR0) : COLOR0 
        return tex2D(TextureSampler, texCoord) * color; 
     
     
    technique Billboards 
        // We use a two-pass technique to render alpha blended geometry with almost-correct 
        // depth sorting. The only way to make blending truly proper for alpha objects is 
        // to draw everything in sorted order, but manually sorting all our billboards 
        // would be very expensive. Instead, we draw our billboards in two passes. 
        // 
        // The first pass has alpha blending turned off, alpha testing set to only accept 
        // ~95% or more opaque pixels, and the depth buffer turned on. Because this is only 
        // rendering the solid parts of each billboard, the depth buffer works as 
        // normal to give correct sorting, but obviously only part of each billboard will 
        // be rendered. 
        // 
        // Then in the second pass we enable alpha blending, set alpha test to only accept 
        // pixels with fractional alpha values, and set the depth buffer to test against 
        // the existing data but not to write new depth values. This means the translucent 
        // areas of each billboard will be sorted correctly against the depth buffer 
        // information that was previously written while drawing the opaque parts, although 
        // there can still be sorting errors between the translucent areas of different 
        // billboards. 
        // 
        // In practice, sorting errors between translucent pixels tend not to be too 
        // noticable as long as the opaque pixels are sorted correctly, so this technique 
        // often looks ok, and is much faster than trying to sort everything 100% 
        // correctly. It is particularly effective for organic textures like grass and 
        // trees. 
         
        pass RenderOpaquePixels 
        { 
            VertexShader = compile vs_1_1 VertexShader(); 
            PixelShader = compile ps_1_1 PixelShader(); 
     
            AlphaBlendEnable = false
                     
            AlphaTestEnable = true
            AlphaFunc = Greater; 
            AlphaRef = 245; 
             
            ZEnable = true
            ZWriteEnable = true
     
            CullMode = None; 
        } 
     
        pass RenderAlphaBlendedFringes 
        { 
            VertexShader = compile vs_1_1 VertexShader(); 
            PixelShader = compile ps_1_1 PixelShader(); 
             
            AlphaBlendEnable = true
            SrcBlend = SrcAlpha; 
            DestBlend = InvSrcAlpha; 
             
            AlphaTestEnable = true
            AlphaFunc = LessEqual; 
            AlphaRef = 245; 
     
            ZEnable = true
            ZWriteEnable = false
     
            CullMode = None; 
        } 
     

    Anyone can help me?
    Thanks :)
  • 11/20/2009 12:24 PM In reply to

    Re: XNA Billboard Sample, adding fog to .fx

    PS:

    I try to put it in the PixelShader, but is not the right way, i obtain only that single per single sprite is influenced by the fog, not all the field...

    I think the best way to get it is in a third pass, but i don't find a correct way...
Page 1 of 1 (2 items) Previous Next