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

📄 softparticles.fx

📁 声音和图片的加载功能,不过运行起来有点卡
💻 FX
📖 第 1 页 / 共 2 页
字号:

//
// PS for the particles
//
PSParticleOut PSBillboardParticleDepthmain(PSParticleIn input, uniform bool bSoftParticles )
{   
    PSParticleOut output;
    
    float2 screenTex = 0.5*( (input.ScreenTex) + float2(1,1));
    screenTex.y = 1 - screenTex.y;
    
    float4 particleSample = g_txVolumeDiff.Sample( g_samVolume, input.Tex );
    float3 particleNormal = g_txVolumeNorm.Sample( g_samVolume, input.Tex );
    
    float size = g_fSizeZScale*input.Size;	//move the size into the depth buffer space
    float particleDepth = input.Depth.x - size*2.0*(particleSample.a);	//augment it by the depth stored in the texture
    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;
    
    output.Color = particleSample;
    output.Depth = particleDepth;
    return output;
}

// ray-sphere intersection
#define DIST_BIAS 0.01
bool RaySphereIntersect( float3 rO, float3 rD, float3 sO, float sR, inout float tnear, inout float tfar )
{
    float3 delta = rO - sO;
    
    float A = dot( rD, rD );
    float B = 2*dot( delta, rD );
    float C = dot( delta, delta ) - sR*sR;
    
    float disc = B*B - 4.0*A*C;
    if( disc < DIST_BIAS )
    {
        return false;
    }
    else
    {
        float sqrtDisc = sqrt( disc );
        tnear = (-B - sqrtDisc ) / (2*A);
        tfar = (-B + sqrtDisc ) / (2*A);
        return true;
    }
}

float4 Noise3D( float3 uv, int octaves )
{
    float4 noiseVal = float4(0,0,0,0);
    float4 octaveVal = float4(0,0,0,0);
    float3 uvOffset;
    float freq = 1;
    float pers = 1;

    for( int i=0; i<octaves; i++ )
    {
        uvOffset = uv + g_OctaveOffsets[i].xyz;
        octaveVal = g_txVolumeDiff.SampleLevel( g_samVolume, uvOffset*freq, 0 );
        noiseVal += pers * octaveVal;
        
        freq *= 3.0;
        pers *= 0.5;
    }
    
    noiseVal.a = abs( noiseVal.a );	//turbulence
    
    return noiseVal;
}

//
// PS for the volume particles
//
#define MAX_STEPS 8
float4 PSVolumeParticlemain( PSParticleIn input, uniform bool bSoftParticles ) : SV_Target
{   
    float2 screenTex = 0.5*( (input.ScreenTex) + float2(1,1));
    screenTex.y = 1 - screenTex.y;
    
    float depthSample = g_txDepth.Sample( g_samPoint, screenTex );
    
    float4 depthViewSample = mul( float4( input.ScreenTex, depthSample, 1 ), g_mInvProj );
    float sampleDepth = depthViewSample.z/depthViewSample.w;
    
    // ray sphere intersection
    float3 worldPos = input.worldPos;
    float3 viewRay = g_vViewDir;
    float3 sphereO = input.particleOrig;
    float rad = input.Size;
    float tnear,tfar;
    
    if( !RaySphereIntersect( worldPos, viewRay, sphereO, rad, tnear, tfar ) )
        discard;
        
    float3 worldNear = worldPos + viewRay*tnear;
    float3 worldFar = worldPos + viewRay*tfar;
    float4 viewNear = mul( float4(worldNear,1), g_mWorldView );
    float4 viewFar = mul( float4(worldFar,1), g_mWorldView );
    float currentDepth = viewNear.z/viewNear.w;
    float farDepth = viewFar.z/viewFar.w;
    float lifePower = input.Tex.z;//*input.Tex.z;
    
    float depthDiff = farDepth - sampleDepth;
    if( depthDiff > 0 )	//make sure we don't trace past the depth buffer
    {
        // if we do, adjust tfar accordingly
        tfar -= depthDiff;
        if( tfar < tnear )
            discard;
        worldFar = worldPos + viewRay*tfar;
        farDepth = sampleDepth;
    }
    
    float3 unitTex = (worldNear - sphereO)/(rad);
    float3 localTexNear,localTexFar;
    if(false)
    {
        localTexNear = (worldNear - sphereO)/(rad*2) + float3(0.5,0.5,0.5);
        localTexFar = (worldFar - sphereO)/(rad*2) + float3(0.5,0.5,0.5);
    }
    else
    {
        float fNoiseSizeAdjust = 1 / g_noiseSize;
        localTexNear = worldNear * fNoiseSizeAdjust;
        localTexFar = worldFar * fNoiseSizeAdjust;
    }
    
    // trace through the volume texture
    int iSteps = length(localTexFar - localTexNear)/g_stepSize;
    iSteps = min( iSteps, MAX_STEPS-2 ) + 2;
    float3 currentTex = localTexNear;
    float3 localTexDelta = (localTexFar - localTexNear)/(iSteps-1);
    float depthDelta = (farDepth - currentDepth)/(iSteps-1);
    float opacityAdjust = g_noiseOpacity/(iSteps-1);
    float lightAdjust = 1.0/(iSteps-1);
    
    float runningOpacity = 0;
    float4 runningLight = float4(0,0,0,0);
    for( int i=0; i<iSteps; i++ )
    {
        float4 noiseCell = Noise3D( currentTex, 4 );
        noiseCell.xyz += normalize( unitTex );
        noiseCell.xyz = normalize( noiseCell.xyz );
        
        // fade out near edges
        float depthFade = 1;
        if( bSoftParticles )
        {	
            depthFade = saturate( (sampleDepth-currentDepth) / g_fFadeDistance );
        }
        
        //falloff as well
        float lenSq = dot( unitTex, unitTex );
        float falloff = 1.0 - lenSq;	//1 - len^2 falloff
        
        // calculate our local opacity for this point
        float localOpacity = noiseCell.a*falloff*depthFade;
        
        // add it to our running total
        runningOpacity += localOpacity;
        
        // calc lighting from our gradient map and add it to the running total
        // dot*0.5 + 0.5 basically makes the dot product wrap around
        // giving us more of a volumetric lighting effect
        // Also just use one overhead directional light.  It gives more contrast and looks cooler.
        float4 localLight = g_directional1*saturate( dot( noiseCell.xyz, float3(0,1,0) )*0.5 + 0.5 );	
        
        //for rendering the particle alone
        //float4 localLight = saturate( dot( noiseCell.xyz, float3(0,1,0) )*0.5 + 0.5 );	
                                                                                                     
        runningLight += localLight;
        
        currentTex += localTexDelta;
        unitTex += localTexDelta;
        currentDepth += depthDelta;
    }
    
    float4 col = float4(input.particleColor,1)*(runningLight*lightAdjust)*0.8 + 0.2;// + g_ambient;
    runningOpacity = saturate( runningOpacity*opacityAdjust )*(1-lifePower);// - 0.5*lifePower;
    
    //for rendering the particle alone
    //float4 col = (runningLight*lightAdjust)*0.8 + 0.2;// + g_ambient;
    //col.xyz = runningOpacity.rrr;
    //runningOpacity = 1;
    
    float4 color = float4(col.xyz,runningOpacity);
    return color;
}

//
// RenderScene
//
technique10 RenderScene
{
    pass p0
    {
        SetVertexShader( CompileShader( vs_4_0, VSScenemain() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PSScenemain() ) );
        
        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        SetDepthStencilState( EnableDepth, 0 );
    }  
}

//
// RenderScene
//
technique10 RenderSky
{
    pass p0
    {
        SetVertexShader( CompileShader( vs_4_0, VSScenemain() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PSSkymain() ) );
        
        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        SetDepthStencilState( DisableDepthTest, 0 );
    }  
}

//
// RenderBillboardParticles_Hard
//
technique10 RenderBillboardParticles_Hard
{
    pass p0
    {
        SetVertexShader( CompileShader( vs_4_0, VSParticlemain() ) );
        SetGeometryShader( CompileShader( gs_4_0, GSParticlemain() ) );
        SetPixelShader( CompileShader( ps_4_0, PSBillboardParticlemain(false) ) );
        
        SetBlendState( AlphaBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        SetDepthStencilState( DisableDepthWrite, 0 );
    }  
}

//
// RenderBillboardParticles_ODepth
//
technique10 RenderBillboardParticles_ODepth
{
    pass p0
    {
        SetVertexShader( CompileShader( vs_4_0, VSParticlemain() ) );
        SetGeometryShader( CompileShader( gs_4_0, GSParticlemain() ) );
        SetPixelShader( CompileShader( ps_4_0, PSBillboardParticleDepthmain(false) ) );
        
        SetBlendState( AlphaBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        SetDepthStencilState( DisableDepthWrite, 0 );
    }  
}

//
// RenderBillboardParticles_Soft
//
technique10 RenderBillboardParticles_Soft
{
    pass p0
    {
        SetVertexShader( CompileShader( vs_4_0, VSParticlemain() ) );
        SetGeometryShader( CompileShader( gs_4_0, GSParticlemain() ) );
        SetPixelShader( CompileShader( ps_4_0, PSBillboardParticlemain(true) ) );
        
        SetBlendState( AlphaBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        SetDepthStencilState( DisableDepthWrite, 0 );
    }  
}

//
// RenderBillboardParticles_Soft
//
technique10 RenderBillboardParticles_ODepthSoft
{
    pass p0
    {
        SetVertexShader( CompileShader( vs_4_0, VSParticlemain() ) );
        SetGeometryShader( CompileShader( gs_4_0, GSParticlemain() ) );
        SetPixelShader( CompileShader( ps_4_0, PSBillboardParticleDepthmain(true) ) );
        
        SetBlendState( AlphaBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        SetDepthStencilState( DisableDepth, 0 );
    }  
}

//
// RenderVolumeParticles_Hard
//
technique10 RenderVolumeParticles_Hard
{
    pass p0
    {
        SetVertexShader( CompileShader( vs_4_0, VSParticlemain() ) );
        SetGeometryShader( CompileShader( gs_4_0, GSParticlemain() ) );
        SetPixelShader( CompileShader( ps_4_0, PSVolumeParticlemain(false) ) );
        
        SetBlendState( AlphaBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        SetDepthStencilState( DisableDepth, 0 );
    }  
}

//
// RenderVolumeParticles_Soft
//
technique10 RenderVolumeParticles_Soft
{
    pass p0
    {
        SetVertexShader( CompileShader( vs_4_0, VSParticlemain() ) );
        SetGeometryShader( CompileShader( gs_4_0, GSParticlemain() ) );
        SetPixelShader( CompileShader( ps_4_0, PSVolumeParticlemain(true) ) );
        
        SetBlendState( AlphaBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
        SetDepthStencilState( DisableDepth, 0 );
    }  
}



⌨️ 快捷键说明

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