This commit is contained in:
2025-11-28 23:13:44 +05:30
commit a3a8e79709
7360 changed files with 1156074 additions and 0 deletions

View File

@ -0,0 +1,111 @@
#ifndef CONFIG_H
#define CONFIG_H
// The VFACE register sign indicates if the face is backfacing or not.
// The Renderer will define this if its supported...
#if !defined(ENABLE_VFACE)
#define ENABLE_VFACE 0
#endif
// When true, ENABLE_COLOR_SWIZZLE_SUPPORT provides dynamic
// color swizzling support from rgb/bgr -> bgr/rgb
// if g_bSwizzleColor is true
// This prevents the need for CPU color swizzling on platforms
// expecting a color format different from that provided
#if !defined(ENABLE_COLOR_SWIZZLE_SUPPORT)
#define ENABLE_COLOR_SWIZZLE_SUPPORT 0
#endif
// The D3D compiler will #define this as TANGENT!!
#ifndef SEMANTIC_TANGENT
#define SEMANTIC_TANGENT TEXCOORD5
#endif
#define SEMANTIC_INSTANCE_T TEXCOORD8
#define SEMANTIC_INSTANCE_X TEXCOORD9
#define SEMANTIC_INSTANCE_Y TEXCOORD10
#define SEMANTIC_INSTANCE_Z TEXCOORD11
#define SEMANTIC_INSTANCE_UV TEXCOORD12
#define SEMANTIC_INSTANCE_LOCAL TEXCOORD13
#define SEMANTIC_DISPLACEMENT TEXCOORD14
#define SEMANTIC_DISPLACEMENT_FLAGS TEXCOORD15
#define SEMANTIC_SPRITE_ROT_SCALEX_SCALEY TEXCOORD14
#define SEMANTIC_BONEINDEX TEXCOORD6
#if !defined(RENDERER_DISPLACED)
#define RENDERER_DISPLACED 0
#endif
#if !defined(ENABLE_TESSELLATION)
#define ENABLE_TESSELLATION 0
#endif
// Parameters passed from the vertex shader to the fragment shader.
struct FragmentParameters
{
float3 worldSpacePosition : TEXCOORD4;
float3 worldSpaceNormal : TEXCOORD5;
float3 worldSpaceTangent : TEXCOORD6;
float3 worldSpaceBinormal : TEXCOORD7;
#if defined(PX_X360) && defined(RENDERER_FRAGMENT)
float2 spriteTexCoord : SPRITETEXCOORD;
#endif
#if defined (RENDERER_GXM)
float2 spriteTexCoord : SPRITECOORD;
#endif
float4 texcoord0 : TEXCOORD0;
float4 texcoord1 : TEXCOORD1;
float4 texcoord2 : TEXCOORD2;
#if !defined (RENDERER_WIN8ARM)
float4 texcoord3 : TEXCOORD3;
#endif
half4 color : COLOR;
};
// Material information for a given fragment.
struct SurfaceMaterial
{
half3 diffuseColor;
half alpha;
half3 emissiveColor;
half3 specularColor;
half specularPower;
half3 tangentSpaceNormal;
};
// Lighting information for a given fragment.
struct Lighting
{
half3 diffuseColor;
half3 specularColor;
};
// Final output for a Forward Rendered Fragment.
struct Fragment
{
half4 color : COLOR0;
};
// Final output for a Deferred Rendered Fragment.
struct DeferredFragment
{
// TODO: COLOR0 alpha should be the alpha value... not emissiveIntensity.
half4 diffuseColor : COLOR0; // rgb=diffuseColor
half4 emissiveColor : COLOR1; // rgb=emissiveColor
half4 worldSpaceNormalAndSpecularPower : COLOR2; // rgb=worldSpaceNormal, a=specularPower
};
// user implemented functions...
SurfaceMaterial computeSurfaceMaterial(const FragmentParameters params);
// lighting functions...
Lighting computeLighting(const FragmentParameters params, const SurfaceMaterial material);
#endif

View File

@ -0,0 +1,144 @@
#ifndef DEFINES_CG
#define DEFINES_CG
#define __in(argType, argName, argSemantic) argType argName : argSemantic
#ifdef RENDERER_GNM
#define JOIN2(a, b) a##b
#define JOIN(a, b) JOIN2(a, b)
#define BEGIN_CBUFFER(name)
#define END_CBUFFER(name)
#define CONST_TYPE
#define DECLARE_TEXTURE(textureName) Texture2D textureName; SamplerState JOIN(textureName,SamplerState);
#define DECLARE_TEXTURE_3D(textureName) Texture3D textureName; SamplerState JOIN(textureName,SamplerState);
#define tex2D(textureName,textureCoord) textureName.Sample(JOIN(textureName,SamplerState), textureCoord)
#define tex2Dproj(textureName,textureCoord) textureName.Sample(JOIN(textureName,SamplerState), textureCoord.xy).x <=
#define __in_opt(argType, argName, argSemantic) , __in(argType, argName, argSemantic)
#define COLOR0 S_TARGET_OUTPUT
#define half3 float3
#define half4 float4
#define half float
#elif !defined(RENDERER_D3D11)
#define BEGIN_CBUFFER(name)
#define END_CBUFFER(name)
#define CONST_TYPE uniform const
#define DECLARE_TEXTURE(name) uniform const sampler2D name;
#define DECLARE_TEXTURE_3D(name) uniform const sampler3D name;
#define __in_opt(argType, argName, argSemantic) , __in(argType, argName, argSemantic)
#else /* !defined(RENDERER_D3D11) */
#define JOIN2(a, b) a##b
#define JOIN(a, b) JOIN2(a, b)
#define BEGIN_CBUFFER(name) cbuffer name {
#define END_CBUFFER(name) }
#define CONST_TYPE
#define DECLARE_TEXTURE(textureName) Texture2D textureName; SamplerState JOIN(textureName,SamplerState);
#define DECLARE_TEXTURE_3D(textureName) Texture3D textureName; SamplerState JOIN(textureName,SamplerState);
#define tex2D(textureName,textureCoord) textureName.Sample(JOIN(textureName,SamplerState), textureCoord)
#define tex2Dproj(textureName,textureCoord) textureName.Sample(JOIN(textureName,SamplerState), textureCoord.xy).x <= textureCoord.z ? 0 : 1
#define __in_opt2(argType, argName, argSemantic) JOIN(__in_,argSemantic) (argType, argName, argSemantic)
#define __in_opt(argType, argName, argSemantic) __in_opt2(argType, argName, argSemantic)
#if defined(USE_ALL) || defined(RENDERER_FRAGMENT)
#define USE_POSITION 1
#define USE_NORMAL 1
#define USE_TANGENT 1
#define USE_TEXCOORD0 1
#define USE_TEXCOORD1 1
#define USE_TEXCOORD2 1
#define USE_TEXCOORD3 1
#define USE_COLOR 1
#define USE_BONE 1
#endif
#define __in_POSITION(a,b,c) __in(a, b, c)
// These semantics are required, not optional, when specified in a shader argument list
#define __in_TEXCOORD6(a,b,c) , __in(a, b, c)
#define __in_TEXCOORD7(a,b,c) , __in(a, b, c)
#define __in_TEXCOORD8(a,b,c) , __in(a, b, c)
#define __in_TEXCOORD9(a,b,c) , __in(a, b, c)
#define __in_TEXCOORD10(a,b,c) , __in(a, b, c)
#define __in_TEXCOORD11(a,b,c) , __in(a, b, c)
//#define __in_TEXCOORD12(a,b,c) , __in(a, b, c) // Optional instance semantic for uv offsets
//#define __in_TEXCOORD13(a,b,c) , __in(a, b, c) // Optional instance semantic for local offsets
#define __in_TEXCOORD14(a,b,c) , __in(a, b, c)
//#define __in_TEXCOORD15(a,b,c) , __in(a, b, c) // Optional displacement semantic
#define __in_TEXCOORD16(a,b,c) , __in(a, b, c)
#define __in_TEXCOORD17(a,b,c) , __in(a, b, c)
#if USE_NORMAL
#define __in_NORMAL(a,b,c) , __in(a, b, c)
#else
#define __in_NORMAL(a,b,c)
#define localSpaceNormal float3(1,0,0)
#endif
#if USE_TANGENT
#define __in_TANGENT(a,b,c) , __in(a, b, c)
#define __in_TEXCOORD5(a,b,c) , __in(a, b, c)
#else
#define __in_TANGENT(a,b,c)
#define __in_TEXCOORD5(a,b,c)
#define localSpaceTangent float4(1,0,0,1)
#endif
#if USE_TEXCOORD0
#define __in_TEXCOORD0(a,b,c) , __in(a, b, c)
#else
#define __in_TEXCOORD0(a,b,c)
#define vertexTexcoord0 float4(0,0,0,0)
#endif
#if USE_TEXCOORD1
#define __in_TEXCOORD1(a,b,c) , __in(a, b, c)
#else
#define __in_TEXCOORD1(A,B,C)
#define vertexTexcoord1 float4(0,0,0,0)
#endif
#if USE_TEXCOORD2
#define __in_TEXCOORD2(a,b,c) , __in(a, b, c)
#else
#define __in_TEXCOORD2(a,b,c)
#define vertexTexcoord2 float4(0,0,0,0)
#endif
#if USE_TEXCOORD3
#define __in_TEXCOORD3(a,b,c) , __in(a, b, c)
#else
#define __in_TEXCOORD3(a,b,c)
#define vertexTexcoord3 float4(0,0,0,0)
#endif
#if USE_COLOR
#define __in_COLOR(a,b,c) , __in(a, b, c)
#else
#define __in_COLOR(a,b,c)
#define vertexColor half4(0,0,0,0)
#endif
#if USE_TEXCOORD12
#define __in_TEXCOORD12(a,b,c) , __in(a, b, c)
#else
#define __in_TEXCOORD12(a,b,c)
#define instanceUVOffset float2(0,0)
#endif
#if USE_TEXCOORD13
#define __in_TEXCOORD13(a,b,c) , __in(a, b, c)
#else
#define __in_TEXCOORD13(a,b,c)
#define instanceLocalOffset float3(0,0,0)
#endif
#if USE_TEXCOORD15
#define __in_TEXCOORD15(a,b,c) , __in(a, b, c)
#else
#define __in_TEXCOORD15(a,b,c)
#define vertexFlagsDisp 0
#endif
#endif /* !defined(RENDERER_D3D11) */
#endif

