Skip to main content
gamedev.net
🔒 Locked 🤖 Godot

Soft Shadow PCSS

Started by royteusink 0 replies 5.8k views
Original Post
royteusink
royteusink
Hi all, I have changed some things in de NVIDIA ShaderLibrary Shadow PCSS code, well it gives me right now a much cleaner softshadows but there is one thing i can't get to work. I want that my models have the texture of there own and not the shader defined texture, my question is what i'm i doing wrong and how can i fix this problem? Thx Fire2Burn Code I added (now it's like a weird mirror or something)

DECLARE_QUAD_TEX(SceneMap,SceneSampler,"A8R8G8B8")
DECLARE_QUAD_DEPTH_BUFFER(DepthBuffer,"D24S8")
float4 OldTex;

"RenderColorTarget0=SceneMap;"
       		   "RenderDepthStencilTarget=DepthBuffer;"
       		   "ClearSetColor=ClearColor;"
	        	"ClearSetDepth=ClearDepth;"
				"Clear=Color;"
				"Clear=Depth;"
	           	"ScriptExternal=color;"

half4 OldTex = tex2D(SceneSampler, IN.UV );


Full Source:
/*********************************************************************NVMH3****
$Id: //sw/devtools/ShaderLibrary/main/HLSL/shadow_PCSS.fx#1 $

Copyright NVIDIA Corporation 2005-2007
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER
PECUNIARY LOSS)
ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

Perceptually-correct soft shadows, based on a three-step process:

1. Find relevant blockers
2. Estimate penumbra sizes
3. Perform variable-sized percentage-closer filtering

% Perceptually-correct soft shadows.
% For more information, please see the 
% "Percentage-Closer Soft Shadows" talk from GDC 2005.
% The talk is available at 
% http://developer.nvidia.com/object/gdc_200...sentations.html

$Author: efoo $

keywords: material shadow
date: 070214

******************************************************************************/

// for machines that support FP16 buffers....
#define HAS_FP16

#include "include\\Quad.fxh"
bool distanceControl <
    string UIName = "Distance Control";
> = true;

half Script : STANDARDSGLOBAL <
       string UIWidget = "none";
       string ScriptClass = "scene";
       string ScriptOrder = "postprocess";
       string ScriptOutput = "color";
       string Script = "Technique=Main;";
> = 0.8; // version #

half4 ClearColor <
       string UIWidget = "color";
       string UIName = "Background";
> = {0,0,0,0.0};

half ClearDepth <string UIWidget = "none";> = 1.0;

#ifdef HAS_FP16
#define FAR 1000.0f
#else
#define FAR 1.0f
#endif

half4 ShadowClearColor <
	string UIName = "Shadow Far BG";
    string UIWidget = "none";
> = {FAR,FAR,FAR,0.0};

texture floorTexture <
	string UIName = "Surface Texture";
	string ResourceName = "floor.dds";
>;

sampler floorSampler = sampler_state
{
	texture = <floorTexture>;
	MagFilter = Linear;
	MinFilter = Linear;
	MipFilter = Linear;
};

DECLARE_QUAD_TEX(SceneMap,SceneSampler,"A8R8G8B8")
DECLARE_QUAD_DEPTH_BUFFER(DepthBuffer,"D24S8")
float4 OldTex;

/************* "UN-TWEAKABLES," TRACKED BY CPU APPLICATION **************/

half4x4 WorldITXf : WorldInverseTranspose <string UIWidget="None";>;
half4x4 WorldViewProjXf : WorldViewProjection <string UIWidget="None";>;
half4x4 WorldXf : World <string UIWidget="None";>;
half4x4 ViewIXf : ViewInverse <string UIWidget="None";>;
half4x4 WorldViewITXf : WorldViewInverseTranspose <string UIWidget="None";>;
half4x4 WorldViewXf : WorldView <string UIWidget="None";>;
half4x4 ViewXf : View <string UIWidget="None";>;
half4x4 ViewITXf : ViewInverseTranspose <string UIWidget="None";>;

half4x4 LampViewXf : View <
   string UIName = "Lamp View Xform";
   //string UIWidget="None";
   string frustum = "light0";
>;

half4x4 LampProjXf : Projection <
   string UIName = "Lamp Projection Xform";
   //string UIWidget="None";
   string frustum = "light0";
>;

///////////////////////////////////////////////////////////////
/// TWEAKABLES ////////////////////////////////////////////////
///////////////////////////////////////////////////////////////

////////////////////////////////////////////// spot light

half3 SpotLightPos : POSITION <
       string UIName = "Lamp Posistion";
       string Object = "SpotLight";
       string Space = "World";
> = {-1.0f, 1.0f, 0.0f};

half3 SpotLightColor : Diffuse <
       string UIName = "Lamp";
       string Object = "SpotLight";
       string UIWidget = "Color";
> = {0.8f, 1.0f, 0.4f};

// Parameters for the algorithm

half lightSize <
   string UIWidget = "slider";
   half UIMin = 0.010;
   half UIMax = 0.100;
   half UIStep = 0.001;
   string UIName = "Light Size";
> = 0.05f;

half ShadBias <
   string UIWidget = "slider";
   half UIMin = 0.0;
   half UIMax = 10.3;
   half UIStep = 0.0001;
   string UIName = "Shadow Bias";
> = 0.01;

half sceneScale <
   string UIWidget = "slider";
   half UIMin = 0.01;
   half UIMax = 100.0;
   half UIStep = 0.1;
   string UIName = "Near Plane Factor";
> = 1.0f;

// General lighting parameters

half SpotLightIntensity <
       string UIName = "Lamp Intensity";
       string UIWidget = "slider";
       half UIMin = 0.0;
       half UIMax = 2;
       half UIStep = 0.1;
> = 1;

half SpotLightCone <
   string UIWidget = "slider";
   half UIMin = 0.0;
   half UIMax = 90.5;
   half UIStep = 0.1;
   string UIName = "Cone Angle";
> = 45.0f;

////////////////////////////////////////////// ambient light

half3 AmbiLightColor : Ambient
<
   string UIName = "Ambient Light";
> = {0.07f, 0.07f, 0.07f};

/////////////// Shadow and Aiming Parameters



////////////////////////////////////////////// surface

half3 SurfColor : Diffuse <
   string UIName = "Surface";
       string UIWidget = "Color";
> = {1.0f, 0.7f, 0.3f};

half Kd <
   string UIWidget = "slider";
   half UIMin = 0.0;
   half UIMax = 1.5;
   half UIStep = 0.01;
   string UIName = "Diffuse";
> = 1.0;

half Ks <
   string UIWidget = "slider";
   half UIMin = 0.0;
   half UIMax = 1.5;
   half UIStep = 0.01;
   string UIName = "Specular";
> = 1.0;

half SpecExpon : SpecularPower <
   string UIWidget = "slider";
   half UIMin = 1.0;
   half UIMax = 128.0;
   half UIStep = 1.0;
   string UIName = "Specular Exponent";
> = 12.0;

////////////////////////////////////////////////////////
/// TEXTURES ///////////////////////////////////////////
////////////////////////////////////////////////////////

#define SHADOW_SIZE 1024

//#ifdef HAS_FP16
//#define SHADOW_FMT  "a16b16g16r16f"
#define SHADOW_FMT  "r32f"
//#else /* !HAS_FP16 */
//#define SHADOW_FMT  "a8b8g8r8"
//#endif /* !HAS_FP16 */

texture ShadMap : RENDERCOLORTARGET <
   half2 Dimensions = { SHADOW_SIZE, SHADOW_SIZE };
   string Format = (SHADOW_FMT) ;
   string UIWidget = "None";
>;
sampler ShadSampler = sampler_state {
   texture = <ShadMap>;
   AddressU  = CLAMP;
   AddressV = CLAMP;
   MipFilter = NONE;
   MinFilter = POINT;
   MagFilter = POINT;
};


texture ShadDepthTarget : RENDERDEPTHSTENCILTARGET <
   half2 Dimensions = { SHADOW_SIZE, SHADOW_SIZE };
   string format = "D24S8";
   string UIWidget = "None";
>;

/////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
/// SHADER CODE BEGINS /////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////

/* data from application vertex buffer */
struct ShadowAppData {
   half3 Position     : POSITION;
   half4 UV           : TEXCOORD0;
   half4 Normal       : NORMAL;
};

// Connector from vertex to pixel shader
struct ShadowVertexOutput {
   half4 HPosition    : POSITION;
   half2 UV           : TEXCOORD0;
   half3 LightVec     : TEXCOORD1;
   half3 WNormal      : TEXCOORD2;
   half3 WView        : TEXCOORD3;
   half4 LP           : TEXCOORD4;    // current position in light-projection space
   float4 Diffuse    : COLOR0;
   float4 TexCoord8   : COLOR1;   
};

// Connector from vertex to pixel shader
struct JustShadowVertexOutput {
   half4 HPosition    : POSITION;
   half4 LP           : TEXCOORD0;    // current position in light-projection space
};

////////////////////////////////////////////////////////////////////////////////
/// Vertex Shaders /////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

JustShadowVertexOutput shadVS(ShadowAppData IN,
                                       uniform half4x4
ShadowViewProjXf       // typically created from aimShadowProjXf()
) {
   JustShadowVertexOutput OUT = (JustShadowVertexOutput)0;
   half4 Po = half4(IN.Position.xyz,(half)1.0);     // object coordinates
   half4 Pw = mul(Po,WorldXf);                        // "P" in world coordinates
   half4 Pl = mul(Pw,ShadowViewProjXf);  // "P" in light coords
   OUT.LP = Pl;                // view coords (also lightspace projection coords in this case)
   OUT.HPosition = Pl; // screen clipspace coords
   return OUT;
}

// from scene camera POV
ShadowVertexOutput mainCamVS(ShadowAppData IN,
                                       uniform half4x4 ShadowViewProjXf)
{
   ShadowVertexOutput OUT = (ShadowVertexOutput)0;
  
   OUT.WNormal = mul(IN.Normal,WorldITXf).xyz; // world coords
   half4 Po = half4(IN.Position.xyz,(half)1.0);     // "P" in object coordinates
   half4 Pw = mul(Po,WorldXf);                        // "P" in world coordinates
   half4 Pl = mul(Pw,ShadowViewProjXf);  // "P" in light coords
   Pl.z -= ShadBias;	// factor in bias here to save pixel shader work
   OUT.LP = Pl;                                                       
// ...for pixel-shader shadow calcs
   OUT.WView = normalize(ViewIXf[3].xyz - Pw.xyz);     // world coords
   OUT.HPosition = mul(Po,WorldViewProjXf);    // screen clipspace coords
   OUT.UV = IN.UV.xy;     
                                              
// pass-thru
   OUT.LightVec = SpotLightPos - Pw.xyz;               // world coords
   return OUT;
}

/*********************************************************/
/*********** pixel shader ********************************/
/*********************************************************/

half4 shadPS(JustShadowVertexOutput IN) : COLOR
{
 
   return half4(IN.LP.zzz,1);
}

// -------------------------------------
// STEP 1: Search for potential blockers
// -------------------------------------
half findBlocker(half2 uv, half4 LP, uniform sampler ShadowMap,
                 uniform half bias, half searchWidth, half numSamples)
{

        // divide filter width by number of samples to use
        half stepSize = 2 * searchWidth / numSamples;

        // compute starting point uv coordinates for search
        uv = uv - half2(searchWidth, searchWidth);

        // reset sum to zero
        half blockerSum = 0;
        half receiver = LP.z;
        half blockerCount = 0;
        half foundBlocker = 0;

        // iterate through search region and add up depth values
        for (int i=0; i<numSamples; i++) {
               for (int j=0; j<numSamples; j++) {
                       half shadMapDepth = tex2D(ShadowMap, uv +
                                                 half2(i*stepSize,j*stepSize)).x;
                       // found a blocker
                       if (shadMapDepth < receiver) {
                               blockerSum += shadMapDepth;
                               blockerCount++;
                               foundBlocker = 1;
                       }
               }
        }

		half result;
		
		if (foundBlocker == 0) {
			// set it to a unique number so we can check
			// later to see if there was no blocker
			result = 999;
		}
		else {
		    // return average depth of the blockers
			result = blockerSum / blockerCount;
		}
		
		return result;
}

// ------------------------------------------------
// STEP 2: Estimate penumbra based on
// blocker estimate, receiver depth, and light size
// ------------------------------------------------
half estimatePenumbra(half2 uv, half4 LP, uniform sampler ShadowMap,
                      uniform half bias, half blocker)
{
       // receiver depth
       half receiver = LP.z; 
       
       // Changed by: Roy Teusink
       if(distanceControl == false) receiver = 15;

       // estimate penumbra using parallel planes approximation
       half penumbra = (receiver - blocker) * lightSize / blocker;
       
       // Changed by: Roy Teusink
       if(distanceControl == false) penumbra = (receiver / blocker-4.55f) * lightSize / blocker; 
       
       return penumbra;
}

// ----------------------------------------------------
// Step 3: Percentage-closer filter implementation with
// variable filter width and number of samples.
// This assumes a square filter with the same number of
// horizontal and vertical samples.
// ----------------------------------------------------

half PCF_Filter(half2 uv, half4 LP, uniform sampler ShadowMap, 
                uniform half bias, half filterWidth, half numSamples)
{
       // compute step size for iterating through the kernel
       half stepSize = 2 * filterWidth / numSamples;

       // compute uv coordinates for upper-left corner of the kernel
       uv = uv - half2(filterWidth,filterWidth);

       half sum = 0;  // sum of successful depth tests

       // now iterate through the kernel and filter
       for (int i=0; i<numSamples; i++) {
               for (int j=0; j<numSamples; j++) {
                       // get depth at current texel of the shadow map
                       half shadMapDepth = 0;
                       
                       shadMapDepth = tex2D(ShadowMap, uv +
                                            half2(i*stepSize,j*stepSize)).x;

                       // test if the depth in the shadow map is closer than
                       // the eye-view point
                       half shad = LP.z < shadMapDepth;

                       // accumulate result
                       sum += shad;
               }
       }
       
       // return average of the samples
       return sum / (numSamples*numSamples);

}

float4 useShadowPS(ShadowVertexOutput IN,
       uniform float CosSpotAng) : COLOR
{
	
   // Generic lighting code 
   float3 Nn = normalize(IN.WNormal);
   float3 Vn = normalize(IN.WView);
   float3 Ln = normalize(IN.LightVec);
   float ldn = dot(Ln,Nn);
   half3 diffContrib = SurfColor*(Kd*ldn * SpotLightColor);
   half3 result = diffContrib;
   
   // The soft shadow algorithm follows:

   // Compute uv coordinates for the point being shaded
   // Saves some future recomputation.
   half2 uv = half2(.5,-.5)*(IN.LP.xy)/IN.LP.w + half2(.5,.5);

   // ---------------------------------------------------------
   // Step 1: Find blocker estimate
   half searchSamples = 6;   // how many samples to use for blocker search
   half blocker = findBlocker(uv, IN.LP,ShadSampler,ShadBias,
                              sceneScale * lightSize / IN.LP.z, searchSamples);
   
   //return (blocker*0.3);  // uncomment to visualize blockers
   
   // ---------------------------------------------------------
   // Step 2: Estimate penumbra using parallel planes approximation
   half penumbra;  
   penumbra = estimatePenumbra(uv, IN.LP, ShadSampler, ShadBias, blocker);

   //return penumbra*32;  // uncomment to visualize penumbrae

   // ---------------------------------------------------------
   // Step 3: Compute percentage-closer filter
   // based on penumbra estimate
   half samples = 8;	// reduce this for higher performance

   // Now do a penumbra-based percentage-closer filter
   half shadowed; 

   shadowed = PCF_Filter(uv, IN.LP, ShadSampler, ShadBias, penumbra, samples);
   
   // If no blocker was found, just return 1.0
   // since the point isn't occluded
   
   if (blocker > 998) 
   		shadowed = 1.0;

   // Visualize lighting and shadows
   
   half4 floorColor = tex2D(floorSampler, IN.UV);
half4 OldTex = tex2D(SceneSampler, IN.UV );
    
   //return floorColor;
   //return shadowed;
   
   return float4((shadowed*result*floorColor*OldTex),1);
}

////////////////////////////////////////////////////////////////////
/// TECHNIQUES /////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////

technique Main <
       string Script = 
       //mycode
       		   "RenderColorTarget0=SceneMap;"
       		   "RenderDepthStencilTarget=DepthBuffer;"
       		   "ClearSetColor=ClearColor;"
	        	"ClearSetDepth=ClearDepth;"
				"Clear=Color;"
				"Clear=Depth;"
	           	"ScriptExternal=color;"
       	
	   //~mycode
       		   "Pass=MakeShadow;"
               "Pass=UseShadow;";
> {

       pass MakeShadow <
               string Script = 
               "RenderColorTarget0=ShadMap;"
               "RenderDepthStencilTarget=ShadDepthTarget;"
               "RenderPort=light0;"
               "ClearSetColor=ShadowClearColor;"
               "ClearSetDepth=ClearDepth;"
               "Clear=Color;"
               "Clear=Depth;"
               "Draw=geometry;";
               
       > {
               VertexShader = compile vs_3_0 shadVS(mul(LampViewXf,LampProjXf));
               ZEnable = true;
               ZWriteEnable = true;
               ZFunc = LessEqual;
               CullMode = None;
               PixelShader = compile ps_3_0 shadPS();
       }
       pass UseShadow <
               string Script = "RenderColorTarget0=;"
                               "RenderDepthStencilTarget=;"
                               "RenderPort=;"
                               "ClearSetColor=ClearColor;"
                               "ClearSetDepth=ClearDepth;"
                               "Clear=Color;"
                               "Clear=Depth;"
                               "Draw=geometry;";
       > {
               VertexShader = compile vs_3_0
			   mainCamVS(mul(LampViewXf,LampProjXf));
               ZEnable = true;
               ZWriteEnable = true;
               ZFunc = LessEqual;
               CullMode = None;
               PixelShader = compile ps_3_0
			   useShadowPS(cos(radians(SpotLightCone)));
       }
}



http://www.vectorstudios.nethttp://engine.vectorstudios.net

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.