Jump to content

[HELP] MTA:SA Diffuse Lighting Shader


Grozz

Recommended Posts

Posted

Hi! I just searched for lighting effects, and i found a shader for XNA. Its an Ambient and Diffuse lighting shader with Shadow Maps:

#define GENERATE_NORMALS
#include "mta-helper.fx"
//------------------------------------------------------------------------------
// File: BasicRender.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
// Global variables
//------------------------------------------------------------------------------
float4 g_MaterialAmbientColor = {0.05f, 0.05f, 0.05f, 0.05f};      // Material's ambient color
float4 g_MaterialDiffuseColor = {0.75f, 0.75f, 0.75f, 0.75f};      // Material's diffuse color

float3 g_LightPos = {1000, 2000, 1000};					// Position of light
float3 g_LightDir = {0, 0, 0};					// Direction of light (temp)
float4x4 g_mLightView;				// View matrix of light
float4x4 g_mLightProj;				// Projection matrix of light

float4 g_LightDiffuse = {0.75f, 0.75f, 0.75f, 0.75f};			// Light's diffuse color
float4 g_LightAmbient = {0.05f, 0.05f, 0.05f, 0.05f};             // Light's ambient color

texture g_MeshTexture;              // Color texture for mesh
texture g_ShadowMapTexture;			// Shadow map texture for lighting

float4x4 g_mWorld;                  // World matrix for object
float3 g_CameraPos;				    // Camera position for scene View 
float4x4 g_mCameraView;				// Camera's view matrix
float4x4 g_mCameraProj;				// Projection matrix


//------------------------------------------------------------------------------
// Texture samplers
//------------------------------------------------------------------------------
sampler MeshTextureSampler = 
sampler_state
{
    Texture = (gTexture0);
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};
sampler ShadowMapSampler =
sampler_state
{
	Texture = <g_ShadowMapTexture>;
    MinFilter = POINT;
    MagFilter = POINT;
    MipFilter = POINT;
    AddressU = Clamp;
    AddressV = Clamp;
};

//------------------------------------------------------------------------------
// Vertex shader output structure
//------------------------------------------------------------------------------
struct VS_OUTPUT
{
    float4 Position   : POSITION0;   // vertex position 
    float2 TextureUV  : TEXCOORD0;  // vertex texture coords   
    float3 vNormal	  : TEXCOORD1;
    float4 vPos       : TEXCOORD2;  
};
struct PS_INPUT
{
    float2 TextureUV  : TEXCOORD0;  // vertex texture coords   
    float3 vNormal	  : TEXCOORD1;
    float4 vPos       : TEXCOORD2;  
};
struct VS_SHADOW_OUTPUT
{
	float4 Position : POSITION;
	float Depth : TEXCOORD0;
};
//------------------------------------------------------------------------------
// Utility function(s)
//------------------------------------------------------------------------------
float4x4 CreateLookAt(float3 gView, float3 gProjection, float3 up)
{
	float3 zaxis = normalize(gView - gProjection);
	float3 xaxis = normalize(cross(up, zaxis));
	float3 yaxis = cross(zaxis, xaxis);
	
	float4x4 view = { xaxis.x, yaxis.x, zaxis.x, 0,
		xaxis.y, yaxis.y, zaxis.y, 0,
		xaxis.z, yaxis.z, zaxis.z, 0,
		-dot(xaxis, gView), -dot(yaxis, gView),
		-dot(zaxis, gView), 1
	};

	return view;
}
float4 GetPositionFromLight(float4 position)
{
	float4x4 WorldViewProjection =
	 mul(mul(gWorld, gLightDiffuse), gLightDirection);
	return mul(position, WorldViewProjection);  
}
//------------------------------------------------------------------------------
// This shader computes rudimentary transform and lighting.
// The XNA VertexDeclaration of our models is PositionNormalTexture.
//------------------------------------------------------------------------------

VS_OUTPUT RenderShadowsVS(
     float3 position : POSITION,
     float3 normal : NORMAL,
     float2 vTexCoord0 : TEXCOORD0 )
{
     VS_OUTPUT Output;

     //generate the world-view-projection matrix
     float4x4 wvp = mul(mul(gWorld, gView), gProjection);
     
     //transform the input position to the output
     Output.Position = mul(float4(position, 1.0), wvp);

	 //transform the normal to world space
     Output.vNormal =  mul(normal, gWorld);
     
     //do not transform the position needed for the
     //shadow map determination
     Output.vPos = float4(position,1.0);
     
     //pass the texture coordinate as-is
	 Output.TextureUV = vTexCoord0;
    
     //return the output structure
     return Output;
}

