diff options
Diffstat (limited to 'tests/hlsl/dxsdk/VarianceShadows11')
3 files changed, 668 insertions, 0 deletions
diff --git a/tests/hlsl/dxsdk/VarianceShadows11/2DQuadShaders.hlsl b/tests/hlsl/dxsdk/VarianceShadows11/2DQuadShaders.hlsl new file mode 100644 index 000000000..c4401f010 --- /dev/null +++ b/tests/hlsl/dxsdk/VarianceShadows11/2DQuadShaders.hlsl @@ -0,0 +1,211 @@ +//TEST:COMPARE_HLSL: -target dxbc-assembly -profile vs_4_0 -entry VSMain -profile ps_4_0 -entry PSBlurX -entry PSBlurY +//-------------------------------------------------------------------------------------- +// File: Skinning10.fx +// +// The effect file for the Skinning10 sample. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +#ifndef SEPERABLE_BLUR_KERNEL_SIZE +#define SEPERABLE_BLUR_KERNEL_SIZE 3 +#endif + +static const int BLUR_KERNEL_BEGIN = SEPERABLE_BLUR_KERNEL_SIZE / -2; +static const int BLUR_KERNEL_END = SEPERABLE_BLUR_KERNEL_SIZE / 2 + 1; +static const float FLOAT_BLUR_KERNEL_SIZE = (float)SEPERABLE_BLUR_KERNEL_SIZE; + +cbuffer cbblurVS : register( b2) +{ + int2 g_iWidthHeight : packoffset( c0 ); + int g_iKernelStart : packoffset( c0.z ); + int g_iKernelEnd : packoffset( c0.w ); +}; + +//-------------------------------------------------------------------------------------- +// defines +//-------------------------------------------------------------------------------------- + +Texture2DArray g_txShadow : register( t5 ); +SamplerState g_samShadow : register( s5 ); + +//-------------------------------------------------------------------------------------- +// Input/Output structures +//-------------------------------------------------------------------------------------- + +struct PSIn +{ + float4 Pos : SV_Position; //Position + float2 Tex : TEXCOORD; //Texture coordinate + float2 ITex : TEXCOORD2; +}; + +struct VSIn +{ + uint Pos : SV_VertexID ; +}; + + +PSIn VSMain(VSIn inn) +{ + PSIn output; + + output.Pos.y = -1.0f + (inn.Pos%2) * 2.0f ; + output.Pos.x = -1.0f + (inn.Pos/2) * 2.0f; + output.Pos.z = .5; + output.Pos.w = 1; + output.Tex.x = inn.Pos/2; + output.Tex.y = 1.0f - inn.Pos%2; + output.ITex.x = (float)(g_iWidthHeight.x * output.Tex.x); + output.ITex.y = (float)(g_iWidthHeight.y * output.Tex.y); + return output; +} + +//float PSDepth + +//------------------------------------------------------------------------------ +// Logarithmic filtering +//------------------------------------------------------------------------------ + +float log_conv ( float x0, float X, float y0, float Y ) +{ + return (X + log(x0 + (y0 * exp(Y - X)))); +} + + +//-------------------------------------------------------------------------------------- +// Pixel shader that performs bump mapping on the final vertex +//-------------------------------------------------------------------------------------- +float2 PSBlurX(PSIn input) : SV_Target +{ +/* + float2 centerDistance; + if ( input.Tex.x < .5 ) centerDistance.x = (1.0 - input.Tex.x); + else centerDistance.x = input.Tex.x; + if ( input.Tex.y < .5 ) centerDistance.y = (1.0 - input.Tex.y); + else centerDistance.y = input.Tex.y; + if (centerDistance.x < centerDistance.y) centerDistance.x = centerDistance.y; + centerDistance.x -= .2; + centerDistance.x *= (1.0f / .8); + + float store_samples[8]; + int ind = 0; + for (int x = g_iKernelStart; x < g_iKernelEnd; ++x) { + store_samples[ind] = g_txShadow.Load( int3(input.ITex.x+(float)x * centerDistance.x , input.ITex.y, 0) ).r; + ind++; + } + const float c = (1.f/5.f); + + float accum; + accum = log_conv( c, store_samples[0], c, store_samples[1] ); + + ind = 0; + for (x = g_iKernelStart - 2; x < g_iKernelEnd; ++x) { + ind++; + accum += log_conv( 1.0f, accum, c, store_samples[ind] ); + } + float2 rt; + rt.x = accum; + return rt; + */ + /* + float2 dep = 0; + float2 centerDistance; + if ( input.Tex.x < .5 ) centerDistance.x = (1.0 - input.Tex.x); + else centerDistance.x = input.Tex.x; + if ( input.Tex.y < .5 ) centerDistance.y = (1.0 - input.Tex.y); + else centerDistance.y = input.Tex.y; + if (centerDistance.x < centerDistance.y) centerDistance.x = centerDistance.y; + centerDistance.x -= .2; + centerDistance.x *= ( 1.0f / 0.8f ); + + for (int x = g_iKernelStart; x < g_iKernelEnd; ++x) { + dep += g_txShadow.Load( int3(input.ITex.x+(float)x * centerDistance.x , input.ITex.y, 0) ).rg; + } + dep /= (g_iKernelEnd - g_iKernelStart); + return dep; + */ + + float2 dep=0; + [unroll]for ( int x = BLUR_KERNEL_BEGIN; x < BLUR_KERNEL_END; ++x ) { + dep += g_txShadow.Sample( g_samShadow, float3( input.Tex.x, input.Tex.y, 0 ), int2( x,0 ) ).rg; + } + dep /= FLOAT_BLUR_KERNEL_SIZE; + return dep; + +// return g_txShadow.Sample(g_samShadow, float3(input.Tex.x, input.Tex.y, 0) ).rg; + +} + +//-------------------------------------------------------------------------------------- +// Pixel shader that performs bump mapping on the final vertex +//-------------------------------------------------------------------------------------- +float2 PSBlurY(PSIn input) : SV_Target +{ +/* + float2 centerDistance; + if ( input.Tex.x < .5 ) centerDistance.x = (1.0 - input.Tex.x); + else centerDistance.x = input.Tex.x; + if ( input.Tex.y < .5 ) centerDistance.y = (1.0 - input.Tex.y); + else centerDistance.y = input.Tex.y; + if (centerDistance.x < centerDistance.y) centerDistance.x = centerDistance.y; + centerDistance.x -= .2; + centerDistance.x *= (1.0f / .8); + + float store_samples[8]; + int ind = 0; + for (int y = g_iKernelStart; y < g_iKernelEnd; ++y) { + store_samples[ind] = g_txShadow.Load( int3(input.ITex.x, input.ITex.y+(float)y * centerDistance.x, 0) ).r; + } + const float c = (1.f/5.f); + + float accum; + accum = log_conv( c, store_samples[0], c, store_samples[1] ); + + ind = 0; + for (y = g_iKernelStart; y < g_iKernelEnd; ++y) { + ind++; + accum += log_conv( 1.0f, accum, c, store_samples[ind] ); + } + float2 rt; + rt.x = accum; + return rt; + */ + + + /* + float2 dep = 0; + + float2 centerDistance; + if ( input.Tex.x < .5 ) centerDistance.x = (1.0 - input.Tex.x); + else centerDistance.x = input.Tex.x; + if ( input.Tex.y < .5 ) centerDistance.y = (1.0 - input.Tex.y); + else centerDistance.y = input.Tex.y; + if (centerDistance.x < centerDistance.y) centerDistance.x = centerDistance.y; + centerDistance.x -= 0; + centerDistance.x *= (1.0f / 1.0f); + + if (centerDistance.x < centerDistance.y) centerDistance.x = centerDistance.y; + for (int y = g_iKernelStart; y < g_iKernelEnd; ++y) { + dep += g_txShadow.Load( int3(input.ITex.x, input.ITex.y+(float)y * centerDistance.x, 0) ).rg; + } + + + dep /= (g_iKernelEnd - g_iKernelStart); + return dep; + + */ + + + float2 dep=0; + [unroll]for ( int y = BLUR_KERNEL_BEGIN; y < BLUR_KERNEL_END; ++y ) { + dep += g_txShadow.Sample( g_samShadow, float3( input.Tex.x, input.Tex.y, 0 ), int2( 0,y ) ).rg; + } + dep /= FLOAT_BLUR_KERNEL_SIZE; + return dep; + + //return g_txShadow.Sample(g_samShadow, float3(input.Tex.x, input.Tex.y, 0) ).rg; +} + + + diff --git a/tests/hlsl/dxsdk/VarianceShadows11/RenderVarianceScene.hlsl b/tests/hlsl/dxsdk/VarianceShadows11/RenderVarianceScene.hlsl new file mode 100644 index 000000000..0b2e43b5c --- /dev/null +++ b/tests/hlsl/dxsdk/VarianceShadows11/RenderVarianceScene.hlsl @@ -0,0 +1,412 @@ +//TEST_IGNORE_FILE: Currently failing due to Spire compiler issues. +//TEST:COMPARE_HLSL: -target dxbc-assembly -profile vs_4_0 -entry VSMain -profile ps_4_0 -entry PSBlurX -entry PSBlurY +//-------------------------------------------------------------------------------------- +// File: RenderCascadeScene.hlsl +// +// This is the main shader file. This shader is compiled with several different flags +// to provide different customizations based on user controls. +// +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------- +// Globals +//-------------------------------------------------------------------------------------- + +// This flag enables the shadow to blend between cascades. This is most useful when the +// the shadow maps are small and artifact can be seen between the various cascade layers. +#ifndef BLEND_BETWEEN_CASCADE_LAYERS_FLAG +#define BLEND_BETWEEN_CASCADE_LAYERS_FLAG 0 +#endif + +// There are two methods for selecting the proper cascade a fragment lies in. Interval selection +// compares the depth of the fragment against the frustum's depth partition. +// Map based selection compares the texture coordinates against the acutal cascade maps. +// Map based selection gives better coverage. +// Interval based selection is easier to extend and understand. +#ifndef SELECT_CASCADE_BY_INTERVAL_FLAG +#define SELECT_CASCADE_BY_INTERVAL_FLAG 0 +#endif + +// The number of cascades +#ifndef CASCADE_COUNT_FLAG +#define CASCADE_COUNT_FLAG 3 +#endif + + +// Most titles will find that 3-4 cascades with +// BLEND_BETWEEN_CASCADE_LAYERS_FLAG, is good for lower end PCs. + +cbuffer cbAllShadowData : register( b0 ) +{ + matrix m_mWorldViewProjection; + matrix m_mWorld; + matrix m_mWorldView; + matrix m_mShadow; + float4 m_vCascadeOffset[8]; + float4 m_vCascadeScale[8]; + int m_nCascadeLevels; // Number of Cascades + int m_iVisualizeCascades; // 1 is to visualize the cascades in different colors. 0 is to just draw the scene + + // For Map based selection scheme, this keeps the pixels inside of the the valid range. + // When there is no boarder, these values are 0 and 1 respectivley. + float m_fMinBorderPadding; + float m_fMaxBorderPadding; + + float m_fCascadeBlendArea; // Amount to overlap when blending between cascades. + float m_fTexelSize; // Padding variables exist because CBs must be a multiple of 16 bytes. + float m_fNativeTexelSizeInX; + float4 m_fCascadeFrustumsEyeSpaceDepthsData[2]; // The values along Z that seperate the cascades. + // This code creates an array based pointer that points towards the vectorized input data. + // This is the only way to index arbitrary arrays of data. + // If the array is used at run time, the compiler will generate code that uses logic to index the correct component. + + static float m_fCascadeFrustumsEyeSpaceDepths[8] = (float[8])m_fCascadeFrustumsEyeSpaceDepthsData; + + float3 m_vLightDir; + float m_fPaddingCB4; + +}; + + + +//-------------------------------------------------------------------------------------- +// Textures and Samplers +//-------------------------------------------------------------------------------------- +Texture2D g_txDiffuse : register( t0 ); +Texture2DArray g_txShadow : register( t5 ); + +SamplerState g_samLinear : register( s0 ); +SamplerState g_samShadow : register( s5 ); + +//-------------------------------------------------------------------------------------- +// Input / Output structures +//-------------------------------------------------------------------------------------- +struct VS_INPUT +{ + float4 vPosition : POSITION; + float3 vNormal : NORMAL; + float2 vTexcoord : TEXCOORD0; +}; + +struct VS_OUTPUT +{ + float3 vNormal : NORMAL; + float2 vTexcoord : COLOR0; + float4 vTexShadow : TEXCOORD1; + float4 vPosition : SV_POSITION; + float4 vInterpPos : TEXCOORD2; + float vDepth : TEXCOORD3; +}; + +//-------------------------------------------------------------------------------------- +// Vertex Shader +//-------------------------------------------------------------------------------------- +VS_OUTPUT VSMain( VS_INPUT Input ) +{ + VS_OUTPUT Output; + + Output.vPosition = mul( Input.vPosition, m_mWorldViewProjection ); + Output.vNormal = mul( Input.vNormal, (float3x3)m_mWorld ); + Output.vTexcoord = Input.vTexcoord; + Output.vInterpPos = Input.vPosition; + Output.vDepth = mul( Input.vPosition, m_mWorldView ).z ; + + // Transform the shadow texture coordinates for all the cascades. + Output.vTexShadow = mul( Input.vPosition, m_mShadow ); + + return Output; +} + + + +static const float4 vCascadeColorsMultiplier[8] = +{ + float4 ( 1.5f, 0.0f, 0.0f, 1.0f ), + float4 ( 0.0f, 1.5f, 0.0f, 1.0f ), + float4 ( 0.0f, 0.0f, 5.5f, 1.0f ), + float4 ( 1.5f, 0.0f, 5.5f, 1.0f ), + float4 ( 1.5f, 1.5f, 0.0f, 1.0f ), + float4 ( 1.0f, 1.0f, 1.0f, 1.0f ), + float4 ( 0.0f, 1.0f, 5.5f, 1.0f ), + float4 ( 0.5f, 3.5f, 0.75f, 1.0f ) +}; + + +void ComputeCoordinatesTransform( in int iCascadeIndex, + in float4 InterpolatedPosition, + in out float4 vShadowTexCoord, + in out float4 vShadowTexCoordViewSpace ) +{ + // Now that we know the correct map, we can transform the world space position of the current fragment + if( SELECT_CASCADE_BY_INTERVAL_FLAG ) + { + vShadowTexCoord = vShadowTexCoordViewSpace * m_vCascadeScale[iCascadeIndex]; + vShadowTexCoord += m_vCascadeOffset[iCascadeIndex]; + } + vShadowTexCoord.w = vShadowTexCoord.z; // We put the z value in w so that we can index the texture array with Z. + vShadowTexCoord.z = iCascadeIndex; + +} + +//-------------------------------------------------------------------------------------- +// Use PCF to sample the depth map and return a percent lit value. +//-------------------------------------------------------------------------------------- +void CalculateVarianceShadow ( in float4 vShadowTexCoord, in float4 vShadowMapTextureCoordViewSpace, int iCascade, out float fPercentLit ) +{ + fPercentLit = 0.0f; + // This loop could be unrolled, and texture immediate offsets could be used if the kernel size were fixed. + // This would be a performance improvment. + + float2 mapDepth = 0; + + + // In orderto pull the derivative out of divergent flow control we calculate the + // derivative off of the view space coordinates an then scale the deriviative. + + float3 vShadowTexCoordDDX = + ddx(vShadowMapTextureCoordViewSpace ); + vShadowTexCoordDDX *= m_vCascadeScale[iCascade].xyz; + float3 vShadowTexCoordDDY = + ddy(vShadowMapTextureCoordViewSpace ); + vShadowTexCoordDDY *= m_vCascadeScale[iCascade].xyz; + + mapDepth += g_txShadow.SampleGrad( g_samShadow, vShadowTexCoord.xyz, + vShadowTexCoordDDX, + vShadowTexCoordDDY); + // The sample instruction uses gradients for some filters. + + float fAvgZ = mapDepth.x; // Filtered z + float fAvgZ2 = mapDepth.y; // Filtered z-squared + + if ( vShadowTexCoord.w <= fAvgZ ) // We put the z value in w so that we can index the texture array with Z. + { + fPercentLit = 1; + } + else + { + float variance = ( fAvgZ2 ) - ( fAvgZ * fAvgZ ); + variance = min( 1.0f, max( 0.0f, variance + 0.00001f ) ); + + float mean = fAvgZ; + float d = vShadowTexCoord.w - mean; // We put the z value in w so that we can index the texture array with Z. + float p_max = variance / ( variance + d*d ); + + // To combat light-bleeding, experiment with raising p_max to some power + // (Try values from 0.1 to 100.0, if you like.) + fPercentLit = pow( p_max, 4 ); + + } + +} + +//-------------------------------------------------------------------------------------- +// Calculate amount to blend between two cascades and the band where blending will occure. +//-------------------------------------------------------------------------------------- +void CalculateBlendAmountForInterval ( in int iNextCascadeIndex, + in out float fPixelDepth, + in out float fCurrentPixelsBlendBandLocation, + out float fBlendBetweenCascadesAmount + ) +{ + + // We need to calculate the band of the current shadow map where it will fade into the next cascade. + // We can then early out of the expensive PCF for loop. + // + float fBlendInterval = m_fCascadeFrustumsEyeSpaceDepths[ iNextCascadeIndex - 1 ]; + if( iNextCascadeIndex > 1 ) + { + fPixelDepth -= m_fCascadeFrustumsEyeSpaceDepths[ iNextCascadeIndex-2 ]; + fBlendInterval -= m_fCascadeFrustumsEyeSpaceDepths[ iNextCascadeIndex-2 ]; + } + // The current pixel's blend band location will be used to determine when we need to blend and by how much. + fCurrentPixelsBlendBandLocation = fPixelDepth / fBlendInterval; + fCurrentPixelsBlendBandLocation = 1.0f - fCurrentPixelsBlendBandLocation; + // The fBlendBetweenCascadesAmount is our location in the blend band. + fBlendBetweenCascadesAmount = fCurrentPixelsBlendBandLocation / m_fCascadeBlendArea; +} + + +//-------------------------------------------------------------------------------------- +// Calculate amount to blend between two cascades and the band where blending will occure. +//-------------------------------------------------------------------------------------- +void CalculateBlendAmountForMap ( in float4 vShadowMapTextureCoord, + in out float fCurrentPixelsBlendBandLocation, + out float fBlendBetweenCascadesAmount ) +{ + // Calcaulte the blend band for the map based selection. + float2 distanceToOne = float2 ( 1.0f - vShadowMapTextureCoord.x, 1.0f - vShadowMapTextureCoord.y ); + fCurrentPixelsBlendBandLocation = min( vShadowMapTextureCoord.x, vShadowMapTextureCoord.y ); + float fCurrentPixelsBlendBandLocation2 = min( distanceToOne.x, distanceToOne.y ); + fCurrentPixelsBlendBandLocation = + min( fCurrentPixelsBlendBandLocation, fCurrentPixelsBlendBandLocation2 ); + fBlendBetweenCascadesAmount = fCurrentPixelsBlendBandLocation / m_fCascadeBlendArea; +} + +//-------------------------------------------------------------------------------------- +// Calculate the shadow based on several options and rende the scene. +//-------------------------------------------------------------------------------------- + +float4 PSMain( VS_OUTPUT Input ) : SV_TARGET +{ + float4 vDiffuse = g_txDiffuse.Sample( g_samLinear, Input.vTexcoord ); + + + float4 vShadowMapTextureCoordViewSpace = 0.0f; + float4 vShadowMapTextureCoord = 0.0f; + float4 vShadowMapTextureCoord_blend = 0.0f; + + float4 vVisualizeCascadeColor = float4(0.0f,0.0f,0.0f,1.0f); + + float fPercentLit = 0.0f; + float fPercentLit_blend = 0.0f; + + int iCascadeFound = 0; + int iCurrentCascadeIndex=1; + int iNextCascadeIndex = 0; + + float fCurrentPixelDepth; + + // The interval based selection technique compares the pixel's depth against the frustum's cascade divisions. + fCurrentPixelDepth = Input.vDepth; + + // This for loop is not necessary when the frustum is uniformaly divided and interval based selection is used. + // In this case fCurrentPixelDepth could be used as an array lookup into the correct frustum. + vShadowMapTextureCoordViewSpace = Input.vTexShadow; + + + if( SELECT_CASCADE_BY_INTERVAL_FLAG ) + { + iCurrentCascadeIndex = 0; + if (CASCADE_COUNT_FLAG > 1 ) + { + float4 vCurrentPixelDepth = Input.vDepth; + float4 fComparison = ( vCurrentPixelDepth > m_fCascadeFrustumsEyeSpaceDepthsData[0]); + float4 fComparison2 = ( vCurrentPixelDepth > m_fCascadeFrustumsEyeSpaceDepthsData[1]); + float fIndex = dot( + float4( CASCADE_COUNT_FLAG > 0, + CASCADE_COUNT_FLAG > 1, + CASCADE_COUNT_FLAG > 2, + CASCADE_COUNT_FLAG > 3) + , fComparison ) + + dot( + float4( + CASCADE_COUNT_FLAG > 4, + CASCADE_COUNT_FLAG > 5, + CASCADE_COUNT_FLAG > 6, + CASCADE_COUNT_FLAG > 7) + , fComparison2 ) ; + + fIndex = min( fIndex, CASCADE_COUNT_FLAG - 1 ); + iCurrentCascadeIndex = (int)fIndex; + } + } + + if ( !SELECT_CASCADE_BY_INTERVAL_FLAG ) + { + iCurrentCascadeIndex = 0; + if ( CASCADE_COUNT_FLAG == 1 ) + { + vShadowMapTextureCoord = vShadowMapTextureCoordViewSpace * m_vCascadeScale[0]; + vShadowMapTextureCoord += m_vCascadeOffset[0]; + } + if ( CASCADE_COUNT_FLAG > 1 ) { + for( int iCascadeIndex = 0; iCascadeIndex < CASCADE_COUNT_FLAG && iCascadeFound == 0; ++iCascadeIndex ) + { + vShadowMapTextureCoord = vShadowMapTextureCoordViewSpace * m_vCascadeScale[iCascadeIndex]; + vShadowMapTextureCoord += m_vCascadeOffset[iCascadeIndex]; + + if ( min( vShadowMapTextureCoord.x, vShadowMapTextureCoord.y ) > m_fMinBorderPadding + && max( vShadowMapTextureCoord.x, vShadowMapTextureCoord.y ) < m_fMaxBorderPadding ) + { + iCurrentCascadeIndex = iCascadeIndex; + iCascadeFound = 1; + } + } + } + } + // Found the correct map. + vVisualizeCascadeColor = vCascadeColorsMultiplier[iCurrentCascadeIndex]; + + ComputeCoordinatesTransform( iCurrentCascadeIndex, Input.vInterpPos, vShadowMapTextureCoord, vShadowMapTextureCoordViewSpace ); + + if( BLEND_BETWEEN_CASCADE_LAYERS_FLAG && CASCADE_COUNT_FLAG > 1 ) + { + // Repeat text coord calculations for the next cascade. + // The next cascade index is used for blurring between maps. + iNextCascadeIndex = min ( CASCADE_COUNT_FLAG - 1, iCurrentCascadeIndex + 1 ); + if( !SELECT_CASCADE_BY_INTERVAL_FLAG ) + { + vShadowMapTextureCoord_blend = vShadowMapTextureCoordViewSpace * m_vCascadeScale[iNextCascadeIndex]; + vShadowMapTextureCoord_blend += m_vCascadeOffset[iNextCascadeIndex]; + } + ComputeCoordinatesTransform( iNextCascadeIndex, Input.vInterpPos, vShadowMapTextureCoord_blend, vShadowMapTextureCoordViewSpace ); + } + float fBlendBetweenCascadesAmount = 1.0f; + float fCurrentPixelsBlendBandLocation = 1.0f; + + if( SELECT_CASCADE_BY_INTERVAL_FLAG ) + { + if( CASCADE_COUNT_FLAG > 1 && BLEND_BETWEEN_CASCADE_LAYERS_FLAG ) + { + CalculateBlendAmountForInterval ( iNextCascadeIndex, fCurrentPixelDepth, + fCurrentPixelsBlendBandLocation, fBlendBetweenCascadesAmount ); + + } + } + else + { + if( CASCADE_COUNT_FLAG > 1 && BLEND_BETWEEN_CASCADE_LAYERS_FLAG ) + { + CalculateBlendAmountForMap ( vShadowMapTextureCoord, + fCurrentPixelsBlendBandLocation, fBlendBetweenCascadesAmount ); + } + } + + // Because the Z coordinate specifies the texture array, + // the derivative will be 0 when there is no divergence + //float fDivergence = abs( ddy( vShadowMapTextureCoord.z ) ) + abs( ddx( vShadowMapTextureCoord.z ) ); + CalculateVarianceShadow ( vShadowMapTextureCoord, vShadowMapTextureCoordViewSpace, + iCurrentCascadeIndex, fPercentLit); + + // We repeat the calcuation for the next cascade layer, when blending between maps. + if( BLEND_BETWEEN_CASCADE_LAYERS_FLAG && CASCADE_COUNT_FLAG > 1 ) + { + if( fCurrentPixelsBlendBandLocation < m_fCascadeBlendArea ) + { // the current pixel is within the blend band. + + // Because the Z coordinate species the texture array, + // the derivative will be 0 when there is no divergence + float fDivergence = abs( ddy( vShadowMapTextureCoord_blend.z ) ) + + abs( ddx( vShadowMapTextureCoord_blend.z) ); + CalculateVarianceShadow ( vShadowMapTextureCoord_blend, vShadowMapTextureCoordViewSpace, + iNextCascadeIndex, fPercentLit_blend ); + + // Blend the two calculated shadows by the blend amount. + fPercentLit = lerp( fPercentLit_blend, fPercentLit, fBlendBetweenCascadesAmount ); + + } + } + + if( !m_iVisualizeCascades ) vVisualizeCascadeColor = float4( 1.0f, 1.0f, 1.0f, 1.0f ); + + float3 vLightDir1 = float3( -1.0f, 1.0f, -1.0f ); + float3 vLightDir2 = float3( 1.0f, 1.0f, -1.0f ); + float3 vLightDir3 = float3( 0.0f, -1.0f, 0.0f ); + float3 vLightDir4 = float3( 1.0f, 1.0f, 1.0f ); + // Some ambient-like lighting. + float fLighting = + saturate( dot( vLightDir1 , Input.vNormal ) )*0.05f + + saturate( dot( vLightDir2 , Input.vNormal ) )*0.05f + + saturate( dot( vLightDir3 , Input.vNormal ) )*0.05f + + saturate( dot( vLightDir4 , Input.vNormal ) )*0.05f ; + + float4 vShadowLighting = fLighting * 0.5f; + fLighting += saturate( dot( m_vLightDir , Input.vNormal ) ); + fLighting = lerp( vShadowLighting, fLighting, fPercentLit ); + + return fLighting * vVisualizeCascadeColor * vDiffuse; + +} + diff --git a/tests/hlsl/dxsdk/VarianceShadows11/RenderVarianceShadow.hlsl b/tests/hlsl/dxsdk/VarianceShadows11/RenderVarianceShadow.hlsl new file mode 100644 index 000000000..9837bf299 --- /dev/null +++ b/tests/hlsl/dxsdk/VarianceShadows11/RenderVarianceShadow.hlsl @@ -0,0 +1,45 @@ +//TEST:COMPARE_HLSL: -target dxbc-assembly -profile vs_4_0 -entry VSMain -profile ps_4_0 -entry PSMain + + +//-------------------------------------------------------------------------------------- +// Globals +//-------------------------------------------------------------------------------------- +cbuffer cbPerObject : register( b0 ) +{ + matrix g_mWorldViewProjection : packoffset( c0 ); +}; + +//-------------------------------------------------------------------------------------- +// Input / Output structures +//-------------------------------------------------------------------------------------- +struct VS_INPUT +{ + float4 vPosition : POSITION; +}; + +struct VS_OUTPUT +{ + float4 vPosition : SV_POSITION; +}; + +//-------------------------------------------------------------------------------------- +// Vertex Shader +//-------------------------------------------------------------------------------------- +VS_OUTPUT VSMain( VS_INPUT Input ) +{ + VS_OUTPUT Output; + + + Output.vPosition = mul( Input.vPosition, g_mWorldViewProjection ); + + return Output; +} + + +float2 PSMain (VS_OUTPUT Input) : SV_TARGET +{ + float2 rt; + rt.x = Input.vPosition.z; + rt.y = rt.x * rt.x; + return rt; +}
\ No newline at end of file |