View File

@ -0,0 +1,100 @@
#ifndef FRAGMENT_ENTRY_CG
#define FRAGMENT_ENTRY_CG
#include <config.cg>
BEGIN_CBUFFER(cbShade)
CONST_TYPE float shadeMode;
END_CBUFFER(cbShade)
#if !defined(ENABLE_VFACE)
#define ENABLE_VFACE 0
#endif
// define the platform specific semantic for the facing register
#define FACE_SEMANTIC VFACE
#if defined(PASS_UNLIT)
Fragment fmain(FragmentParameters params)
{
Fragment fout;
SurfaceMaterial material = computeSurfaceMaterial(params);
fout.color = half4(material.diffuseColor, material.alpha);
return fout;
}
#elif defined(PASS_AMBIENT_LIGHT) || defined(PASS_POINT_LIGHT) || defined(PASS_DIRECTIONAL_LIGHT) || defined(PASS_SPOT_LIGHT) || defined(PASS_SPOT_LIGHT_NO_SHADOW)
Fragment fmain(FragmentParameters params
#if ENABLE_VFACE
,float vface : FACE_SEMANTIC
#endif
)
{
#if !ENABLE_VFACE
float vface = 1.0;
#endif
#if ENABLE_VFACE_SCALE
vface *= g_vfaceScale;
#endif
Fragment fout;
float3x3 tangentBasis = float3x3(params.worldSpaceTangent, params.worldSpaceBinormal, params.worldSpaceNormal);
SurfaceMaterial material = computeSurfaceMaterial(params);
float3 bumpNormal = mul(material.tangentSpaceNormal, tangentBasis);
#if defined(NO_SUPPORT_DDX_DDY)
//#if !defined(GLSL_COMPILER)
params.worldSpaceNormal = sign(vface) * normalize(bumpNormal);
//#endif
#else
// emulate flat shading by taking the derivative of position with respective to screen dx and dy and taking the cross product
float3 faceNormal = cross(ddy(params.worldSpacePosition.xyz), ddx(params.worldSpacePosition.xyz));
// select bump or face normal based on shade mode
params.worldSpaceNormal = sign(vface) * normalize(lerp(bumpNormal, faceNormal, shadeMode));
#endif // NO_SUPPORT_DDX_DDY
Lighting lighting = computeLighting(params, material);
float3 diffuseColor = material.diffuseColor * lighting.diffuseColor;
float3 emissiveColor = material.emissiveColor + material.specularColor * lighting.specularColor;
fout.color = half4(diffuseColor + emissiveColor, material.alpha);
//fout.color = half4(params.worldSpaceNormal, 1); // renders normals.
// Fog
//float depth = length(params.worldSpacePosition - g_eyePosition);
//float fogBlend = min(1.0f, depth/g_fogColorAndDistance.w);
//fout.color.xyz = half3(fout.color.xyz * (1.0f-fogBlend) + g_fogColorAndDistance.xyz * fogBlend);
return fout;
}
#elif defined(PASS_NORMALS)
Fragment fmain(FragmentParameters params)
{
Fragment fout;
SurfaceMaterial material = computeSurfaceMaterial(params);
fout.color = half4(0,1,0,material.alpha);
return fout;
}
#elif defined(PASS_DEPTH)
Fragment fmain(FragmentParameters params)
{
Fragment fout;
SurfaceMaterial material = computeSurfaceMaterial(params);
float depth = length(params.worldSpacePosition - g_eyePosition);
fout.color = half4((half)depth,(half)depth,(half)depth,material.alpha);
return fout;
}
#elif defined(PASS_DEFERRED)
DeferredFragment fmain(FragmentParameters params)
{
DeferredFragment fout;
SurfaceMaterial material = computeSurfaceMaterial(params);
fout.diffuseColor = half4(material.diffuseColor, 0);
fout.emissiveColor = half4(material.emissiveColor, 0);
fout.worldSpaceNormalAndSpecularPower = half4(params.worldSpaceNormal, material.specularPower);
return fout;
}
#endif
#endif

View File

