161 lines
5.1 KiB
HLSL
161 lines
5.1 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
#include "/Engine/Public/Platform.ush"
|
|
#include "/Plugin/TextureGraph/SamplerStates.ush"
|
|
#include "/Plugin/TextureGraph/TileInfo.ush"
|
|
#include "/Plugin/TextureGraph/Paint.ush"
|
|
|
|
Texture2D SourceTexture;
|
|
float4 FillColor;
|
|
|
|
float CoverageX;
|
|
float CoverageY;
|
|
|
|
float TranslationX;
|
|
float TranslationY;
|
|
|
|
float PivotX;
|
|
float PivotY;
|
|
|
|
float RotationX;
|
|
float RotationY;
|
|
|
|
float ScaleX;
|
|
float ScaleY;
|
|
|
|
float FilterMode;
|
|
float MirrorX;
|
|
float MirrorY;
|
|
|
|
float StaggerX;
|
|
float StaggerY;
|
|
|
|
float StrideX;
|
|
float StrideY;
|
|
|
|
float Zoom;
|
|
float StretchToFit;
|
|
float SpacingX;
|
|
float SpacingY;
|
|
|
|
float CellScaling;
|
|
|
|
|
|
float BlendDebugGrid;
|
|
|
|
float MaskBox(in float2 uv, in float2 minValue, in float2 maxValue)
|
|
{
|
|
float2 masked = step(minValue, uv) * step(uv, maxValue);
|
|
return min(masked.x, masked.y);
|
|
}
|
|
float MaskBox(in float2 uv, in float minValue, in float maxValue)
|
|
{
|
|
return MaskBox(uv, float2(minValue, minValue), float2(maxValue, maxValue));
|
|
}
|
|
|
|
float4 FSH_TransformBlit(float2 uv : TEXCOORD0) : SV_Target0
|
|
{
|
|
float2 layerPos = TileInfo_fromCurrentTileToLayer(uv);
|
|
float2 layerResolution = TileInfo_layerResolution();
|
|
float2 pixelSize = rcp(layerResolution);
|
|
float LayerAspectRatio = layerResolution.x/layerResolution.y;
|
|
|
|
float2 Coverage = float2(CoverageX, CoverageY);
|
|
float2 Translation = float2(TranslationX, TranslationY);
|
|
float2 Pivot = float2(PivotX, PivotY) * Coverage; // Pivot is applied in the normalized Coverage rectangle
|
|
float2 Rotation = float2(RotationX, RotationY);
|
|
float2 Scale = float2(ScaleX, ScaleY);
|
|
|
|
float2 Stagger = float2(StaggerX, StaggerY);
|
|
int2 Stride = int2(StrideX, StrideY);
|
|
|
|
// TilePos is the going to be the uv of the pixel on which we are going to apply the transformation steps
|
|
// Frst of all flip the y to work with Y up
|
|
float2 tilePos = float2(layerPos.x, 1.0 - layerPos.y);
|
|
|
|
// Apply translation
|
|
tilePos -= Translation;
|
|
|
|
// Apply the pivot and rotation
|
|
tilePos -= Pivot;
|
|
tilePos = float2(dot(tilePos, Rotation), dot(tilePos, float2(-Rotation.y, Rotation.x)));
|
|
tilePos += Pivot;
|
|
|
|
// eval the tile grid mask for debug
|
|
float tileGridMask = Paint_Grid(tilePos, 1.0, length(pixelSize) * 4);
|
|
|
|
// Eval the coverage mask, wrap it on the neighboor tiles or not
|
|
float2 filteredTilePos = (FilterMode > 0.0 ? frac(tilePos) : tilePos);
|
|
float CoverageMask = MaskBox(filteredTilePos, 0, Coverage);
|
|
|
|
// focus on the cell domain inside of the tile
|
|
float2 cellPos = tilePos - floor(tilePos);
|
|
|
|
// eval debug mask for coverage box and the Pivot point
|
|
float coverageGridMask = CoverageMask * Paint_BoxEdge(cellPos, 0, Coverage, 0, pixelSize * 3);
|
|
float pivotMask = Paint_BoxEdge(tilePos, Pivot, Pivot, pixelSize * 6, -pixelSize * 3);
|
|
|
|
// Aspect ratio of the uv space is going follow scaling transformations
|
|
float UVAspectRatio = 1.0;
|
|
|
|
// apply coverage scaling
|
|
cellPos /= Coverage;
|
|
UVAspectRatio *= (Coverage.x / Coverage.y);
|
|
pixelSize /= Coverage;
|
|
|
|
// apply scaling
|
|
cellPos *= Scale;
|
|
UVAspectRatio *= (Scale.y / Scale.x);
|
|
pixelSize *= Scale;
|
|
|
|
// apply stagger
|
|
cellPos -= floor(cellPos).yx * Stagger;
|
|
|
|
// Eval the staggered grid for debug
|
|
float stagGridMask = CoverageMask * Paint_BoxEdge(cellPos, 0, 1.0, 0.0, pixelSize * 2.5 );
|
|
|
|
// apply stride effect as a mask
|
|
int2 cellTilePos = int2(floor(cellPos)); // this is the cell tile coordinate
|
|
int2 StrideCell = (cellTilePos % (1 + Stride));
|
|
float StrideMask = (float((StrideCell.x == 0) && (StrideCell.y == 0)));
|
|
|
|
// Eval spacing as a stretching to respect the aspect ratio or not
|
|
float2 spacing = lerp(float2(0, 1 - (UVAspectRatio)), float2(1 - rcp(UVAspectRatio), 0), (UVAspectRatio > 1.0));
|
|
spacing = lerp(spacing, float2(SpacingX, SpacingY), StretchToFit);
|
|
|
|
// Eval the spaced cell pos
|
|
// we do a simple remap of the cellPos from [half_spacing, 1 - half_spacing] to [0, 1]
|
|
float2 spacedCellPos = ( (cellPos - cellTilePos) - spacing * 0.5) / (1 - spacing);
|
|
|
|
// and a last scaling to apply the zoom control
|
|
float scaling = rcp(max(length(pixelSize), Zoom));
|
|
spacedCellPos = ((spacedCellPos * 2 - 1) * scaling) * 0.5 + 0.5;
|
|
|
|
// Eval the cell grid masked for debug
|
|
float cellGridMask = CoverageMask * Paint_BoxEdge(spacedCellPos, 0, 1.0, -pixelSize * 0.5, pixelSize * 1.25);
|
|
|
|
|
|
// also compute the mask for spacedCell and exclude anything out of the [0,1] box
|
|
float CellMask = MaskBox(spacedCellPos, 0, 1);
|
|
CoverageMask *= CellMask;
|
|
|
|
// Finally fetch the source texture
|
|
float2 fetchPos = spacedCellPos;
|
|
|
|
// Apply mirroring to uvs
|
|
fetchPos.x = lerp(fetchPos.x, 1.0 - fetchPos.x, MirrorX);
|
|
fetchPos.y = lerp(1.0 - fetchPos.y, fetchPos.y, MirrorY);
|
|
|
|
float4 SourceColor = float4(0, 0, 0, 1);
|
|
SourceColor = SourceTexture.Sample(SamplerStates_Linear_Wrap, fetchPos);
|
|
|
|
float4 Color = lerp(FillColor, SourceColor, (CoverageMask * StrideMask * SourceColor.a));
|
|
|
|
Color = lerp(Color, float4(1, 1, 0, 1), BlendDebugGrid * tileGridMask);
|
|
Color = lerp(Color, float4(0, 1, 1, 1), BlendDebugGrid * coverageGridMask);
|
|
//Color = lerp(Color, float4(1, 0.5, 0, 1), BlendDebugGrid * stagGridMask);
|
|
Color = lerp(Color, float4(1, 0, 1, 1), BlendDebugGrid * cellGridMask);
|
|
Color = lerp(Color, float4(0, 1, 1, 1), BlendDebugGrid * pivotMask);
|
|
|
|
return Color;
|
|
}
|