Original Post
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) Full Source:
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 );
/*********************************************************************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)));
}
}