@ -0,0 +1,96 @@
#ifndef FRAGMENT_ENTRY_CG
#define FRAGMENT_ENTRY_CG
#include <config.cg>
BEGIN_CBUFFER(cbShade)
CONST_TYPE float shadeMode;
END_CBUFFER(cbShade)
#if !defined(ENABLE_VFACE)
#define ENABLE_VFACE 0
#endif
// define the platform specific semantic for the facing register
#define FACE_SEMANTIC VFACE
#if defined(PASS_UNLIT)
Fragment fmain(FragmentParameters params)
{
Fragment fout;
SurfaceMaterial material = computeSurfaceMaterial(params);
fout.color = half4(material.diffuseColor, material.alpha);
return fout;
}
#elif defined(PASS_AMBIENT_LIGHT) || defined(PASS_POINT_LIGHT) || defined(PASS_DIRECTIONAL_LIGHT) || defined(PASS_SPOT_LIGHT) || defined(PASS_SPOT_LIGHT_NO_SHADOW)
Fragment fmain(FragmentParameters params
#if ENABLE_VFACE
,float vface : FACE_SEMANTIC
#endif
)
{
#if !ENABLE_VFACE
float vface = 1.0;
#endif
#if ENABLE_VFACE_SCALE
vface *= g_vfaceScale;
#endif
Fragment fout;
float3x3 tangentBasis = float3x3(params.worldSpaceTangent, params.worldSpaceBinormal, params.worldSpaceNormal);
SurfaceMaterial material = computeSurfaceMaterial(params);
float3 bumpNormal = mul(material.tangentSpaceNormal, tangentBasis);
#ifndef NO_SUPPORT_DDX_DDY
// emulate flat shading by taking the derivative of position with respective to screen dx and dy and taking the cross product
float3 faceNormal = cross(ddy(params.worldSpacePosition.xyz), ddx(params.worldSpacePosition.xyz));
// select bump or face normal based on shade mode
params.worldSpaceNormal = sign(vface) * normalize(lerp(bumpNormal, faceNormal, shadeMode));
#endif // NO_SUPPORT_DDX_DDY
Lighting lighting = computeLighting(params, material);
float3 diffuseColor = material.diffuseColor * lighting.diffuseColor;
float3 emissiveColor = material.emissiveColor + material.specularColor * lighting.specularColor;
fout.color = half4(diffuseColor + emissiveColor, material.alpha);
//fout.color = half4(params.worldSpaceNormal, 1); // renders normals.
// Fog
float depth = length(params.worldSpacePosition - g_eyePosition);
float fogBlend = min(1.0f, depth/g_fogColorAndDistance.w);
fout.color.xyz = half3(fout.color.xyz * (1.0f-fogBlend) + g_fogColorAndDistance.xyz * fogBlend);
return fout;
}
#elif defined(PASS_NORMALS)
Fragment fmain(FragmentParameters params)
{
Fragment fout;
SurfaceMaterial material = computeSurfaceMaterial(params);
fout.color = half4(0,1,0,material.alpha);
return fout;
}
#elif defined(PASS_DEPTH)
Fragment fmain(FragmentParameters params)
{
Fragment fout;
SurfaceMaterial material = computeSurfaceMaterial(params);
float depth = length(params.worldSpacePosition - g_eyePosition);
fout.color = half4((half)depth,(half)depth,(half)depth,material.alpha);
return fout;
}
#elif defined(PASS_DEFERRED)
DeferredFragment fmain(FragmentParameters params)
{
DeferredFragment fout;
SurfaceMaterial material = computeSurfaceMaterial(params);
fout.diffuseColor = half4(material.diffuseColor, 0);
fout.emissiveColor = half4(material.emissiveColor, 0);
fout.worldSpaceNormalAndSpecularPower = half4(params.worldSpaceNormal, material.specularPower);
return fout;
}
#endif
#endif

View File

@ -0,0 +1,87 @@
#ifndef FRAGMENT_ENTRY_CG
#define FRAGMENT_ENTRY_CG
#include <config.cg>
BEGIN_CBUFFER(cbShade)
CONST_TYPE float shadeMode;
END_CBUFFER(cbShade)
#if !defined(ENABLE_VFACE)
#define ENABLE_VFACE 0
#endif
// define the platform specific semantic for the facing register
#define FACE_SEMANTIC VFACE
#if defined(PASS_UNLIT)
Fragment fmain(FragmentParameters params)
{
Fragment fout;
SurfaceMaterial material = computeSurfaceMaterial(params);
fout.color = half4(material.diffuseColor, material.alpha);
return fout;
}
#elif defined(PASS_AMBIENT_LIGHT) || defined(PASS_POINT_LIGHT) || defined(PASS_DIRECTIONAL_LIGHT) || defined(PASS_SPOT_LIGHT) || defined(PASS_SPOT_LIGHT_NO_SHADOW)
Fragment fmain(FragmentParameters params
#if ENABLE_VFACE
,float vface : FACE_SEMANTIC
#endif
)
{
#if !ENABLE_VFACE
float vface = 1.0;
#endif
#if ENABLE_VFACE_SCALE
vface *= g_vfaceScale;
#endif
Fragment fout;
float3x3 tangentBasis = float3x3(params.worldSpaceTangent, params.worldSpaceBinormal, params.worldSpaceNormal);
SurfaceMaterial material = computeSurfaceMaterial(params);
float3 bumpNormal = mul(material.tangentSpaceNormal, tangentBasis);
#ifndef NO_SUPPORT_DDX_DDY
// emulate flat shading by taking the derivative of position with respective to screen dx and dy and taking the cross product
float3 faceNormal = cross(ddy(params.worldSpacePosition.xyz), ddx(params.worldSpacePosition.xyz));
// select bump or face normal based on shade mode
params.worldSpaceNormal = sign(vface) * normalize(lerp(bumpNormal, faceNormal, shadeMode));
#endif // NO_SUPPORT_DDX_DDY
fout.color = half4(material.diffuseColor.x,material.diffuseColor.y,material.diffuseColor.z,1);
return fout;
}
#elif defined(PASS_NORMALS)
Fragment fmain(FragmentParameters params)
{
Fragment fout;
SurfaceMaterial material = computeSurfaceMaterial(params);
fout.color = half4(0,1,0,material.alpha);
return fout;
}
#elif defined(PASS_DEPTH)
Fragment fmain(FragmentParameters params)
{
Fragment fout;
SurfaceMaterial material = computeSurfaceMaterial(params);
float depth = length(params.worldSpacePosition - g_eyePosition);
fout.color = half4((half)depth,(half)depth,(half)depth,material.alpha);
return fout;
}
#elif defined(PASS_DEFERRED)
DeferredFragment fmain(FragmentParameters params)
{
DeferredFragment fout;
SurfaceMaterial material = computeSurfaceMaterial(params);
fout.diffuseColor = half4(material.diffuseColor, 0);
fout.emissiveColor = half4(material.emissiveColor, 0);
fout.worldSpaceNormalAndSpecularPower = half4(params.worldSpaceNormal, material.specularPower);
return fout;
}
#endif
#endif

View File