VS_SHADOW_OUTPUT RenderShadowMapVS(float4 vPos: POSITION)
{
	VS_SHADOW_OUTPUT Out;
	Out.Position = GetPositionFromLight(vPos); 
	// Depth is Z/W.  This is returned by the pixel shader.
	// Subtracting from 1 gives us more precision in floating point.
	Out.Depth.x = 1-(Out.Position.z/Out.Position.w);	
	return Out;
}

//------------------------------------------------------------------------------
// Pixel shader output structure
//------------------------------------------------------------------------------
struct PS_OUTPUT
{
    float4 RGBColor : COLOR0;  // Pixel color    
};


//------------------------------------------------------------------------------
// This shader outputs the pixel's color by modulating the texture's
//       color with diffuse material color
//------------------------------------------------------------------------------

PS_OUTPUT RenderShadowsPS( PS_INPUT In ) 
{ 
    PS_OUTPUT Output;
    
    // Standard lighting equation
    float4 vTotalLightDiffuse = float4(0.1f,0.1f,0.1f,0.1f);
    float3 lightDir = normalize(g_LightPos+In.vPos);  // direction of light
    vTotalLightDiffuse += g_LightDiffuse * max(0,dot(In.vNormal, lightDir)); 
    vTotalLightDiffuse.a = 0.5f;
	// Now, consult the ShadowMap to see if we're in shadow
    float4 lightingPosition 
		= GetPositionFromLight(In.vPos);// Get our position on the shadow map
   
    // Get the shadow map depth value for this pixel   
    float2 ShadowTexC = 
		0.5 * lightingPosition.xy / lightingPosition.w + float2( 0.5, 0.5 );
    ShadowTexC.y = 1.0f - ShadowTexC.y;

    float shadowdepth = tex2D(ShadowMapSampler, ShadowTexC).r;    
    
    // Check our value against the depth value
    float ourdepth = 1 + (lightingPosition.z / lightingPosition.w);
    
    // Check the shadowdepth against the depth of this pixel
    // a fudge factor is added to account for floating-point error
	if (shadowdepth-0.03 > ourdepth)
	{
	    // we're in shadow, cut the light
		vTotalLightDiffuse = float4(0,0,0,1);
	};

    Output.RGBColor = tex2D(MeshTextureSampler, In.TextureUV) * 
		(vTotalLightDiffuse + g_LightAmbient);
        
    return Output;
    
}
PS_OUTPUT DiffuseOnlyPS(VS_OUTPUT In) : COLOR
{
	 PS_OUTPUT Output;
     //calculate per-pixel diffuse
     float3 directionToLight = normalize(g_LightPos - In.vPos);
     float diffuseIntensity = saturate( dot(directionToLight, In.vNormal));
     float4 diffuse = g_LightDiffuse * diffuseIntensity;
     
     float4 color = diffuse + g_LightAmbient;
     color.a = 0.0;
     
     Output.RGBColor = tex2D(MeshTextureSampler, In.TextureUV) * color;
     
     return Output;
}
PS_OUTPUT TextureOnlyPS(float2 TextureUV  : TEXCOORD0) : COLOR
{
     PS_OUTPUT Output;
     Output.RGBColor = tex2D(MeshTextureSampler, TextureUV);
     
     return Output;
}
float4 RenderShadowMapPS( VS_SHADOW_OUTPUT In ) : COLOR
{ 
	// The depth is Z divided by W. We return
	// this value entirely in a 32-bit red channel
	// using SurfaceFormat.Single.  This preserves the
	// floating-point data for finer detail.
    return float4(In.Depth.x,0,0,1);
}
//------------------------------------------------------------------------------
// Renders scene to render target
//------------------------------------------------------------------------------
technique TextureRender
{
	pass P0
	{
        VertexShader = compile vs_2_0 RenderShadowsVS();
        PixelShader  = compile ps_2_0 TextureOnlyPS(); 
		
	}
	pass P1
	{
        VertexShader = compile vs_2_0 RenderShadowsVS();
        PixelShader  = compile ps_2_0 RenderShadowsPS(); 
	}
	pass P2
	{
		// These render states are necessary to get a shadow map.
		// You should consider resetting CullMode and AlphaBlendEnable
		// before you render your main scene.	
		CullMode = CW;
		ZEnable = TRUE;
		ZWriteEnable = TRUE;
		AlphaBlendEnable = TRUE;
		
        VertexShader = compile vs_2_0 RenderShadowMapVS();
        PixelShader  = compile ps_2_0 RenderShadowMapPS();
	
	}
}

This is not the original .fx file, i configured it for MTA. The diffuse and the ambient light works correctly, but not generating shadows. Any Idea?

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...