Add Games File

This commit is contained in:
Ivan Anikin
2026-05-19 13:42:41 +07:00
parent 7908479e0c
commit 12e7e22c1a
3672 changed files with 125922 additions and 0 deletions
@@ -0,0 +1,426 @@
#include "/Engine/Public/Platform.ush"
#include "/Engine/Private/Common.ush"
#include "/Engine/Generated/UniformBuffers/View.ush"
//#include "SceneTexturesCommon.ush"
//DECLARE_UNIFORM_BUFFER(View);
RWTexture2D<float4> SceneColorTexture;
RWTexture2D<float4> BaseColorTexture;
Texture2D NormalTexture;
Texture2D<float> SceneDepthTexture;
Texture2D CustomDepthTexture;
Texture2D<uint2> CustomStencilTexture;
//Texture2D SceneDepthTexture : register(t0);
//SamplerState DepthSampler : register(s0);
//SamplerState InputSampler;
float3 CameraPosition;
float3 CameraForwardVector;
float UseCustomLightPosition;
float3 LightPosition;
float3 LightDirection;
float UseCustomLightColor;
float3 LightColor;
float LightScale;
float RimEdgeFade;
float UseBinaryEdge;
float RimEdgeBinaryRange;
float SampleScreenScale;
float SampleScale;
int CustomStencilMask;
// for UE5.2
#ifndef DFHackToFloat
#define DFHackToFloat LWCHackToFloat
#endif
#define GROUP_SIZE 8 // スレッドグループサイズ
//#define FILTER_RADIUS 2 // フィルター範囲 (ハロー)
// 共有メモリ: 色データ用
//groupshared float4 SharedColorTile[GROUP_SIZE + FILTER_RADIUS * 2][GROUP_SIZE + FILTER_RADIUS * 2];
// 共有メモリ: Stencilデータ用 (uintで効率化)
//groupshared uint SharedStencilTile[GROUP_SIZE + FILTER_RADIUS * 2][GROUP_SIZE + FILTER_RADIUS * 2];
float GetLinearDepth_raw(uint2 pixelCoord)
{
float DeviceZ = SceneDepthTexture[pixelCoord];
return ConvertFromDeviceZ(DeviceZ);
}
float GetLinearDepth(float2 UV, uint2 pixelCoord)
{
float DeviceZ = SceneDepthTexture[pixelCoord];
return ConvertFromDeviceZ(DeviceZ);
}
float3 LocalGetCameraVector(float2 UV){
// Convert UV to NDC (Normalized Device Coordinates)
float2 NDC_xy = UV * 2.0f - 1.0f;
NDC_xy.y = -NDC_xy.y; // Flip Y for DirectX coordinate system
// Assume far plane (Z=1 in clip space for direction)
float4 ClipSpace = float4(NDC_xy, 1.0f, 1.0f);
// Unproject to View Space using ClipToView (inverse projection)
float4 ViewSpace = mul(ClipSpace, View.ClipToView);
ViewSpace /= ViewSpace.w; // Perspective divide
float3 ViewDir = normalize(ViewSpace.xyz);
// Convert View direction to World space
float3 WorldDir = mul(ViewDir, (float3x3)View.ViewToTranslatedWorld);
WorldDir = normalize(WorldDir);
return WorldDir;
}
MaterialFloat2 ViewportUVToSceneTextureUV2(MaterialFloat2 ViewportUV, const uint SceneTextureId)
{
/*
if (IsPostProcessInputSceneTexture(SceneTextureId))
{
switch (SceneTextureId)
{
case PPI_PostProcessInput0:
return ViewportUV * PostProcessInput_0_UVViewportSize + PostProcessInput_0_UVViewportMin;
case PPI_PostProcessInput1:
return ViewportUV * PostProcessInput_1_UVViewportSize + PostProcessInput_1_UVViewportMin;
case PPI_PostProcessInput2:
return ViewportUV * PostProcessInput_2_UVViewportSize + PostProcessInput_2_UVViewportMin;
case PPI_PostProcessInput3:
return ViewportUV * PostProcessInput_3_UVViewportSize + PostProcessInput_3_UVViewportMin;
case PPI_PostProcessInput4:
return ViewportUV * PostProcessInput_4_UVViewportSize + PostProcessInput_4_UVViewportMin;
default:
return ViewportUV;
}
}
*/
return ViewportUVToBufferUV(ViewportUV);
}
float2 LocalGetScreenPositionForProjectionType(float2 ScreenPosition, float SceneDepth)
{
// For perspective projection matrix, the scene depth is required as part of the clip to view calculations
// For orthogonal projection matrix, scene depth should not be used
//return select(IsOrthoProjection(), ScreenPosition, ScreenPosition * SceneDepth);
return ScreenPosition * SceneDepth;
}
float3 LocalGetWorldPositionFromScreenUV_raw(float2 ScreenUV, uint2 pixelCoord)
{
float2 uv = ViewportUVToSceneTextureUV2((ScreenUV), 1);
float3 depth = GetLinearDepth(ScreenUV, pixelCoord);//SceneTextureLookup(uv, 1, false).rgb;
float2 screen = (uv - View.ScreenPositionScaleBias.wz) / View.ScreenPositionScaleBias.xy;
return mul(float4(LocalGetScreenPositionForProjectionType(screen, depth.x), depth.x, 1), DFHackToFloat(PrimaryView.ScreenToWorld)).xyz;
}
float3 LocalGetWorldPositionFromScreenUV(float2 ScreenUV)
{
return LocalGetWorldPositionFromScreenUV_raw(ScreenUV, ScreenUV * View.ViewSizeAndInvSize.xy);
}
[numthreads(GROUP_SIZE, GROUP_SIZE, 1)]
void MainCS(uint3 DispatchThreadID : SV_DispatchThreadID)
{
#if FEATURE_LEVEL >= FEATURE_LEVEL_SM6
// テクスチャ全体サイズ
uint width, height;
SceneColorTexture.GetDimensions(width, height);
// ビューに表示されているピクセル数:View.ViewSizeAndInvSize.xy
const float2 ViewSize = View.ViewSizeAndInvSize.xy;
// このスレッドで書き込み対象にしている座標
const uint2 pixelCoord = DispatchThreadID.xy;
// ビューに対して 0-1 で示したもの
const float2 ScreenUV = float2(pixelCoord.x, pixelCoord.y) / View.ViewSizeAndInvSize.xy;
// WorldPos
const float3 WorldPosition = LocalGetWorldPositionFromScreenUV_raw(ScreenUV, pixelCoord);
const float LinearDepth = GetLinearDepth(ScreenUV, pixelCoord);
//
if ((CustomStencilTexture[pixelCoord].y & CustomStencilMask)) {
if (SceneDepthTexture[pixelCoord] <= CustomDepthTexture[pixelCoord].r) {
// Normal
float3 PackedNormal = NormalTexture[pixelCoord].xyz;
float3 WorldNormal = PackedNormal * 2.0 - 1.0; // [-1, 1]に変換
// 光源への方向ベクトル
//float3 LocalLightDirection = View.DirectionalLightDirection;
float3 LocalLightDirection = LightDirection;
if (UseCustomLightPosition) {
LocalLightDirection = normalize(LightPosition - WorldPosition);
}
LocalLightDirection = normalize(LocalLightDirection);
// 法線とライトを考慮してフェード
float NormalWeight = 1.f;
if (dot(PackedNormal, PackedNormal) == 0.f) {
// for unlit (no normal)
// 常にrimを出す 1
} else {
NormalWeight = dot(WorldNormal, LocalLightDirection);
NormalWeight = saturate(NormalWeight);
if (UseBinaryEdge) {
// エッジを2値にする
NormalWeight = (NormalWeight >= RimEdgeBinaryRange) ? 1.f : 0.f;
} else {
// エッジ フェード
NormalWeight = pow(NormalWeight, RimEdgeFade);
}
}
{
//SceneColorTexture[pixelCoord].xyz = fmod(abs(WorldPosition), 10) / 10;
//return;
}
{
float a = normalize(CameraPosition - WorldPosition);
if (dot(LocalLightDirection, a) <= 0) {
//NormalWeight = 0;
}
}
if (NormalWeight > 0.f) {
// 平面にて ライトベクトル
float4 ClipLightDir = mul(float4(-LocalLightDirection, 0.0), View.RelativeWorldToClip);
ClipLightDir.xyz = normalize(ClipLightDir.xyz);
//float SampleRange = float(height) * SampleScreenScale;
//float SampleRange = View.BufferSizeAndInvSize.y * SampleScreenScale;
// サーチ距離
float SampleRange = View.ViewSizeAndInvSize.y * SampleScreenScale;
SampleRange = SampleRange / LinearDepth * 10.f * (3.14159265f/ 2.f / View.FieldOfViewWideAngles.x);
//float2 UnscaledMin = View.UnscaledViewRect.Min.xy;
//float2 UnscaledMax = View.UnscaledViewRect.Max.xy;
//float2 UnscaledSize = UnscaledMax - UnscaledMin; // フル幅/高さ (pixels)
//float SampleRange = UnscaledSize.y * SampleScreenScale;
bool bEdge = false;
float LocalSampleScale = max(SampleScale, 1.0);
float EdgeColorScale = 1.0f;
{
float fade = 0.01f;
float2 OutArea = float2(width, height) * fade;
// エッジサーチ先の座標
//float2 checkEnd = float2(pixelCoord) + SampleRange;
float2 checkEnd = (ClipLightDir.xy * float2(SampleRange,SampleRange)) + pixelCoord;
// 左上のはみ出し
float2 out1 = abs( min(float2(0,0), checkEnd - OutArea));
// 右下のはみ出し
float2 out2 = abs(max(float2(width, height), checkEnd + OutArea));
// はみ出し 最大
float2 out3 = max(out1, out2-float2(width, height));
out3.x = saturate(max(out3.x, out3.y));
//EdgeColorScale = 1.f - out3.x;
}
// Stencilのエッジを検出
for (float i = 0; i < SampleRange; i += LocalSampleScale) {
int2 target = int2(ClipLightDir.xy * float2(i,i)) + pixelCoord;
target = clamp(target, int2(0,0), int2(width-1, height-1));
if (CustomStencilTexture[target].y == 0) {
bEdge = true;
break;
}
}
if (bEdge) {
// エッジ
float3 col = UseCustomLightColor ? LightColor : View.DirectionalLightColor.xyz;
SceneColorTexture[pixelCoord].xyz = max(SceneColorTexture[pixelCoord].xyz, col * LightScale * EdgeColorScale * NormalWeight);
}
//for (int i = 0; i < 100; ++i) {
// SceneColorTexture[pixelCoord + int2((ClipLightDir.xy * float2(i,i)))] = 10;
//}
}// 法線判定 end
}} // mask end
return;
/*
float LinearDepth = 1;
{
float2 UV = ViewSize / float2(width, height);
float Depth = SceneDepthTexture[pixelCoord]; //SceneDepthTexture.SampleLevel(DepthSampler, UV, 0);
LinearDepth = GetLinearDepth(UV, pixelCoord);
float t = saturate(LinearDepth / 5000.f);
float3 color = lerp(float3(0, 0, 1), float3(0, 1, 0), t); // 青→緑
color = lerp(color, float3(1, 0, 0), t); // 緑→赤
//SceneColorTexture[pixelCoord].xyz = color; // frac(LinearDepth / 5000.f);
//SceneColorTexture[pixelCoord] = float4(LinearDepth / 1000.0, 0.0, 0.0, 1.0);
}
// CustomStencilTexture
//SceneColorTexture[pixelCoord].xyz = color; // frac(LinearDepth / 5000.f);
if (CustomStencilTexture[pixelCoord].y & CustomStencilMask) {
if (SceneDepthTexture[pixelCoord] <= CustomDepthTexture[pixelCoord].r) {
//float2 UV = ViewSize / float2(width, height);
float2 UV = View.BufferSizeAndInvSize.zw;
float3 PackedNormal = NormalTexture[pixelCoord].xyz;
float3 WorldNormal = PackedNormal * 2.0 - 1.0; // [-1, 1]に変換
float3 LocalLightDirection = View.DirectionalLightDirection;
if (UseCustomLightPosition) {
LocalLightDirection = normalize(ReconstructWorldPosition(UV, pixelCoord) - LightPosition);
}
LocalLightDirection = normalize(LightDirection);
float t = 1.f;
if (dot(PackedNormal, PackedNormal) == 0.f) {
// for unlit (no normal)
// always 1
} else {
t = dot(WorldNormal, LocalLightDirection);
t = saturate(t);
if (UseBinaryEdge) {
// エッジを2値にする
t = (t >= RimEdgeBinaryRange) ? 1.f : 0.f;
} else {
// エッジ フェード
t = pow(t, RimEdgeFade);
}
}
if (t > 0.f) {
float4 ClipLightDir = mul(float4(-LocalLightDirection, 0.0), View.RelativeWorldToClip);
ClipLightDir.xyz = normalize(ClipLightDir.xyz);
//float SampleRange = float(height) * SampleScreenScale;
//float SampleRange = View.BufferSizeAndInvSize.y * SampleScreenScale;
float SampleRange = View.ViewSizeAndInvSize.y * SampleScreenScale;
SampleRange = SampleRange / LinearDepth * 10.f * (3.14159265f/ 2.f / View.FieldOfViewWideAngles.x);
//float2 UnscaledMin = View.UnscaledViewRect.Min.xy;
//float2 UnscaledMax = View.UnscaledViewRect.Max.xy;
//float2 UnscaledSize = UnscaledMax - UnscaledMin; // フル幅/高さ (pixels)
//float SampleRange = UnscaledSize.y * SampleScreenScale;
bool bEdge = false;
float LocalSampleScale = max(SampleScale, 1.0);
float EdgeColorScale = 1.0f;
{
float fade = 0.01f;
float2 OutArea = float2(width, height) * fade;
// エッジサーチ先の座標
//float2 checkEnd = float2(pixelCoord) + SampleRange;
float2 checkEnd = (ClipLightDir.xy * float2(SampleRange,SampleRange)) + pixelCoord;
// 左上のはみ出し
float2 out1 = abs( min(float2(0,0), checkEnd - OutArea));
// 右下のはみ出し
float2 out2 = abs(max(float2(width, height), checkEnd + OutArea));
// はみ出し 最大
float2 out3 = max(out1, out2-float2(width, height));
out3.x = saturate(max(out3.x, out3.y));
//EdgeColorScale = 1.f - out3.x;
}
// Stencilのエッジを検出
for (float i = 0; i < SampleRange; i += LocalSampleScale) {
int2 target = int2(ClipLightDir.xy * float2(i,i)) + pixelCoord;
target = clamp(target, int2(0,0), int2(width-1, height-1));
if (CustomStencilTexture[target].y == 0) {
bEdge = true;
break;
}
}
if (bEdge) {
// エッジ
float3 col = UseCustomLightColor ? LightColor : View.DirectionalLightColor.xyz;
SceneColorTexture[pixelCoord].xyz = max(SceneColorTexture[pixelCoord].xyz, col * LightScale * EdgeColorScale * t);
}
//for (int i = 0; i < 100; ++i) {
// SceneColorTexture[pixelCoord + int2((ClipLightDir.xy * float2(i,i)))] = 10;
//}
}
}
}
{
//float2 UV = ViewSize / float2(width, height);
//SceneColorTexture[pixelCoord].xyz = saturate(ReconstructWorldPosition(UV, pixelCoord));
}
*/
#endif
}
@@ -0,0 +1,4 @@
void MyShaderPS(float4 SvPosition : SV_POSITION, out float4 OutSceneColor : SV_Target0)
{
OutSceneColor = float4(SomeParameter.xxx, 0);
}