@ -0,0 +1,98 @@
#ifndef GLOBALS_CG
#define GLOBALS_CG
#define MAX_BONES 60
#if !defined(MAX_LIGHTS)
#define MAX_LIGHTS 1
#endif
#include <defines.cg>
BEGIN_CBUFFER(cbMesh0)
CONST_TYPE float4x4 g_MVP;
END_CBUFFER(cbMesh0)
BEGIN_CBUFFER(cbMesh)
CONST_TYPE float4x4 g_modelMatrix;
CONST_TYPE float4x4 g_modelViewMatrix;
CONST_TYPE float4x4 g_modelViewProjMatrix;
END_CBUFFER(cbMesh)
BEGIN_CBUFFER(cbFrame)
CONST_TYPE float4x4 g_viewMatrix;
CONST_TYPE float4x4 g_projMatrix;
CONST_TYPE float3 g_eyePosition;
CONST_TYPE float3 g_eyeDirection;
END_CBUFFER(cbFrame)
BEGIN_CBUFFER(cbFrameInv)
CONST_TYPE float4x4 g_invViewProjMatrix;
END_CBUFFER(cbFrameInv)
#if defined USE_VTF
CONST_TYPE sampler2D g_boneTexture; // Vertex texture to hold bone matrices
#endif
BEGIN_CBUFFER(cbBones)
CONST_TYPE float4x4 g_boneMatrices[MAX_BONES]; // TODO: change this to a float4x3 (a transposed 3x4) so we can pack more bones in...
#if defined USE_VTF
CONST_TYPE int g_boneTextureHeight; // Bone texture height
#endif
END_CBUFFER(cbBones)
BEGIN_CBUFFER(cbFog)
CONST_TYPE float4 g_fogColorAndDistance;
END_CBUFFER(cbFog)
BEGIN_CBUFFER(cbAmbient)
CONST_TYPE float3 g_ambientColor;
END_CBUFFER(cbAmbient)
BEGIN_CBUFFER(cbLight)
CONST_TYPE float3 g_lightColor;
CONST_TYPE float3 g_lightDirection;
CONST_TYPE float3 g_lightPosition;
CONST_TYPE float g_lightIntensity;
CONST_TYPE float g_lightInnerRadius;
CONST_TYPE float g_lightOuterRadius;
CONST_TYPE float g_lightInnerCone;
CONST_TYPE float g_lightOuterCone;
END_CBUFFER(cbLight)
BEGIN_CBUFFER(cbScale)
#if ENABLE_VFACE_SCALE
CONST_TYPE float g_vfaceScale;
#endif
END_CBUFFER(cbScale)
// D3D11 expects rgba
#if ENABLE_COLOR_SWIZZLE_SUPPORT
BEGIN_CBUFFER(cbSwizzleColor)
CONST_TYPE int g_bSwizzleColor;
END_CBUFFER(cbSwizzleColor)
half4 swizzle(half4 inColor) { return g_bSwizzleColor ? inColor.zyxw : inColor; }
#else
half4 swizzle(half4 inColor) { return inColor; }
#endif
#if defined(RENDERER_D3D11)
// D3D11 screen coordinates differ from GL/DX9
BEGIN_CBUFFER(cbView2D)
CONST_TYPE float4x4 g_viewMatrix2D;
END_CBUFFER(cbView2D)
#else
static const float4x4 g_viewMatrix2D = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
#endif
#if defined(PASS_SPOT_LIGHT)
// TODO: Make this less hacky, have a PASS_SUPPORTS_SHADOWS #define
#define PASS_SUPPORTS_SHADOWS
DECLARE_TEXTURE(g_lightShadowMap);
BEGIN_CBUFFER(cbLightShadow)
CONST_TYPE float4x4 g_lightShadowMatrix;
END_CBUFFER(cbLightShadow)
#endif
#endif

View File

@ -0,0 +1,108 @@
#ifndef LIGHTING_CG
#define LIGHTING_CG
#include <config.cg>
#include <globals.cg>
// Internal Lighting functions...
Lighting computeAmbientLight( const FragmentParameters params, const SurfaceMaterial material);
Lighting computeDirectionalLight(const FragmentParameters params, const SurfaceMaterial material);
Lighting computePointLight( const FragmentParameters params, const SurfaceMaterial material);
Lighting computeSpotLight( const FragmentParameters params, const SurfaceMaterial material);
#if defined(PASS_SUPPORTS_SHADOWS)
#define NUM_SHADOW_OFFSETS 32
static float2 shadowMapOffsets[NUM_SHADOW_OFFSETS] =
{
float2( 0.024439,-0.191747), float2( 0.127369, 0.462646), float2( 0.769628,-0.291028), float2(-0.684950, 0.518250),
float2( 0.019485, 0.303360), float2(-0.234805,-0.278718), float2(-0.679808,-0.717623), float2(-0.004622,-0.000659),
float2(-0.128309,-0.515931), float2( 0.497521, 0.347996), float2( 0.197836,-0.405042), float2(-0.576391,-0.192435),
float2( 0.379497, 0.355307), float2( 0.642894,-0.338695), float2( 0.368096, 0.394195), float2(-0.024818,-0.234009),
float2(-0.487682, 0.608270), float2( 0.822138, 0.568698), float2(-0.184849, 0.191561), float2( 0.020395,-0.012156),
float2(-0.647774,-0.197404), float2(-0.681738,-0.615919), float2(-0.418447,-0.412937), float2( 0.632155, 0.357966),
float2(-0.742742,-0.038003), float2(-0.759170,-0.569653), float2(-0.508216, 0.317101), float2( 0.547166,-0.267258),
float2(-0.134347, 0.070130), float2(-0.210947,-0.774648), float2( 0.751069, 0.026197), float2(-0.595643,-0.277915),
};
#endif
float computeShadowTerm(const FragmentParameters params)
{
float shadowMask = 1;
#if defined(PASS_SUPPORTS_SHADOWS) && ENABLE_SHADOWS
const float shadowDepthBias = 0.02;
const float depthBias = 0.00006;
#if 0
float4 lsp = mul(float4(params.worldSpacePosition, 1), g_lightShadowMatrix);
lsp = float4(float2(0.5,-0.5)*lsp.xy/lsp.w + 0.5, lsp.z/lsp.w - depthBias, 1);
shadowMask = tex2Dproj(g_lightShadowMap, lsp).x;
#elif 1
const float shadowOffsetScale = 0.005;
float4 lsp = mul(float4(params.worldSpacePosition, 1), g_lightShadowMatrix);
lsp = float4(float2(0.5,-0.5)*lsp.xy/lsp.w + 0.5, lsp.z/lsp.w - depthBias, 1);
shadowMask = 0;
for(int i=0; i<NUM_SHADOW_OFFSETS; i++)
{
float4 texcoord = lsp+float4(shadowMapOffsets[i]*shadowOffsetScale, 0,0);
shadowMask += tex2Dproj(g_lightShadowMap, texcoord).x;
}
shadowMask /= NUM_SHADOW_OFFSETS;
#else
const float fragmentDepth = length(g_lightPosition-params.worldSpacePosition)-shadowDepthBias;
float4 lsp = mul(float4(params.worldSpacePosition, 1), g_lightShadowMatrix);
lsp = float4(float2(0.5,-0.5)*lsp.xy/lsp.w + 0.5, lsp.z/lsp.w - depthBias, 1);
const float shadowOffsetScale = 0.002;
float4 shadowSpacePosition = mul(float4(params.worldSpacePosition, 1), g_lightShadowMatrix);
float2 shadowUV = float2(0.5,-0.5) * shadowSpacePosition.xy / shadowSpacePosition.w + float2(0.5, 0.5);
for(int i=0; i<NUM_SHADOW_OFFSETS/4; i++)
{
float4 shadowMapColor;
shadowMapColor.r = tex2D(g_lightShadowMap, (shadowUV+shadowMapOffsets[i*4+0]*shadowOffsetScale)).r;
shadowMapColor.g = tex2D(g_lightShadowMap, (shadowUV+shadowMapOffsets[i*4+1]*shadowOffsetScale)).r;
shadowMapColor.b = tex2D(g_lightShadowMap, (shadowUV+shadowMapOffsets[i*4+2]*shadowOffsetScale)).r;
shadowMapColor.a = tex2D(g_lightShadowMap, (shadowUV+shadowMapOffsets[i*4+3]*shadowOffsetScale)).r;
for(int j=0; j<4; j++)
{
if(shadowMapColor[j] < lsp.z)
{
shadowMask -= (1.0f/NUM_SHADOW_OFFSETS);
}
}
}
#endif
#endif
return shadowMask;
}
Lighting computeLighting(const FragmentParameters params, const SurfaceMaterial material)
{
Lighting lout;
#if defined(PASS_AMBIENT_LIGHT)
lout = computeAmbientLight(params, material);
#elif defined(PASS_DIRECTIONAL_LIGHT)
lout = computeDirectionalLight(params, material);
#elif defined(PASS_POINT_LIGHT)
lout = computePointLight(params, material);
#elif defined(PASS_SPOT_LIGHT) || defined(PASS_SPOT_LIGHT_NO_SHADOW)
lout = computeSpotLight(params, material);
#endif
const float shadowTerm = computeShadowTerm(params);
lout.diffuseColor *= (half)shadowTerm;
lout.specularColor *= (half)shadowTerm;
lout.diffuseColor += (half3)g_ambientColor * material.diffuseColor;
return lout;
}
#endif

