Graphics/Shaders: Add support for DistanceDepth (aka point-light shadow maps)
This commit is contained in:
parent
b3a43eb5ed
commit
addbb98671
|
|
@ -8,6 +8,7 @@ import SkinLinearPosition from Engine.SkinningLinear;
|
||||||
|
|
||||||
// Pass-specific options
|
// Pass-specific options
|
||||||
option DepthPass: bool = false;
|
option DepthPass: bool = false;
|
||||||
|
option DistanceDepth: bool = false;
|
||||||
|
|
||||||
// Material options
|
// Material options
|
||||||
option HasBaseColorTexture: bool = false;
|
option HasBaseColorTexture: bool = false;
|
||||||
|
|
@ -62,20 +63,22 @@ external
|
||||||
[tag("SkeletalData")] skeletalData: uniform[SkeletalData]
|
[tag("SkeletalData")] skeletalData: uniform[SkeletalData]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fragment stage
|
struct VertToFrag
|
||||||
struct FragIn
|
|
||||||
{
|
{
|
||||||
[location(0), cond(HasUV)] uv: vec2[f32],
|
[location(0)] worldPos: vec3[f32],
|
||||||
[location(1), cond(HasColor)] color: vec4[f32]
|
[location(1), cond(HasUV)] uv: vec2[f32],
|
||||||
|
[location(2), cond(HasColor)] color: vec4[f32],
|
||||||
|
[builtin(position)] position: vec4[f32]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fragment stage
|
||||||
struct FragOut
|
struct FragOut
|
||||||
{
|
{
|
||||||
[location(0)] RenderTarget0: vec4[f32]
|
[location(0)] RenderTarget0: vec4[f32],
|
||||||
|
[builtin(frag_depth), cond(DistanceDepth)] fragdepth: f32
|
||||||
}
|
}
|
||||||
|
|
||||||
[entry(frag), cond(!DepthPass || AlphaTest)]
|
fn ComputeColor(input: VertToFrag) -> vec4[f32]
|
||||||
fn main(input: FragIn) -> FragOut
|
|
||||||
{
|
{
|
||||||
let color = settings.BaseColor;
|
let color = settings.BaseColor;
|
||||||
|
|
||||||
|
|
@ -85,12 +88,19 @@ fn main(input: FragIn) -> FragOut
|
||||||
const if (HasColor)
|
const if (HasColor)
|
||||||
color *= input.color;
|
color *= input.color;
|
||||||
|
|
||||||
const if (HasUV && HasBaseColorTexture)
|
const if (HasBaseColorTexture)
|
||||||
color *= MaterialBaseColorMap.Sample(input.uv);
|
color *= MaterialBaseColorMap.Sample(input.uv);
|
||||||
|
|
||||||
const if (HasUV && HasAlphaTexture)
|
const if (HasAlphaTexture)
|
||||||
color.w *= MaterialAlphaMap.Sample(input.uv).x;
|
color.w *= MaterialAlphaMap.Sample(input.uv).x;
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
[entry(frag), cond(!DepthPass || AlphaTest)]
|
||||||
|
fn main(input: VertToFrag) -> FragOut
|
||||||
|
{
|
||||||
|
let color = ComputeColor(input);
|
||||||
const if (AlphaTest)
|
const if (AlphaTest)
|
||||||
{
|
{
|
||||||
if (color.w < settings.AlphaThreshold)
|
if (color.w < settings.AlphaThreshold)
|
||||||
|
|
@ -102,9 +112,41 @@ fn main(input: FragIn) -> FragOut
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dummy fragment shader (TODO: Add a way to delete stage?)
|
// Shadow passes entries
|
||||||
[entry(frag), cond(DepthPass && !AlphaTest)]
|
[entry(frag), cond(DepthPass && DistanceDepth)]
|
||||||
fn main() {}
|
[depth_write(replace)]
|
||||||
|
fn main(input: VertToFrag) -> FragOut
|
||||||
|
{
|
||||||
|
let color = ComputeColor(input);
|
||||||
|
const if (AlphaTest)
|
||||||
|
{
|
||||||
|
if (color.w < settings.AlphaThreshold)
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
let output: FragOut;
|
||||||
|
output.RenderTarget0 = color;
|
||||||
|
|
||||||
|
let dist = distance(viewerData.eyePosition, input.worldPos);
|
||||||
|
output.fragdepth = dist / viewerData.farPlane;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
[entry(frag), cond(DepthPass && AlphaTest && !DistanceDepth)]
|
||||||
|
fn main(input: VertToFrag) -> FragOut
|
||||||
|
{
|
||||||
|
let color = ComputeColor(input);
|
||||||
|
if (color.w < settings.AlphaThreshold)
|
||||||
|
discard;
|
||||||
|
|
||||||
|
let output: FragOut;
|
||||||
|
output.RenderTarget0 = color;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
[entry(frag), cond(DepthPass && !AlphaTest && !DistanceDepth)]
|
||||||
|
fn main() {} //< dummy
|
||||||
|
|
||||||
// Vertex stage
|
// Vertex stage
|
||||||
struct VertIn
|
struct VertIn
|
||||||
|
|
@ -134,15 +176,8 @@ struct VertIn
|
||||||
billboardColor: vec4[f32]
|
billboardColor: vec4[f32]
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VertOut
|
|
||||||
{
|
|
||||||
[location(0), cond(HasUV)] uv: vec2[f32],
|
|
||||||
[location(1), cond(HasColor)] color: vec4[f32],
|
|
||||||
[builtin(position)] position: vec4[f32]
|
|
||||||
}
|
|
||||||
|
|
||||||
[entry(vert), cond(Billboard)]
|
[entry(vert), cond(Billboard)]
|
||||||
fn billboardMain(input: VertIn) -> VertOut
|
fn billboardMain(input: VertIn) -> VertToFrag
|
||||||
{
|
{
|
||||||
let size = input.billboardSizeRot.xy;
|
let size = input.billboardSizeRot.xy;
|
||||||
let sinCos = input.billboardSizeRot.zw;
|
let sinCos = input.billboardSizeRot.zw;
|
||||||
|
|
@ -160,8 +195,11 @@ fn billboardMain(input: VertIn) -> VertOut
|
||||||
vertexPos += cameraRight * rotatedPosition.x;
|
vertexPos += cameraRight * rotatedPosition.x;
|
||||||
vertexPos += cameraUp * rotatedPosition.y;
|
vertexPos += cameraUp * rotatedPosition.y;
|
||||||
|
|
||||||
let output: VertOut;
|
let worldPosition = instanceData.worldMatrix * vec4[f32](vertexPos, 1.0);
|
||||||
output.position = viewerData.viewProjMatrix * instanceData.worldMatrix * vec4[f32](vertexPos, 1.0);
|
|
||||||
|
let output: VertToFrag;
|
||||||
|
output.worldPos = worldPosition.xyz;
|
||||||
|
output.position = viewerData.viewProjMatrix * worldPosition;
|
||||||
|
|
||||||
const if (HasColor)
|
const if (HasColor)
|
||||||
output.color = input.billboardColor;
|
output.color = input.billboardColor;
|
||||||
|
|
@ -173,7 +211,7 @@ fn billboardMain(input: VertIn) -> VertOut
|
||||||
}
|
}
|
||||||
|
|
||||||
[entry(vert), cond(!Billboard)]
|
[entry(vert), cond(!Billboard)]
|
||||||
fn main(input: VertIn) -> VertOut
|
fn main(input: VertIn) -> VertToFrag
|
||||||
{
|
{
|
||||||
let pos: vec3[f32];
|
let pos: vec3[f32];
|
||||||
|
|
||||||
|
|
@ -194,7 +232,8 @@ fn main(input: VertIn) -> VertOut
|
||||||
|
|
||||||
let worldPosition = instanceData.worldMatrix * vec4[f32](pos, 1.0);
|
let worldPosition = instanceData.worldMatrix * vec4[f32](pos, 1.0);
|
||||||
|
|
||||||
let output: VertOut;
|
let output: VertToFrag;
|
||||||
|
output.worldPos = worldPosition.xyz;
|
||||||
output.position = viewerData.viewProjMatrix * worldPosition;
|
output.position = viewerData.viewProjMatrix * worldPosition;
|
||||||
|
|
||||||
const if (HasColor)
|
const if (HasColor)
|
||||||
|
|
|
||||||
|
|
@ -212,13 +212,10 @@ fn main(input: VertToFrag) -> FragOut
|
||||||
let lightProjPos = light.viewProjMatrices[cascadeIndex] * vec4[f32](input.worldPos, 1.0);
|
let lightProjPos = light.viewProjMatrices[cascadeIndex] * vec4[f32](input.worldPos, 1.0);
|
||||||
let shadowCoords = lightProjPos.xyz / lightProjPos.w;
|
let shadowCoords = lightProjPos.xyz / lightProjPos.w;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// calculate bias (based on depth map resolution and slope)
|
// calculate bias (based on depth map resolution and slope)
|
||||||
let bias = max(0.05 * (1.0 - lambert), 0.005);
|
let bias = max(0.05 * (1.0 - lambert), 0.005);
|
||||||
bias *= 1.0 / (light.cascadeDistances[cascadeIndex] * 0.05);
|
bias *= 1.0 / (light.cascadeDistances[cascadeIndex] * 0.05);
|
||||||
|
|
||||||
//shadowFactor = shadowMapsDirectional[lightIndex].SampleDepthComp(vec3[f32](shadowCoords.xy, f32(cascadeIndex)), shadowCoords.z).r;
|
|
||||||
shadowFactor = 0.0;
|
shadowFactor = 0.0;
|
||||||
[unroll]
|
[unroll]
|
||||||
for x in -1 -> 2
|
for x in -1 -> 2
|
||||||
|
|
@ -380,7 +377,7 @@ fn main(input: VertToFrag) -> FragOut
|
||||||
}
|
}
|
||||||
|
|
||||||
let output: FragOut;
|
let output: FragOut;
|
||||||
output.RenderTarget0 = ComputeColor(input);
|
output.RenderTarget0 = color;
|
||||||
|
|
||||||
let dist = distance(viewerData.eyePosition, input.worldPos);
|
let dist = distance(viewerData.eyePosition, input.worldPos);
|
||||||
output.fragdepth = dist / viewerData.farPlane;
|
output.fragdepth = dist / viewerData.farPlane;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue