Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- internal void Pass(ReadOnlySpan<Float4> sourceData, ReadOnlySpan<Float4> lastPassData, Span<Float4> target) {
- var source = new Texture(this, sourceData, SourceSize);
- var prev = new Texture(this, lastPassData, SourceSize);
- for (int y = 0; y < TargetSize.Height; ++y) {
- int yOffset = GetY(y) * TargetSize.Width;
- for (int x = 0; x < TargetSize.Width; ++x) {
- int targetOffset = yOffset + GetX(x);
- Float2 sourceOffset = new Float2(
- x * 0.5f,
- y * 0.5f
- );
- Float2 fracP = CgMath.Frac(sourceOffset);
- Float2 dir = fracP - new Float2(0.5f, 0.5f);
- if ((dir.X * dir.Y) > 0.0f) { // I'm unsure how this _ever_ would not be zero? If the inputs are half the size of the output, then xy - 0.5 is always <= zero.
- target[targetOffset] = (fracP.X > 0.5) ?
- source.Sample(sourceOffset) :
- prev.Sample(sourceOffset);
- continue;
- }
- // Skip pixels on wrong grid
- // Cannot really replicate this behavior in this implementation...
- // float2 fp = frac(VAR.texCoord * IN.texture_size);
- // float2 dir = fp - float2(0.5, 0.5);
- // if ((dir.x * dir.y) > 0.0) return (fp.x > 0.5) ? tex2D(s0, VAR.texCoord) : tex2D(PASSPREV2.texture, VAR.texCoord);
- //Float2 g1 = new Float2(0.0f, 0.5f / size.Y); // half texel, source
- //Float2 g2 = new Float2(0.5f / size.X, 0.0f); // half texel, source
- // float3 P0 = tex2D(PASSPREV2.texture, VAR.texCoord - 3.0*g1 ).xyz;
- //
- Float2 g1 = (fracP.X > 0.5f) ? new Float2(0.5f, 0.0f) : new Float2(0.0f, 0.5f);
- Float2 g2 = (fracP.X > 0.5f) ? new Float2(0.0f, 0.5f) : new Float2(0.5f, 0.0f);
- var centroid = prev.Sample(sourceOffset);
- var P0 = prev.Sample(sourceOffset -3.0f*g1 ).RGB;
- var P1 = source.Sample(sourceOffset -3.0f*g2).RGB;
- var P2 = source.Sample(sourceOffset +3.0f*g2).RGB;
- var P3 = prev.Sample(sourceOffset +3.0f*g1 ).RGB;
- // float3 B = tex2D(s0, VAR.texCoord - 2.0 * g1 - g2).xyz;
- // (2 * 0.5 texels) - 0.5 texels
- // 1 texel - 0.5 texels
- // 0.5 texels should become 0 texels.
- var B = source.Sample(sourceOffset -2.0f*g1 -g2).RGB;
- var C = prev.Sample(sourceOffset -g1 -2.0f*g2).RGB;
- var D = source.Sample(sourceOffset -2.0f*g1 +g2).RGB;
- var E = prev.Sample(sourceOffset -g1 ).RGB;
- var F = source.Sample(sourceOffset -g2).RGB;
- var G = prev.Sample(sourceOffset -g1 +2.0f*g2).RGB;
- var H = source.Sample(sourceOffset +g2).RGB;
- var I = prev.Sample(sourceOffset +2.0f*g1 +g2).RGB;
- var F4 = source.Sample(sourceOffset +g1 -2.0f*g2).RGB;
- var I4 = prev.Sample(sourceOffset +2.0f*g1 -g2).RGB;
- var H5 = source.Sample(sourceOffset +g1 +2.0f*g2).RGB;
- var I5 = prev.Sample(sourceOffset +2.0f*g1 +g2).RGB;
- float b = RGBToYUV(B);
- float c = RGBToYUV(C);
- float d = RGBToYUV(D);
- float e = RGBToYUV(E);
- float f = RGBToYUV(F);
- float g = RGBToYUV(G);
- float h = RGBToYUV(H);
- float i = RGBToYUV(I);
- float i4 = RGBToYUV(I4); float p0 = RGBToYUV(P0);
- float i5 = RGBToYUV(I5); float p1 = RGBToYUV(P1);
- float h5 = RGBToYUV(H5); float p2 = RGBToYUV(P2);
- float f4 = RGBToYUV(F4); float p3 = RGBToYUV(P3);
- // Calc edgeness in diagonal directions.
- float dEdge =
- WeightedDifferenceDiagonal(d, b, g, e, c, p2, h, f, p1, h5, i, f4, i5, i4) -
- WeightedDifferenceDiagonal(c, f4, b, f, i4, p0, e, i, p3, d, h, i5, g, h5);
- // Calc edgeness in horizontal/vertical directions.
- float hvEdge =
- WeightedDifferenceHorizontalVertical(f, i, e, h, c, i5, b, h5) -
- WeightedDifferenceHorizontalVertical(e, f, h, i, d, f4, g, i4);
- float limits = Configuration.EdgeStrength + 0.000001f;
- float edgeStrength = CgMath.SmoothStep(0.0f, limits, Math.Abs(dEdge));
- // Filter weights. Two taps only.
- Float4 w1 = new(-Weight1, Weight1 + 0.5f, Weight1 + 0.5f, -Weight1);
- Float4 w2 = new(-Weight2, Weight2 + 0.25f, Weight2 + 0.25f, -Weight2);
- // Filtering and normalization in four direction generating four colors.
- Float3 c1 = CgMath.MatrixMul(w1, P2, H, F, P1);
- Float3 c2 = CgMath.MatrixMul(w1, P0, E, I, P3);
- Float3 c3 = CgMath.MatrixMul(w2, D + G, E + H, F + I, F4 + I4);
- Float3 c4 = CgMath.MatrixMul(w2, C + B, F + E, I + H, I5 + H5);
- float alpha = centroid.A;
- // Smoothly blends the two strongest directions (one in diagonal and the other in vert/horiz direction).
- Float3 color = CgMath.Lerp(
- CgMath.Lerp(c1, c2, CgMath.Step(0.0f, dEdge)),
- CgMath.Lerp(c3, c4, CgMath.Step(0.0f, hvEdge)),
- 1.0f - edgeStrength
- );
- // Anti-ringing code.
- Float3 minSample =
- CgMath.Min4(E, F, H, I) +
- (1.0f - Configuration.AntiRinging) *
- CgMath.Lerp(
- (P2 - H) * (F - P1),
- (P0 - E) * (I - P3),
- CgMath.Step(0.0f, dEdge)
- );
- Float3 maxSample =
- CgMath.Max4(E, F, H, I) -
- (1.0f - Configuration.AntiRinging) *
- CgMath.Lerp(
- (P2 - H) * (F - P1),
- (P0 - E) * (I - P3),
- CgMath.Step(0.0f, dEdge)
- );
- color = color.Clamp(minSample, maxSample);
- target[targetOffset] = new(color, alpha);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement