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

Spotlight fall off

Last post 6/29/2009 8:47 PM by legalize. 1 replies.
  • 6/10/2009 12:15 AM

    Spotlight fall off

    Hi Everyone,

    I am new into HLSL and trying to build a good SpotLight using deferred shading. I went through Catalin Zima's tutorial (http://www.catalinzima.com/?page_id=55) and was able to get spotlight working. However, I do not like the idea of just plotting a circle on the ground. Also, the spotlight is pretty much view angle dependent which aint very true about the spotlights.

    I would like to have an effect like the one below:


    However, I am not sure how should I go ahead with lighting the air to make a shape like the one above. Any suggestions?

    My FX Code:
    float4x4 World; 
    float4x4 View; 
    float4x4 Projection; 
     
    //color of the light  
    float3 Color;  
     
    //position of the camera, for specular light 
    float3 cameraPosition;  
     
    //this is used to compute the world-position 
    float4x4 InvertViewProjection;  
     
    //this is the position of the light 
    float3 lightPosition; 
     
    //how far does this light reach 
    float lightRadius; 
     
    //control the brightness of the light 
    float lightIntensity = 1.0f; 
     
    //controls the view angle  
    float lightAngleCosine = 45; 
     
    //specify direction of spotlight 
    float3 lightDirection; 
     
    // diffuse color, and specularIntensity in the alpha channel 
    texture colorMap;  
    // normals, and specularPower in the alpha channel 
    texture normalMap; 
    //depth 
    texture depthMap; 
     
    sampler colorSampler = sampler_state 
        Texture = (colorMap); 
        AddressU = CLAMP; 
        AddressV = CLAMP; 
        MagFilter = LINEAR; 
        MinFilter = LINEAR; 
        Mipfilter = LINEAR; 
    }; 
    sampler depthSampler = sampler_state 
        Texture = (depthMap); 
        AddressU = CLAMP; 
        AddressV = CLAMP; 
        MagFilter = POINT; 
        MinFilter = POINT; 
        Mipfilter = POINT; 
    }; 
    sampler normalSampler = sampler_state 
        Texture = (normalMap); 
        AddressU = CLAMP; 
        AddressV = CLAMP; 
        MagFilter = POINT; 
        MinFilter = POINT; 
        Mipfilter = POINT; 
    }; 
     
     
    struct VertexShaderInput 
        float3 Position : POSITION0; 
    }; 
     
    struct VertexShaderOutput 
        float4 Position : POSITION0; 
        float4 ScreenPosition : TEXCOORD0; 
    }; 
     
    VertexShaderOutput VertexShaderFunction(VertexShaderInput input) 
        VertexShaderOutput output; 
        //processing geometry coordinates 
        float4 worldPosition = mul(float4(input.Position,1), World); 
        float4 viewPosition = mul(worldPosition, View); 
        output.Position = mul(viewPosition, Projection); 
        output.ScreenPosition = output.Position; 
        return output; 
     
    float2 halfPixel; 
    float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 
    {     
        input.ScreenPosition.xy /= input.ScreenPosition.w; 
     
        float2 texCoord = 0.5f * (float2(input.ScreenPosition.x,-input.ScreenPosition.y) + 1); 
        texCoord -=halfPixel; 
         
        float4 normalData = tex2D(normalSampler,texCoord); 
        float3 normal = 2.0f * normalData.xyz - 1.0f; 
      
        float specularPower = normalData.a * 255; 
        float specularIntensity = tex2D(colorSampler, texCoord).a; 
     
        float depthVal = tex2D(depthSampler,texCoord).r;     
     
        //compute screen-space position 
        float4 position; 
        position.xy = input.ScreenPosition.xy; 
        position.z = depthVal; 
        position.w = 1.0f; 
       
        //transform to world space 
        position = mul(position, InvertViewProjection); 
        position /= position.w; 
       
         
        float3 lightVector = lightPosition - position; 
        float attenuation = saturate(1.0f - length(lightVector)/lightRadius);  
        lightVector = normalize(lightVector);      
        float dotCos = dot(lightDirection, -lightVector); 
         
        if(dotCos > lightAngleCosine) 
        { 
            float spotIntensity =  pow(dotCos,2); 
             
            float NdL = max(0,dot(normal,lightVector)); 
            float3 diffuseLight = NdL * Color.rgb; 
     
            float3 reflectionVector = normalize(reflect(-lightVector, normal)); 
            float3 directionToCamera = normalize(cameraPosition - position); 
            float specularLight = specularIntensity * pow( saturate(dot(reflectionVector, directionToCamera)), specularPower); 
     
            attenuation *= spotIntensity; 
            return attenuation * lightIntensity * float4(diffuseLight.rgb,specularLight); 
        } 
        else 
        { 
            return float4(0,0,0,0); 
        }   
        return float4(0,0,0,0); 
     
    technique Technique1 
        pass Pass1 
        { 
            VertexShader = compile vs_2_0 VertexShaderFunction(); 
            PixelShader = compile ps_2_0 PixelShaderFunction(); 
        } 
     
  • 6/29/2009 8:47 PM In reply to

    Re: Spotlight fall off

    ShutterBug:
    Hi Everyone,

    I am new into HLSL and trying to build a good SpotLight using deferred shading. I went through Catalin Zima's tutorial (http://www.catalinzima.com/?page_id=55) and was able to get spotlight working. However, I do not like the idea of just plotting a circle on the ground. Also, the spotlight is pretty much view angle dependent which aint very true about the spotlights.

    I would like to have an effect like the one below:


    However, I am not sure how should I go ahead with lighting the air to make a shape like the one above. Any suggestions?


    What you're asking for is volumetric lighting and is independent of whether its a spot light, point light, etc.  You're asking for interaction between the atmosphere and the light.  In the image you posted, the interaction is most visible near the light because that is where the light is most concentrated within the volume of atmosphere affected by the light.

    You can find shaders for atmospheric lighting if you google around.  A cheap way to fake it is to simply put a "fin" of geometry in front of the light that fakes this effect.
Page 1 of 1 (2 items) Previous Next