Skip to content

Commit 5d01387

Browse files
Temporal antialiasing using velocity on Skin meshes.
1 parent e0c614f commit 5d01387

File tree

6 files changed

+116
-46
lines changed

6 files changed

+116
-46
lines changed

h3d/scene/Skin.hx

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,10 @@ class Skin extends MultiMaterial {
269269
var jointsData : Array<JointData>; // Runtime data
270270

271271
var currentPalette : Array<h3d.Matrix>;
272+
var prevPalette : Array<h3d.Matrix>;
272273
var splitPalette : Array<Array<h3d.Matrix>>;
274+
var prevSplitPalette : Array<Array<h3d.Matrix>>;
275+
var prevJointsFrame : Int = -1;
273276
var forceJointsUpdateOnFrame : Int = -1;
274277
var jointsUpdated : Bool;
275278
var paletteChanged : Bool;
@@ -430,6 +433,8 @@ class Skin extends MultiMaterial {
430433

431434
jointsData = [];
432435
currentPalette = [];
436+
prevPalette = null;
437+
prevSplitPalette = null;
433438
paletteChanged = true;
434439
makeJointsData();
435440
for( i in 0...skinData.boundJoints.length )
@@ -457,7 +462,19 @@ class Skin extends MultiMaterial {
457462

458463
@:noDebug
459464
function syncJoints() {
460-
if( !jointsUpdated && forceJointsUpdateOnFrame != hxd.Timer.frameCount ) return;
465+
if( !jointsUpdated && forceJointsUpdateOnFrame != hxd.Timer.frameCount )
466+
return;
467+
468+
if ( computeVelocity() ) {
469+
syncPrevJoints();
470+
skinShader.calcPrevPos = true;
471+
} else {
472+
prevSplitPalette = null;
473+
prevPalette = null;
474+
skinShader.calcPrevPos = false;
475+
}
476+
477+
skinShader.calcPrevPos = computeVelocity();
461478

462479
for( j in skinData.allJoints )
463480
jointsData[j.index].sync(this, j);
@@ -467,6 +484,26 @@ class Skin extends MultiMaterial {
467484
prevEnableRetargeting = enableRetargeting;
468485
}
469486

487+
function syncPrevJoints() {
488+
if ( prevJointsFrame == hxd.Timer.frameCount )
489+
return;
490+
prevJointsFrame = hxd.Timer.frameCount;
491+
492+
if ( prevPalette == null ) {
493+
prevPalette = [];
494+
for ( _ in 0...currentPalette.length )
495+
prevPalette.push(h3d.Matrix.I());
496+
if ( splitPalette != null ) {
497+
prevSplitPalette = [];
498+
for ( a in skinData.splitJoints )
499+
prevSplitPalette.push([for ( j in a.joints ) prevPalette[j.bindIndex]]);
500+
}
501+
}
502+
for ( i => m in currentPalette )
503+
prevPalette[i].load(m);
504+
skinShader.prevBonesMatrixes = prevPalette;
505+
}
506+
470507
override function emit( ctx : RenderContext ) {
471508
calcScreenRatio(ctx);
472509
syncJoints(); // In case sync was not called because of culling (eg fixedPosition)
@@ -511,6 +548,8 @@ class Skin extends MultiMaterial {
511548
} else {
512549
var i = ctx.drawPass.index;
513550
skinShader.bonesMatrixes = splitPalette[i];
551+
if ( prevSplitPalette != null )
552+
skinShader.prevBonesMatrixes = prevSplitPalette[i];
514553
primitive.selectMaterial(i, primitive.screenRatioToLod(curScreenRatio));
515554
ctx.uploadParams();
516555
primitive.render(ctx.engine);

h3d/scene/pbr/Renderer.hx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,7 @@ class Renderer extends h3d.scene.Renderer {
760760
slides.shader.shadowMapCube = shadowMap;
761761
slides.shader.shadowIsCube = shadowMap.flags.has(Cube);
762762
slides.shader.shadowMapChannel = R;
763+
slides.shader.velocity = textures.velocity;
763764
pbrProps.isScreen = true;
764765
slides.render();
765766
if( !debugging ) {
@@ -792,20 +793,22 @@ class Renderer extends h3d.scene.Renderer {
792793
var win = hxd.Window.getInstance();
793794

794795
if( e.kind == ERelease && e.button == 2 && hxd.Math.distance(e.relX-debugPushPos.x,e.relY-debugPushPos.y) < 10 ) {
795-
var x = Std.int((e.relX / win.width) * 4);
796-
var y = Std.int((e.relY / win.height) * 4);
796+
var x = Std.int((e.relX / win.width) * 3);
797+
var y = Std.int((e.relY / win.height) * 3);
797798
if( slides.shader.mode != Full ) {
798799
slides.shader.mode = Full;
799800
} else {
800801
var a : Array<h3d.shader.pbr.Slides.DebugMode>;
801-
if( y == 3 )
802-
a = [Emmissive,Depth,AO,Shadow];
802+
if( y == 0 )
803+
a = [Albedo,Normal,Depth];
804+
else if ( y == 1 )
805+
a = [Metalness,Roughness,AO];
803806
else
804-
a = [Albedo,Normal,Roughness,Metalness];
807+
a = [Emissive,Shadow,Velocity];
805808
slides.shader.mode = a[x];
806809
}
807810
}
808-
if( e.kind == EWheel && (slides.shader.mode == Shadow || (slides.shader.mode == Full && e.relX > win.width/4 && e.relY > win.height/4)) )
811+
if( e.kind == EWheel && (slides.shader.mode == Shadow || (slides.shader.mode == Full && e.relX > win.width/3 && e.relY > win.height/3)) )
809812
debugShadowMapIndex += e.wheelDelta > 0 ? 1 : -1;
810813
}
811814

h3d/shader/Skin.hx

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,24 +43,36 @@ class Skin extends SkinBase {
4343
var indexes : Bytes4;
4444
};
4545

46-
var transformedTangent : Vec4;
4746
var previousTransformedPosition : Vec3;
4847

4948
function vertex() {
49+
if ( calcPrevPos ) {
50+
boneMatrixX = prevBonesMatrixes[int(input.indexes.x)];
51+
boneMatrixY = prevBonesMatrixes[int(input.indexes.y)];
52+
boneMatrixZ = prevBonesMatrixes[int(input.indexes.z)];
53+
boneMatrixW = prevBonesMatrixes[int(input.indexes.w)];
54+
skinWeights = vec4(input.weights, 0.0);
55+
if ( fourBonesByVertex )
56+
skinWeights.w = 1 - (input.weights.x + input.weights.y + input.weights.z);
57+
58+
previousTransformedPosition = applySkinPoint(relativePosition);
59+
}
60+
5061
boneMatrixX = bonesMatrixes[int(input.indexes.x)];
5162
boneMatrixY = bonesMatrixes[int(input.indexes.y)];
5263
boneMatrixZ = bonesMatrixes[int(input.indexes.z)];
5364
boneMatrixW = bonesMatrixes[int(input.indexes.w)];
5465
skinWeights = vec4(input.weights, 0.0);
55-
if(fourBonesByVertex) {
66+
if ( fourBonesByVertex )
5667
skinWeights.w = 1 - (input.weights.x + input.weights.y + input.weights.z);
57-
}
5868

5969
transformedPosition = applySkinPoint(relativePosition);
6070
transformedNormal = applySkinVec(input.normal);
6171

62-
previousTransformedPosition = transformedPosition;
6372
transformedNormal = normalize(transformedNormal);
73+
74+
if ( !calcPrevPos )
75+
previousTransformedPosition = transformedPosition;
6476
}
6577
};
6678
}

h3d/shader/SkinBase.hx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ class SkinBase extends hxsl.Shader {
1010

1111
@const var MaxBones : Int;
1212
@const @param var fourBonesByVertex = false;
13+
@const var calcPrevPos : Bool = false;
1314

1415
@ignore @param var bonesMatrixes : Array<Mat3x4,MaxBones>;
15-
16+
@ignore @param var prevBonesMatrixes : Array<Mat3x4,MaxBones>;
1617
};
1718

1819
public function new() {

h3d/shader/SkinTangent.hx

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ class SkinTangent extends SkinBase {
44

55
static var SRC = {
66

7+
@:import h3d.shader.Skin.Utils;
8+
79
@input var input : {
810
var position : Vec3;
911
var normal : Vec3;
@@ -13,30 +15,38 @@ class SkinTangent extends SkinBase {
1315
};
1416

1517
var transformedTangent : Vec4;
18+
var previousTransformedPosition : Vec3;
1619

1720
function vertex() {
18-
transformedPosition =
19-
(relativePosition * bonesMatrixes[int(input.indexes.x)]) * input.weights.x +
20-
(relativePosition * bonesMatrixes[int(input.indexes.y)]) * input.weights.y +
21-
(relativePosition * bonesMatrixes[int(input.indexes.z)]) * input.weights.z;
22-
transformedNormal =
23-
(input.normal * mat3(bonesMatrixes[int(input.indexes.x)])) * input.weights.x +
24-
(input.normal * mat3(bonesMatrixes[int(input.indexes.y)])) * input.weights.y +
25-
(input.normal * mat3(bonesMatrixes[int(input.indexes.z)])) * input.weights.z;
26-
transformedTangent.xyz =
27-
(input.tangent.xyz * mat3(bonesMatrixes[int(input.indexes.x)])) * input.weights.x +
28-
(input.tangent.xyz * mat3(bonesMatrixes[int(input.indexes.y)])) * input.weights.y +
29-
(input.tangent.xyz * mat3(bonesMatrixes[int(input.indexes.z)])) * input.weights.z;
30-
31-
if(fourBonesByVertex) {
32-
var w4 = 1 - (input.weights.x + input.weights.y + input.weights.z);
33-
transformedPosition += (relativePosition * bonesMatrixes[int(input.indexes.w)]) * w4;
34-
transformedNormal += (input.normal * mat3(bonesMatrixes[int(input.indexes.z)])) * w4;
35-
transformedTangent.xyz += (input.tangent.xyz * mat3(bonesMatrixes[int(input.indexes.w)])) * w4;
21+
if ( calcPrevPos ) {
22+
boneMatrixX = prevBonesMatrixes[int(input.indexes.x)];
23+
boneMatrixY = prevBonesMatrixes[int(input.indexes.y)];
24+
boneMatrixZ = prevBonesMatrixes[int(input.indexes.z)];
25+
boneMatrixW = prevBonesMatrixes[int(input.indexes.w)];
26+
skinWeights = vec4(input.weights, 0.0);
27+
if ( fourBonesByVertex )
28+
skinWeights.w = 1 - (input.weights.x + input.weights.y + input.weights.z);
29+
30+
previousTransformedPosition = applySkinPoint(relativePosition);
3631
}
37-
32+
33+
boneMatrixX = bonesMatrixes[int(input.indexes.x)];
34+
boneMatrixY = bonesMatrixes[int(input.indexes.y)];
35+
boneMatrixZ = bonesMatrixes[int(input.indexes.z)];
36+
boneMatrixW = bonesMatrixes[int(input.indexes.w)];
37+
skinWeights = vec4(input.weights, 0.0);
38+
if ( fourBonesByVertex )
39+
skinWeights.w = 1 - (input.weights.x + input.weights.y + input.weights.z);
40+
41+
transformedPosition = applySkinPoint(relativePosition);
42+
transformedNormal = applySkinVec(input.normal);
43+
transformedTangent.xyz = applySkinVec(input.tangent.xyz);
44+
3845
transformedNormal = normalize(transformedNormal);
3946
transformedTangent.xyz = normalize(transformedTangent.xyz);
47+
48+
if ( !calcPrevPos )
49+
previousTransformedPosition = transformedPosition;
4050
}
4151

4252
};

h3d/shader/pbr/Slides.hx

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ enum abstract DebugMode(Int) {
44
var Full = 0;
55
var Albedo = 1;
66
var Normal = 2;
7-
var Roughness = 3;
7+
var Depth = 3;
88
var Metalness = 4;
9-
var Emmissive = 5;
10-
var Depth = 6;
11-
var AO = 7;
9+
var Roughness = 5;
10+
var AO = 6;
11+
var Emissive = 7;
1212
var Shadow = 8;
13+
var Velocity = 9;
1314
}
1415

1516
class Slides extends ScreenShader {
@@ -28,28 +29,30 @@ class Slides extends ScreenShader {
2829

2930
@param var shadowMap : Channel;
3031
@param var shadowMapCube : SamplerCube;
32+
@param var velocity : Sampler2D;
3133
@const var shadowIsCube : Bool;
3234
@const var smode : Int;
3335

3436
function getColor(x:Float,y:Float) : Vec3 {
3537
var color : Vec3;
36-
if( y < 3 ) {
38+
if( y < 1 ) {
3739
if( x < 1 )
3840
color = albedo.sqrt();
3941
else if( x < 2 )
4042
color = packNormal(normal).rgb;
41-
else if( x < 3 )
42-
color = roughness.xxx;
4343
else
44-
color = metalness.xxx;
45-
} else {
44+
color = depth.xxx;
45+
} else if ( y < 2 ) {
4646
if( x < 1 )
47-
color = vec3(emissive, custom1, custom2);
47+
color = metalness.xxx;
4848
else if( x < 2 )
49-
color = depth.xxx;
49+
color = roughness.xxx;
5050
else if( x < 3 )
5151
color = occlusion.xxx;
52-
else {
52+
} else {
53+
if ( x < 1 )
54+
color = vec3(emissive, custom1, custom2);
55+
else if ( x < 2 ) {
5356
var uv = vec2(x,y) - 3;
5457
if( shadowIsCube ) {
5558
var phi = (1 - uv.x)*3.1415*2;
@@ -58,19 +61,21 @@ class Slides extends ScreenShader {
5861
color = shadowMapCube.get(dir).xxx;
5962
} else
6063
color = shadowMap.get(uv).xxx;
64+
} else {
65+
color = packNormal(velocity.get(input.uv).xyz * 100.0).xyz;
6166
}
6267
}
6368
return color;
6469
}
6570

6671
function fragment() {
6772
var color : Vec3;
68-
var x = input.uv.x * 4;
69-
var y = input.uv.y * 4;
73+
var x = input.uv.x * 3;
74+
var y = input.uv.y * 3;
7075
if( smode == 0 )
7176
color = getColor(x,y);
7277
else
73-
color = getColor( (smode - 1)%4 + input.uv.x, int((smode - 1) / 4) * 3 + input.uv.y );
78+
color = getColor( (smode - 1)%3 + input.uv.x, int((smode - 1) / 3) + input.uv.y );
7479
pixelColor = vec4(color, 1.);
7580
}
7681
};

0 commit comments

Comments
 (0)