View File

@ -0,0 +1,199 @@
#ifndef NOISE_CG
#define NOISE_CG
#include <config.cg>
////////////////////////////////////////////////////////////////////////
static uint permutation[] = { 151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
};
// gradients for 3d noise
static float3 g[] = {
1,1,0,
-1,1,0,
1,-1,0,
-1,-1,0,
1,0,1,
-1,0,1,
1,0,-1,
-1,0,-1,
0,1,1,
0,-1,1,
0,1,-1,
0,-1,-1,
1,1,0,
0,-1,1,
-1,1,0,
0,-1,-1,
};
// Functions
int permSample(uint i) {
return permutation[i % 256];
}
float4 permSample2D(float2 p) {
p *= 256;
int A = permSample(p.x) + p.y;
int AA = permSample(A);
int AB = permSample(A + 1);
int B = permSample(p.x + 1) + p.y;
int BA = permSample(B);
int BB = permSample(B + 1);
return float4(AA, AB, BA, BB) / 255.0;
}
float3 gradSample(float p) {
return g[ p*16 ];
}
float3 permGradSample(float p) {
return g[ permutation[p*256] % 16 ];
}
float3 fade(float3 t) {
return t * t * t * (t * (t * 6 - 15) + 10);
}
float perm(float x) {
return permSample(x);
}
float4 perm2d(float2 p) {
return permSample2D(p);
}
float grad(float x, float3 p) {
return dot(gradSample(x), p);
}
float gradperm(float x, float3 p) {
return dot(permGradSample(x), p);
}
// 3D noise
#if 0
// original version
float inoise(float3 p)
{
float3 P = fmod(floor(p), 256.0); // FIND UNIT CUBE THAT CONTAINS POINT
p -= floor(p); // FIND RELATIVE X,Y,Z OF POINT IN CUBE.
float3 f = fade(p); // COMPUTE FADE CURVES FOR EACH OF X,Y,Z.
P = P / 256.0;
const float one = 1.0 / 256.0;
// HASH COORDINATES OF THE 8 CUBE CORNERS
float A = perm(P.x) + P.y;
float4 AA;
AA.x = perm(A) + P.z;
AA.y = perm(A + one) + P.z;
float B = perm(P.x + one) + P.y;
AA.z = perm(B) + P.z;
AA.w = perm(B + one) + P.z;
// AND ADD BLENDED RESULTS FROM 8 CORNERS OF CUBE
return lerp( lerp( lerp( grad(perm(AA.x ), p ),
grad(perm(AA.z ), p + float3(-1, 0, 0) ), f.x),
lerp( grad(perm(AA.y ), p + float3(0, -1, 0) ),
grad(perm(AA.w ), p + float3(-1, -1, 0) ), f.x), f.y),
lerp( lerp( grad(perm(AA.x+one), p + float3(0, 0, -1) ),
grad(perm(AA.z+one), p + float3(-1, 0, -1) ), f.x),
lerp( grad(perm(AA.y+one), p + float3(0, -1, -1) ),
grad(perm(AA.w+one), p + float3(-1, -1, -1) ), f.x), f.y), f.z);
}
#else
// optimized version
float inoise(float3 p)
{
float3 P = fmod(floor(p), 256.0); // FIND UNIT CUBE THAT CONTAINS POINT
p -= floor(p); // FIND RELATIVE X,Y,Z OF POINT IN CUBE.
float3 f = fade(p); // COMPUTE FADE CURVES FOR EACH OF X,Y,Z.
P = P / 256.0;
const float one = 1.0 / 256.0;
// HASH COORDINATES OF THE 8 CUBE CORNERS
float4 AA = perm2d(P.xy) + P.z;
// AND ADD BLENDED RESULTS FROM 8 CORNERS OF CUBE
return lerp( lerp( lerp( gradperm(AA.x, p ),
gradperm(AA.z, p + float3(-1, 0, 0) ), f.x),
lerp( gradperm(AA.y, p + float3(0, -1, 0) ),
gradperm(AA.w, p + float3(-1, -1, 0) ), f.x), f.y),
lerp( lerp( gradperm(AA.x+one, p + float3(0, 0, -1) ),
gradperm(AA.z+one, p + float3(-1, 0, -1) ), f.x),
lerp( gradperm(AA.y+one, p + float3(0, -1, -1) ),
gradperm(AA.w+one, p + float3(-1, -1, -1) ), f.x), f.y), f.z);
}
#endif
static const float PI = 3.14159265f;
float3 inoiseOffset(float3 p)
{
float offsetX = inoise(p.xzy * g_tessUVScale.x);
float offsetY = inoise(p * g_tessUVScale.x);
float offsetZ = (offsetX + offsetY) * .5;
return float3(offsetX, offsetY, offsetZ);
}
// utility functions
// calculate gradient of noise (expensive!)
float3 inoiseGradient(float3 p, float d)
{
float f0 = inoise(p);
float fx = inoise(p + float3(d, 0, 0));
float fy = inoise(p + float3(0, d, 0));
float fz = inoise(p + float3(0, 0, d));
return float3(fx - f0, fy - f0, fz - f0) / d;
}
// utility functions
// calculate gradient of noise (expensive!)
float3 inoiseNormal(float3 p, float3 n)
{
float3 nN = normalize(n);
float theta = abs(acos(dot(nN, float3(1,0,0))));
float3 xAxis, zAxis;
if (theta > .001 && theta < (PI * 1.999)) {
zAxis = cross(nN, float3(1, 0, 0));
xAxis = cross(zAxis, nN);
}
else {
xAxis = cross(float3(0, 0, 1), nN);
zAxis = cross(xAxis, nN);
}
float3 pX = p + xAxis;
float3 pZ = p + zAxis;
float3 f0 = inoiseOffset(p) + p;
float3 fx = inoiseOffset(pX) + pX;
float3 fz = inoiseOffset(pZ) + pZ;
float3 dx = fx - f0;
float3 dz = fz - f0;
return normalize(cross(dx, dz));
}
#endif

View File

@ -0,0 +1,63 @@
#ifndef PHONG_LIGHTING_CG
#define PHONG_LIGHTING_CG
#include <config.cg>
#include <globals.cg>
#include <lighting.cg>
Lighting computeAmbientLight(const FragmentParameters params, const SurfaceMaterial material)
{
Lighting lout;
lout.diffuseColor = 0;
lout.specularColor = 0;
return lout;
}
Lighting computeDirectionalLight(const FragmentParameters params, const SurfaceMaterial material)
{
Lighting lout;
half3 lightColor = (half3)g_lightColor * (half)g_lightIntensity;
lout.diffuseColor = (half)saturate(dot(params.worldSpaceNormal, -g_lightDirection)) * lightColor;
float3 surfToEye = normalize(params.worldSpacePosition - g_eyePosition);
lout.specularColor = (half)pow(saturate(dot(reflect(-g_lightDirection, params.worldSpaceNormal), surfToEye)), material.specularPower) * lightColor;
return lout;
}
Lighting computePointLight(const FragmentParameters params, const SurfaceMaterial material)
{
Lighting lout;
lout.diffuseColor = 0;
lout.specularColor = 0;
return lout;
}
Lighting computeSpotLight(const FragmentParameters params, const SurfaceMaterial material)
{
Lighting lout;
half3 lightColor =(half3)g_lightColor * (half)g_lightIntensity;
float3 surfToEye = normalize(params.worldSpacePosition - g_eyePosition);
float3 surfToLight = g_lightPosition - params.worldSpacePosition;
float distance = length(surfToLight);
surfToLight *= 1 / distance; // is just doing a normalize faster?
float attenuation = 0;
if(distance < g_lightInnerRadius) attenuation = 1;
else if(distance < g_lightOuterRadius) attenuation = 1 - ((distance - g_lightInnerRadius) / (g_lightOuterRadius - g_lightInnerRadius));
float conedot = dot(-g_lightDirection, surfToLight);
if(conedot < g_lightOuterCone) attenuation = 0;
else if(conedot < g_lightInnerCone) attenuation *= (conedot - g_lightOuterCone) / (g_lightInnerCone - g_lightOuterCone);
float diffuse = saturate(dot(params.worldSpaceNormal, surfToLight));
float specular = pow(saturate(dot(reflect(surfToLight, params.worldSpaceNormal), surfToEye)), material.specularPower);
lout.diffuseColor = ((half)attenuation * (half)diffuse * lightColor);
lout.specularColor = ((half)attenuation * (half)specular * lightColor);
return lout;
}
#endif

View File

@ -0,0 +1,186 @@
#ifndef TESSELLATION_CG
#define TESSELLATION_CG
#include <config.cg>
#include <globals.cg>
#if !defined(ADAPTIVE_TESSELLATION)
#define ADAPTIVE_TESSELLATION 1
#endif
#if !defined(WEIGHTED_TESSELLATION)
#define WEIGHTED_TESSELLATION 1
#endif
#if !defined(ENABLE_EXTRA_SEMANTICS)
#define ENABLE_EXTRA_SEMANTICS 1
#endif
#if !defined(ENABLE_INTERIOR_DISTANCE)
#define ENABLE_INTERIOR_DISTANCE 1
#endif
#if ENABLE_TESSELLATION==0
//--------------------------------------------------------------------------------------
// Vertex Shader Output
//--------------------------------------------------------------------------------------
struct VertexOut
{
FragmentParameters params;
float4 screenSpacePosition : POSITION;
};
#else
struct VertexOut
{
FragmentParameters params;
float4 screenSpacePosition : POSITION;
#if ENABLE_EXTRA_SEMANTICS
float4 localPosition : SEMANTIC_MODEL_POSITION;
uint flagsDisp : SEMANTIC_DISPLACEMENT_FLAGS;
float4 modelMatrix[4] : SEMANTIC_MODEL_MATRIX;
#endif
};
//--------------------------------------------------------------------------------------
// Constants
//--------------------------------------------------------------------------------------
BEGIN_CBUFFER(cbTessellation)
// x = Edge Factor
// y = Inside factor
// z = Distance factor where (1 - (z/x)) clamps distance LOD
// w = Optional screen-space factor
CONST_TYPE float4 g_tessFactor : packoffset(c0);
// x = Min distance for LOD scaling
// y = Max distance for LOD scaling
CONST_TYPE float2 g_tessMinMaxDistance : packoffset(c1);
// x = Height scaling factor
// y = Height bias (applied before scaling)
CONST_TYPE float2 g_tessHeightScaleAndBias : packoffset(c1.z);
// x = U scaling factor
// y = V scaling factor
CONST_TYPE float2 g_tessUVScale : packoffset(c2);
END_CBUFFER(cbTessellation)
//--------------------------------------------------------------------------------------
// Static Constants
//--------------------------------------------------------------------------------------
static const uint X_FLAG = 0;
static const uint Y_FLAG = 1;
static const uint Z_FLAG = 2;
static const uint AXIS_MASK = 3;//X_FLAG | Y_FLAG | Z_FLAG;
static const uint FIXED_FLAG = 4;
static const uint INTERIOR_FLAG = 8;
//--------------------------------------------------------------------------------------
// Functions
//--------------------------------------------------------------------------------------
float getDisplacementWeight(uint uFlags)
{
return (uFlags & FIXED_FLAG) ? 0.f : 1.f;
}
uint getDisplacementAxis(uint uFlags)
{
return uFlags & AXIS_MASK;
}
bool isEdgeInterior(uint uFlags)
{
return uFlags & INTERIOR_FLAG;
}
/*
float getInteriorDistance(float3 vEdgeFactors, float3 vBaryCoords)
{
float3 vEdgeCoords = float3(1,1,1) -
normalize(float3(vBaryCoords.x + vBaryCoords.y,
vBaryCoords.y + vBaryCoords.z,
vBaryCoords.z + vBaryCoords.x) * .5);
if(vEdgeFactors.x > 0.)
vEdgeCoords.x = 0.;
if(vEdgeFactors.y > 0.)
vEdgeCoords.y = 0.;
if(vEdgeFactors.z > 0.)
vEdgeCoords.z = 0.;
return sqrt(max(vEdgeCoords.x, max(vEdgeCoords.y, vEdgeCoords.z)));
}*/
float getInteriorDistance(float3 edgeFactors, float3 baryCoords)
{
// Calculate distance from triangle exterior [0...1]
float3 vInteriorDistance = sqrt(baryCoords*edgeFactors);
//float3 vInteriorDistance = baryCoords*edgeFactors;
vInteriorDistance += float3(1,1,1) - edgeFactors;
return clamp(min(min(vInteriorDistance.x, vInteriorDistance.y), vInteriorDistance.z), 0, 1);
//float fInteriorDistance = 3.f * min(min(fU+input.EdgeFactors.x, fV+input.EdgeFactors.y), fW+input.EdgeFactors.z);
//float fInteriorDistance = 3.f * min(min(fU, fV), fW);
}
// Distance between point and line segment defined by p0 -> p1
float computeDistance(float3 worldSpacePosition, float3 p0, float3 p1)
{
float3 v = p1 - p1;
float3 w = worldSpacePosition - p0;
float c1 = dot(w,v);
if ( c1 <= 0 )
return distance(worldSpacePosition, p0);
float c2 = dot(v,v);
if ( c2 <= c1 )
return distance(worldSpacePosition, p1);
float b = c1 / c2;
return distance(worldSpacePosition, p0 + b * v);
}
// LOD distance based on viewpoint
float computeDistance(float3 worldSpacePosition, float3 eyePosition)
{
// Min and max distance should be chosen according to scene quality requirements
const float fMinDistance = g_tessMinMaxDistance.x;//x5.0f;
const float fMaxDistance = g_tessMinMaxDistance.y;//100.f;
// Calculate distance between vertex and camera, and a vertex distance factor issued from it
float fDistance = distance( worldSpacePosition.xyz, eyePosition );
return 1.0 - clamp( ( ( fDistance - fMinDistance ) / ( fMaxDistance - fMinDistance ) ),
0.0,
1.0 - g_tessFactor.z/g_tessFactor.x);
}
float3 pointInPlane(in float3 n, in float3 p, in float3 pPlane)
{
return p - dot(n, p - pPlane) * n;
}
float3 computeBarycentricCoordinates(in float3 p, in float3 n, in float3 a, in float3 b, in float3 c)
{
float3 pProj = pointInPlane(n, p, a);
float abc = dot(n, cross(b-a, c-a));
float pbc = dot(n, cross(b-pProj, c-pProj));
float pca = dot(n, cross(c-pProj, a-pProj));
float x0 = pbc / abc;
float x1 = pca / abc;
float x2 = 1.0f - x0 - x1;
return float3(x0, x1, x2);
}
#endif /* ENABLE_TESSELLATION==1 */
#endif

View File

@ -0,0 +1,309 @@
#ifndef TESSELLATION_ENTRY_CG
#define TESSELLATION_ENTRY_CG
#define ENABLE_EXTRA_SEMANTICS 1
#include <tessellation.cg>
#include <config.cg>
//--------------------------------------------------------------------------------------
// Functions
//--------------------------------------------------------------------------------------
// To be defined by the user
void computeOffsetAndNormal(in float3 vLocalPos, in float3 vFaceNormal, in float3 vBaryCoords,
inout float3 vOffset, inout float3 vNormal);
//--------------------------------------------------------------------------------------
// Structures
//--------------------------------------------------------------------------------------
struct HullConstOut
{
float Edges[3] : SV_TessFactor;
float Inside : SV_InsideTessFactor;
float3 EdgeFactors : POSITION3;
bool3 EdgeInterior : SEMANTIC_INTERIOR;
float4x4 ModelMatrix : SEMANTIC_MODEL_MATRIX;
};
struct HullControlOut
{
FragmentParameters params;
float3 vWorldPos : SV_POSITION;
float3 vLocalPos : SEMANTIC_DISPLACEMENT_POSITION;
float fWeightDisp : SEMANTIC_DISPLACEMENT_WEIGHT;
uint uAxis : SEMANTIC_DISPLACEMENT_AXIS;
};
struct DomainOut
{
FragmentParameters params;
float4 screenSpacePosition : SV_POSITION;
};
//--------------------------------------------------------------------------------------
// Hull shader
//--------------------------------------------------------------------------------------
HullConstOut ConstantsHS( InputPatch<VertexOut, 3> inputPatch, uint uPID : SV_PrimitiveID )
{
HullConstOut output = (HullConstOut)0;
float4 vEdgeTessellationFactors = g_tessFactor.xxxy;
float3 vEdgeFactor;
bool3 vInterior;
#if 0
vEdgeFactor.x = distance(inputPatch[1].params.worldSpacePosition.xyz, inputPatch[2].params.worldSpacePosition.xyz);
vEdgeFactor.y = distance(inputPatch[2].params.worldSpacePosition.xyz, inputPatch[0].params.worldSpacePosition.xyz);
vEdgeFactor.z = distance(inputPatch[1].params.worldSpacePosition.xyz, inputPatch[0].params.worldSpacePosition.xyz);
if( (vEdgeFactor.x > vEdgeFactor.y) && (vEdgeFactor.x > vEdgeFactor.z) ) { vEdgeFactor = float3(0.,1.,1.); vInterior.x = true; }
else if( (vEdgeFactor.y > vEdgeFactor.x) && (vEdgeFactor.y > vEdgeFactor.z) ) { vEdgeFactor = float3(1.,0.,1.); vInterior.y = true; }
else { vEdgeFactor = float3(1.,1.,0.); vInterior.z = true; }
#elif 1
// Assume all edges are exterior
vInterior = bool3(false, false, false);
vEdgeFactor = float3(1., 1., 1.);
// For some stupid reason, odd primitives have a different vertex order
if (uPID % 2 == 0)
{
vInterior[0] = isEdgeInterior(inputPatch[1].flagsDisp);
vInterior[1] = isEdgeInterior(inputPatch[2].flagsDisp);
vInterior[2] = isEdgeInterior(inputPatch[0].flagsDisp);
}
else
{
vInterior[0] = isEdgeInterior(inputPatch[2].flagsDisp);
vInterior[1] = isEdgeInterior(inputPatch[0].flagsDisp);
vInterior[2] = isEdgeInterior(inputPatch[1].flagsDisp);
}
// If the edge is interior, it will not be used to calculate "inner" distance
if(vInterior[0]) vEdgeFactor[0] = 0.;
if(vInterior[1]) vEdgeFactor[1] = 0.;
if(vInterior[2]) vEdgeFactor[2] = 0.;
#elif 0
// bool3 vbInterior;
// vbInterior.x = isInterior(inputPatch[0].flagsDisp);
// vbInterior.y = isInterior(inputPatch[1].flagsDisp);
// vbInterior.z = isInterior(inputPatch[2].flagsDisp);
// if( vbInterior.x && vbInterior.y && vbInterior.z ) vEdgeFactor = float3(0.,0.,0.);
// else if( vbInterior.y && vbInterior.z ) { vEdgeFactor = float3(0.,1.,1.); vInterior.x = true; }
// else if( vbInterior.z && vbInterior.x ) { vEdgeFactor = float3(1.,0.,1.); vInterior.y = true; }
// else if( vbInterior.x && vbInterior.y ) { vEdgeFactor = float3(1.,1.,0.); vInterior.z = true; }
// else vEdgeFactor = float3(1.,1.,1.);
#elif 0
// if( vbInterior.y && vbInterior.z ) { vEdgeFactor = float3(0.,1.,1.); vInterior.x = true; }
// else if( vbInterior.z && vbInterior.x ) { vEdgeFactor = float3(1.,0.,1.); vInterior.y = true; }
// else if( vbInterior.x && vbInterior.y ) { vEdgeFactor = float3(1.,1.,0.); vInterior.z = true; }
// else vEdgeFactor = float3(1.,1.,1.);
#endif
#if ADAPTIVE_TESSELLATION
float3 distanceFactor;
distanceFactor.x = computeDistance(inputPatch[0].params.worldSpacePosition.xyz, g_eyePosition);
distanceFactor.y = computeDistance(inputPatch[1].params.worldSpacePosition.xyz, g_eyePosition);
distanceFactor.z = computeDistance(inputPatch[2].params.worldSpacePosition.xyz, g_eyePosition);
/*
// Only apply LOD if the screen space triangle size is below a given threshold
float3 ab = inputPatch[0].screenSpacePosition.xyz - inputPatch[1].screenSpacePosition.xyz;
float3 ac = inputPatch[0].screenSpacePosition.xyz - inputPatch[2].screenSpacePosition.xyz;
float3 abCrossAc = cross(ab,ac);
float area2 = dot(abCrossAc, abCrossAc);
if (area2 < g_tessFactor.w)
*/
{
// Calculate edge scale factor from vertex scale factor: simply compute
// average tess factor between the two vertices making up an edge
vEdgeTessellationFactors.x = 0.5 * ( distanceFactor.y + distanceFactor.z);
vEdgeTessellationFactors.y = 0.5 * ( distanceFactor.z + distanceFactor.x);
vEdgeTessellationFactors.z = 0.5 * ( distanceFactor.x + distanceFactor.y);
vEdgeTessellationFactors.w = vEdgeTessellationFactors.x;
// Multiply them by global tessellation factor
vEdgeTessellationFactors *= g_tessFactor.xxxy;
}
#endif
// Assign tessellation levels
output.Edges[0] = vEdgeTessellationFactors.x;
output.Edges[1] = vEdgeTessellationFactors.y;
output.Edges[2] = vEdgeTessellationFactors.z;
output.Inside = vEdgeTessellationFactors.w;
output.EdgeFactors = vEdgeFactor;
output.EdgeInterior = vInterior;
output.ModelMatrix = float4x4(inputPatch[0].modelMatrix[0],
inputPatch[0].modelMatrix[1],
inputPatch[0].modelMatrix[2],
inputPatch[0].modelMatrix[3]);
return output;
}
[domain("tri")]
[partitioning("fractional_odd")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
[patchconstantfunc("ConstantsHS")]
[maxtessfactor(15.0)]
HullControlOut hmain( InputPatch<VertexOut, 3> inputPatch, uint uCPID : SV_OutputControlPointID )
{
HullControlOut output;
output.params = inputPatch[uCPID].params;
output.vWorldPos = inputPatch[uCPID].params.worldSpacePosition;
output.vLocalPos = inputPatch[uCPID].localPosition.xyz;
output.fWeightDisp = getDisplacementWeight(inputPatch[uCPID].flagsDisp);
output.uAxis = getDisplacementAxis(inputPatch[uCPID].flagsDisp);
return output;
}
//--------------------------------------------------------------------------------------
// Domain Shader
//--------------------------------------------------------------------------------------
[domain("tri")]
DomainOut dmain( HullConstOut input,
float3 BarycentricCoordinates : SV_DomainLocation,
const OutputPatch<HullControlOut, 3> inputPatch )
{
DomainOut output;
float fU = BarycentricCoordinates.x;
float fV = BarycentricCoordinates.y;
float fW = BarycentricCoordinates.z;
// Interpolate world space position with barycentric coordinates
float3 vWorldPos = fU * inputPatch[0].vWorldPos +
fV * inputPatch[1].vWorldPos +
fW * inputPatch[2].vWorldPos;
// Interpolate world space normal and renormalize it
float3 vNormal = fU * inputPatch[0].params.worldSpaceNormal +
fV * inputPatch[1].params.worldSpaceNormal +
fW * inputPatch[2].params.worldSpaceNormal;
vNormal = normalize( vNormal );
// Interpolate world space normal and renormalize it
float3 vBiNormal = fU * inputPatch[0].params.worldSpaceBinormal +
fV * inputPatch[1].params.worldSpaceBinormal+
fW * inputPatch[2].params.worldSpaceBinormal;
output.params.worldSpaceBinormal = normalize( vBiNormal );
// Interpolate world space tangent and renormalize it
float3 vTangent = fU * inputPatch[0].params.worldSpaceTangent +
fV * inputPatch[1].params.worldSpaceTangent +
fW * inputPatch[2].params.worldSpaceTangent;
output.params.worldSpaceTangent = normalize( vTangent );
// Interpolate color
output.params.color = (half)fU * inputPatch[0].params.color +
(half)fV * inputPatch[1].params.color +
(half)fW * inputPatch[2].params.color;
// Interpolate local space position with barycentric coordinates
float3 vLocalPos = fU * inputPatch[0].vLocalPos +
fV * inputPatch[1].vLocalPos +
fW * inputPatch[2].vLocalPos;
// Transform world space normal into local coordinates
float3 vLocalNormal = normalize(mul(transpose((float3x3)input.ModelMatrix), vNormal));
// Interpolate the displacement weight with barycentric coordinates
#if 1
float fWeightDisp = fU * inputPatch[0].fWeightDisp +
fV * inputPatch[1].fWeightDisp +
fW * inputPatch[2].fWeightDisp;
#else
float3 vWeightDisp = float3(fU * (1 - inputPatch[0].fWeightDisp),
fV * (1 - inputPatch[1].fWeightDisp),
fW * (1 - inputPatch[2].fWeightDisp));
float fWeightDisp = 1. - max(vWeightDisp.x, max(vWeightDisp.y, vWeightDisp.z));
#endif
#if ENABLE_INTERIOR_DISTANCE
// Compute the interior weight as a function of distance from the shorterst 2 edges
float fWeightInterior = getInteriorDistance(input.EdgeFactors, BarycentricCoordinates);
// Compose the weight as a combination of the two with range [0,1], and scale by a global factor
float fWeight = sqrt(fWeightDisp) * .5 + fWeightInterior *.5;
#else
float fWeight = sqrt(fWeightDisp);
#endif
fWeight = clamp(fWeight, 0, 1);
// Call user defined displacement function
float3 vOffset;
float3 vOffsetNormal;
computeOffsetAndNormal(vLocalPos, vLocalNormal, BarycentricCoordinates,
vOffset, vOffsetNormal);
#if ENABLE_INTERIOR_DISTANCE
// Restricts interior offsets to those projected along the face normal, and scale
vOffset = (vOffset.xyz * (1.f - fWeightInterior)) +
(dot(vOffset.xyz, vLocalNormal) * vLocalNormal * ( fWeightInterior));
#endif
// Transform the computed offset into world space
vOffset = mul((float3x3)input.ModelMatrix, vOffset);
vOffsetNormal = mul((float3x3)input.ModelMatrix, vOffsetNormal);
// Compute the final world space position
vWorldPos += vOffset * fWeight * g_tessHeightScaleAndBias.x;;
output.params.worldSpacePosition = vWorldPos;
// Compute the final world space normal
output.params.worldSpaceNormal = normalize(vNormal*(1-fWeight) + vOffsetNormal*fWeight);
// Recompute the barycentric coordinates at the displaced location
float3 newBarys = computeBarycentricCoordinates(vWorldPos, vNormal, inputPatch[0].vWorldPos, inputPatch[1].vWorldPos, inputPatch[2].vWorldPos);
fU = newBarys.x;
fV = newBarys.y;
fW = newBarys.z;
// Interpolate texcoords with the new barycentric coordinates
output.params.texcoord0 = fU * inputPatch[0].params.texcoord0 +
fV * inputPatch[1].params.texcoord0 +
fW * inputPatch[2].params.texcoord0;
output.params.texcoord1 = fU * inputPatch[0].params.texcoord1 +
fV * inputPatch[1].params.texcoord1 +
fW * inputPatch[2].params.texcoord1;
output.params.texcoord2 = fU * inputPatch[0].params.texcoord2 +
fV * inputPatch[1].params.texcoord2 +
fW * inputPatch[2].params.texcoord2;
output.params.texcoord3 = fU * inputPatch[0].params.texcoord3 +
fV * inputPatch[1].params.texcoord3 +
fW * inputPatch[2].params.texcoord3;
// Shader Debuggging
//output.params.color = half4((half)abs(vTexcoordYDisp.y), (half)0, 0, 0);
//output.params.color = half4((half)fWeight, 0, 0, 0);
//output.params.color = half4((half)input.EdgeFactors.x, (half)input.EdgeFactors.y, (half)input.EdgeFactors.z, 0);
//half4 color[3]; color[0] = color[1] = color[2] = half4(0,0,0,1);
//if( input.EdgeInterior.x ) { color[0].x = 1.; color[1].x = 1.; }
//if( input.EdgeInterior.y ) { color[1].y = 1.; color[2].y = 1.; }
//if( input.EdgeInterior.z ) { color[2].z = 1.; color[0].z = 1.; }
/*if( input.EdgeInterior.x ) { color[1].x = 1.; color[2].x = 1.; }
if( input.EdgeInterior.y ) { color[2].x = 1.; color[0].x = 1.; }
if( input.EdgeInterior.z ) { color[0].x = 1.; color[1].x = 1.; }
output.params.color = (half)fU * color[0] + (half)fV * color[1] + (half)fW * color[2];*/
//output.params.color = half4((half)isInterior(input[0].EdgeFactors.x, (half)input.EdgeFactors.y, (half)input.EdgeFactors.z, 0);
//output.params.color = half4((half)vModelNormal.x, (half)vModelNormal.y, (half)vModelNormal.z, 0);
//output.params.color = half4((half)vModelPos.x, (half)vModelPos.y, (half)vModelPos.z, 0);
//output.params.color = half4((half)s, (half)t, 0, 0);
//output.params.color = half4((half)fU, (half)fV, (half)fW, 0);
//output.params.color = half4((half)vOffset.x, (half)vOffset.y, (half)vOffset.z, 0);
//output.params.color = half4((half)fWeightInterior, (half)fWeightInterior, (half)fWeightInterior, 0);
//output.params.color = half4((half)fWeightDisp, (half)fWeightDisp, (half)fWeightDisp, 0);
/*output.params.color = half4((half)fU * inputPatch[0].fWeightDisp +
(half)fV * inputPatch[1].fWeightDisp +
(half)fW * inputPatch[2].fWeightDisp, 0, 0, 1);*/
// Transform world position with viewprojection matrix
output.screenSpacePosition = mul(g_projMatrix, mul(g_viewMatrix, float4(vWorldPos.xyz, 1.0)));
return output;
}
#endif