⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 softparticles.fx

📁 声音和图片的加载功能,不过运行起来有点卡
💻 FX
📖 第 1 页 / 共 2 页
字号:
//--------------------------------------------------------------------------------------
// File: SoftParticles.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------

// structs
struct VSSceneIn
{
    float3 Pos            : POSITION;
    float3 Norm           : NORMAL;  
    float2 Tex            : TEXCOORD;
    float3 Tan            : TANGENT;
};

struct PSSceneIn
{
    float4 Pos			  : SV_POSITION;
    float3 Norm			  : NORMAL;
    float2 Tex			  : TEXCOORD0;
    float3 Tan			  : TEXCOORD1;
    float3 vPos			  : TEXCOORD2;
};

struct VSParticleIn
{
    float3 Pos			  : POSITION;
    float3 Vel			  : VELOCITY;
    float Life			  : LIFE;
    float Size			  : SIZE;
};

struct GSParticleIn
{
    float3 Pos            : POSITION;
    float Life            : LIFE;	//stage of animation we're in [0..1] 0 is first frame, 1 is last
    float Size            : SIZE;
};

struct PSParticleIn
{
    float4 Pos			  : SV_POSITION;
    float3 Tex			  : TEXCOORD0;
    float2 ScreenTex	  : TEXCOORD1;
    float2 Depth		  : TEXCOORD2;
    float  Size			  : TEXCOORD3;
    float3 worldPos		  : TEXCOORD4;
    float3 particleOrig	  : TEXCOORD5;
    float3 particleColor  : TEXCOORD6;
};

cbuffer cbPerObject
{
    matrix g_mWorldViewProj;
    matrix g_mWorldView;
    matrix g_mWorld;
    matrix g_mInvView;
    matrix g_mInvProj;
    float3 g_vViewDir;
};

cbuffer cbUser
{
    float g_fFadeDistance;
    float g_fSizeZScale;
    float4 g_vViewLightDir1;
    float4 g_vViewLightDir2;
    float4 g_vWorldLightDir1;
    float4 g_vWorldLightDir2;
    float4 g_vEyePt;
    
    float g_stepSize = 0.01;
    float g_noiseSize = 40.0;
    float g_noiseOpacity = 20.0;
};

cbuffer cbNoiseOffset
{
    float4 g_OctaveOffsets[4];
};

cbuffer cbImmutable
{
    float3 g_positions[4] =
    {
        float3( -1, 1, 0 ),
        float3( 1, 1, 0 ),
        float3( -1, -1, 0 ),
        float3( 1, -1, 0 ),
    };
    float2 g_texcoords[4] = 
    { 
        float2(0,0), 
        float2(1,0),
        float2(0,1),
        float2(1,1),
    };
    float4 g_directional1 = float4( 0.992, 1.0, 0.880, 0.0 );
    float4 g_directional2 = float4( 0.595, 0.6, 0.528, 0.0 );
    float4 g_ambient = float4(0.525,0.474,0.474,0.0);
};

Texture2D g_txDiffuse;
Texture2D g_txNormal;
Texture2D g_txColorGradient;
Texture3D g_txVolumeDiff;
Texture3D g_txVolumeNorm;
Texture2D g_txDepth;
SamplerState g_samLinearClamp
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Clamp;
    AddressV = Clamp;
};

SamplerState g_samLinearWrap
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

SamplerState g_samPoint
{
    Filter = MIN_MAG_MIP_POINT;
    AddressU = Clamp;
    AddressV = Clamp;
};

SamplerState g_samVolume
{
    Filter = MIN_MAG_LINEAR_MIP_POINT;
    AddressU = Wrap;
    AddressV = Wrap;
    AddressW = Wrap;
};


BlendState AlphaBlending
{
    AlphaToCoverageEnable = FALSE;
    BlendEnable[0] = TRUE;
    SrcBlend = SRC_ALPHA;
    DestBlend = INV_SRC_ALPHA;
    BlendOp = ADD;
    SrcBlendAlpha = ZERO;
    DestBlendAlpha = ZERO;
    BlendOpAlpha = ADD;
    RenderTargetWriteMask[0] = 0x0F;
};

BlendState NoBlending
{
    AlphaToCoverageEnable = FALSE;
    BlendEnable[0] = FALSE;
};

DepthStencilState EnableDepth
{
    DepthEnable = TRUE;
    DepthWriteMask = ALL;
};

DepthStencilState DisableDepth
{
    DepthEnable = FALSE;
    DepthWriteMask = ZERO;
};

DepthStencilState DisableDepthWrite
{
    DepthEnable = TRUE;
    DepthWriteMask = ZERO;
};

DepthStencilState DisableDepthTest
{
    DepthEnable = TRUE;
    DepthWriteMask = ALL;
    DepthFunc = ALWAYS;
};

//
// Vertex shader for drawing the scene
//
PSSceneIn VSScenemain(VSSceneIn input)
{
    PSSceneIn output;
    
    output.vPos = mul( float4(input.Pos,1), g_mWorld );
    output.Pos = mul( float4(input.Pos,1), g_mWorldViewProj );
    output.Norm = normalize( mul( input.Norm, (float3x3)g_mWorld ) );
    output.Tan = normalize( mul( input.Tan, (float3x3)g_mWorld ) );
    output.Tex = input.Tex;
    
    return output;
}

//
// PS for the scene
//
float4 PSScenemain(PSSceneIn input) : SV_Target
{   
    float4 diffuse = g_txDiffuse.Sample( g_samLinearWrap, input.Tex );
    float specMask = diffuse.a;
    float3 norm = g_txNormal.Sample( g_samLinearWrap, input.Tex );
    norm *= 2;
    norm -= float3(1,1,1);
    
    float3 binorm = normalize( cross( input.Norm, input.Tan ) );
    float3x3 BTNMatrix = float3x3( binorm, input.Tan, input.Norm );
    norm = normalize(mul( norm, BTNMatrix ));
    
    // diffuse lighting
    float4 lighting = saturate( dot( norm, g_vWorldLightDir1.xyz ) )*g_directional1;
    lighting += saturate( dot( norm, g_vWorldLightDir2.xyz ) )*g_directional2;
    lighting += g_ambient;
    
    // Calculate specular power
    float3 viewDir = normalize( g_vEyePt - input.vPos );
    float3 halfAngle = normalize( viewDir + g_vWorldLightDir1.xyz );
    float4 specPower1 = saturate( pow( dot( halfAngle, norm ), 32 ) ) * g_directional1;
    
    halfAngle = normalize( viewDir + g_vWorldLightDir2.xyz );
    float4 specPower2 = saturate( pow( dot( halfAngle, norm ), 32 ) ) * g_directional2;
    
    return lighting*diffuse + (specPower1+specPower2)*specMask;
}

//
// PS for the sky
//
float4 PSSkymain(PSSceneIn input) : SV_Target
{   
    return g_txDiffuse.Sample( g_samLinearWrap, input.Tex );
}

//
// Vertex shader for drawing particles
//
GSParticleIn VSParticlemain(VSParticleIn input)
{
    GSParticleIn output;
    
    output.Pos = input.Pos;
    output.Life = input.Life;
    output.Size = input.Size;
    
    return output;
}

//
// Geometry shader for creating point sprites
//
[maxvertexcount(4)]
void GSParticlemain(point GSParticleIn input[1], inout TriangleStream<PSParticleIn> SpriteStream)
{
    PSParticleIn output;
    
    float4 orig = mul( float4(input[0].Pos,1), g_mWorld );
    output.particleOrig = orig.xyz;
    
    if( input[0].Life > -1 )
    {
        // calculate color from a 1d gradient texture
        float3 particleColor = g_txColorGradient.SampleLevel( g_samLinearClamp, float2(input[0].Life,0), 0 );
        output.particleColor = particleColor;
            
        //
        // Emit two new triangles
        //
        [unroll] for(int i=0; i<4; i++)
        {
            float3 position = g_positions[i]*input[0].Size;
            position = mul( position, (float3x3)g_mInvView ) + input[0].Pos;
            output.Pos = mul( float4(position,1.0), g_mWorldViewProj );
            
            // pass along the texcoords
            output.Tex = float3(g_texcoords[i],input[0].Life);
            
            // screenspace coordinates for the lookup into the depth buffer
            output.ScreenTex = output.Pos.xy/output.Pos.w;
            
            // output depth of this particle
            output.Depth = output.Pos.zw;
            
            // size
            output.Size = input[0].Size;
                                    
            // world position
            float4 posWorld = mul( float4(position,1.0), g_mWorld );
            output.worldPos = posWorld;							
            
            SpriteStream.Append(output);
        }
        SpriteStream.RestartStrip();
    }
}

//
// PS for the particles
//
float4 PSBillboardParticlemain(PSParticleIn input, uniform bool bSoftParticles ) : SV_TARGET
{     
    float2 screenTex = 0.5*( (input.ScreenTex) + float2(1,1));
    screenTex.y = 1 - screenTex.y;
    
    float4 particleSample = g_txVolumeDiff.Sample( g_samVolume, input.Tex );
    
    float particleDepth = input.Depth.x;
    particleDepth /= input.Depth.y;
        
    float depthFade = 1;
    if( bSoftParticles )
    {
        // We need to determine the distance between the value stored in the depth buffer
        // and the value that came in from the GS
        // Because the depth values aren't linear, we need to transform the depthsample back into view space
        // in order for the comparison to give us an accurate distance
        float depthSample = g_txDepth.Sample( g_samPoint, screenTex );
        
        float4 depthViewSample = mul( float4( input.ScreenTex, depthSample, 1 ), g_mInvProj );
        float4 depthViewParticle = mul( float4( input.ScreenTex, particleDepth, 1 ), g_mInvProj );
        
        float depthDiff = depthViewSample.z/depthViewSample.w - depthViewParticle.z/depthViewParticle.w;
        if( depthDiff < 0 )
            discard;
            
        depthFade = saturate( depthDiff / g_fFadeDistance );
    }
        
    float4 Light = g_directional1 + g_ambient;
    particleSample.rgb *= Light.xyz*input.particleColor;
    particleSample.a *= depthFade;
    
    return particleSample;
}

struct PSParticleOut
{
    float4 Color : SV_Target;
    float Depth : SV_Depth;
};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -