Szerző Téma: [MTA][SHADER][HELP] - Dinamikus Fények, árnyékok  (Megtekintve 527 alkalommal)

[MTA][SHADER][HELP] - Dinamikus Fények, árnyékok
« Dátum: 2016. november 24. - 14:30:54 »
0 Show voters
Üdv. Pár napja kezdtem el shaderekkel foglalkozni, nem egy nehéz téma, viszonylag könnyen meg tudtam érteni. Egy dinamikus megvilágítás shaderen dolgozok, ami árnyékokat is vet. Ambient, és Diffuse Light megvan, tökéletesen kezeli az MTA, bugok nélkül. Az alpha textúrákat is megvilágítja rendesen, eddig oké.
A shadert a microsoft oldalról szedtem, eredetileg XNA-hoz íródott, de sikerült átkonfigurálnom MTA-hoz. Benne van az ambient light, a diffuse light, és a shadow map is, egy gond van: Nem generál árnyékot, pedig kéne. Vannak olyan paraméterek a shaderben amiket nem tudtam átvinni mta-helper.fx-ből, mert nincsenek benne, de elvileg azokat nem is abból kéne kiszámolnia. Előre is köszi a segítséget. A .fx fájl tartalma:
 
#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();
}
}

 

SimplePortal 2.3.7 © 2008-2024, SimplePortal