-
Notifications
You must be signed in to change notification settings - Fork 32
Feature/urp blur #135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Feature/urp blur #135
Changes from all commits
88285ef
6aacca8
aea4016
3ba4d4c
9c914d8
d93c1db
59ec072
27a4c50
fe3f58b
2f674e0
7964dd4
586742c
316035e
a5d8d55
5752361
268bb6e
3a18347
13f3691
0e1ba27
28b6a8b
178b444
db9476f
c43c0c7
3061335
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
name: .NET Tests (Safe Caching + Reporting + Exclude IntegrationTests) | ||
|
||
on: | ||
push: | ||
pull_request: | ||
|
||
permissions: | ||
contents: read # always minimal | ||
checks: write # needed to post check run | ||
pull-requests: none | ||
|
||
jobs: | ||
build-test: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: read | ||
checks: write | ||
pull-requests: none | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
|
||
- name: Setup .NET | ||
uses: actions/setup-dotnet@v3 | ||
with: | ||
dotnet-version: '8.0.x' | ||
cache: true | ||
cache-dependency-path: | | ||
**/*.csproj | ||
Directory.Packages.props | ||
|
||
- name: Restore dependencies | ||
run: dotnet restore CsCore/CsCore.sln | ||
|
||
- name: Build solution | ||
run: dotnet build CsCore/CsCore.sln --no-restore | ||
|
||
- name: Run xUnit tests (exclude integrationTests) | ||
run: > | ||
dotnet test CsCore/xUnitTests/xUnitTests.csproj | ||
--no-build | ||
--verbosity normal | ||
--logger "trx;LogFileName=test-results.trx" | ||
--filter "FullyQualifiedName\!~integrationTests" | ||
|
||
report: | ||
needs: build-test | ||
if: github.event_name != 'pull_request' | ||
|| github.event.pull_request.head.repo.full_name == github.repository | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: read | ||
checks: write | ||
pull-requests: write | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
|
||
- name: Upload and annotate test results | ||
uses: dorny/test-reporter@v1 | ||
with: | ||
name: Test Results | ||
path: '**/*.trx' | ||
reporter: dotnet-trx | ||
fail-on-error: 'true' | ||
Comment on lines
+55
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The To fix this, you need to upload the test results as an artifact in the First, add this step to the end of your - name: Upload test results
uses: actions/upload-artifact@v4
with:
name: test-results
path: '**/*.trx'
retention-days: 1 Then, you can replace the steps in this
|
||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
%YAML 1.1 | ||
%TAG !u! tag:unity3d.com,2011: | ||
--- !u!114 &-253989385686868923 | ||
MonoBehaviour: | ||
m_ObjectHideFlags: 11 | ||
m_CorrespondingSourceObject: {fileID: 0} | ||
m_PrefabInstance: {fileID: 0} | ||
m_PrefabAsset: {fileID: 0} | ||
m_GameObject: {fileID: 0} | ||
m_Enabled: 1 | ||
m_EditorHideFlags: 0 | ||
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} | ||
m_Name: | ||
m_EditorClassIdentifier: | ||
version: 9 | ||
--- !u!21 &2100000 | ||
Material: | ||
serializedVersion: 8 | ||
m_ObjectHideFlags: 0 | ||
m_CorrespondingSourceObject: {fileID: 0} | ||
m_PrefabInstance: {fileID: 0} | ||
m_PrefabAsset: {fileID: 0} | ||
m_Name: BlurUrp | ||
m_Shader: {fileID: 4800000, guid: a4714f3096a129d44a751f81e3c94ff2, type: 3} | ||
m_Parent: {fileID: 0} | ||
m_ModifiedSerializedProperties: 0 | ||
m_ValidKeywords: [] | ||
m_InvalidKeywords: [] | ||
m_LightmapFlags: 4 | ||
m_EnableInstancingVariants: 0 | ||
m_DoubleSidedGI: 0 | ||
m_CustomRenderQueue: 3000 | ||
stringTagMap: {} | ||
disabledShaderPasses: | ||
- MOTIONVECTORS | ||
m_LockedProperties: | ||
m_SavedProperties: | ||
serializedVersion: 3 | ||
m_TexEnvs: | ||
- _BaseMap: | ||
m_Texture: {fileID: 0} | ||
m_Scale: {x: 1, y: 1} | ||
m_Offset: {x: 0, y: 0} | ||
- _BumpMap: | ||
m_Texture: {fileID: 0} | ||
m_Scale: {x: 1, y: 1} | ||
m_Offset: {x: 0, y: 0} | ||
- _DetailAlbedoMap: | ||
m_Texture: {fileID: 0} | ||
m_Scale: {x: 1, y: 1} | ||
m_Offset: {x: 0, y: 0} | ||
- _DetailMask: | ||
m_Texture: {fileID: 0} | ||
m_Scale: {x: 1, y: 1} | ||
m_Offset: {x: 0, y: 0} | ||
- _DetailNormalMap: | ||
m_Texture: {fileID: 0} | ||
m_Scale: {x: 1, y: 1} | ||
m_Offset: {x: 0, y: 0} | ||
- _EmissionMap: | ||
m_Texture: {fileID: 0} | ||
m_Scale: {x: 1, y: 1} | ||
m_Offset: {x: 0, y: 0} | ||
- _MainTex: | ||
m_Texture: {fileID: 0} | ||
m_Scale: {x: 1, y: 1} | ||
m_Offset: {x: 0, y: 0} | ||
- _MetallicGlossMap: | ||
m_Texture: {fileID: 0} | ||
m_Scale: {x: 1, y: 1} | ||
m_Offset: {x: 0, y: 0} | ||
- _OcclusionMap: | ||
m_Texture: {fileID: 0} | ||
m_Scale: {x: 1, y: 1} | ||
m_Offset: {x: 0, y: 0} | ||
- _ParallaxMap: | ||
m_Texture: {fileID: 0} | ||
m_Scale: {x: 1, y: 1} | ||
m_Offset: {x: 0, y: 0} | ||
- _SpecGlossMap: | ||
m_Texture: {fileID: 0} | ||
m_Scale: {x: 1, y: 1} | ||
m_Offset: {x: 0, y: 0} | ||
- unity_Lightmaps: | ||
m_Texture: {fileID: 0} | ||
m_Scale: {x: 1, y: 1} | ||
m_Offset: {x: 0, y: 0} | ||
- unity_LightmapsInd: | ||
m_Texture: {fileID: 0} | ||
m_Scale: {x: 1, y: 1} | ||
m_Offset: {x: 0, y: 0} | ||
- unity_ShadowMasks: | ||
m_Texture: {fileID: 0} | ||
m_Scale: {x: 1, y: 1} | ||
m_Offset: {x: 0, y: 0} | ||
m_Ints: [] | ||
m_Floats: | ||
- _AddPrecomputedVelocity: 0 | ||
- _AlphaClip: 0 | ||
- _AlphaToMask: 0 | ||
- _Blend: 0 | ||
- _BlendModePreserveSpecular: 1 | ||
- _BumpScale: 1 | ||
- _ClearCoatMask: 0 | ||
- _ClearCoatSmoothness: 0 | ||
- _ColorMask: 10.21 | ||
- _Cull: 2 | ||
- _Cutoff: 0.5 | ||
- _DetailAlbedoMapScale: 1 | ||
- _DetailNormalMapScale: 1 | ||
- _DstBlend: 0 | ||
- _DstBlendAlpha: 0 | ||
- _EnvironmentReflections: 1 | ||
- _GlossMapScale: 0 | ||
- _Glossiness: 0 | ||
- _GlossyReflections: 0 | ||
- _Iterations: 1.173 | ||
- _Metallic: 0 | ||
- _OcclusionStrength: 1 | ||
- _Parallax: 0.005 | ||
- _QueueOffset: 0 | ||
- _ReceiveShadows: 1 | ||
- _Samples: 7.17 | ||
- _Size: 0.8 | ||
- _Smoothness: 0.5 | ||
- _SmoothnessTextureChannel: 0 | ||
- _SpecularHighlights: 1 | ||
- _SrcBlend: 1 | ||
- _SrcBlendAlpha: 1 | ||
- _Stencil: 0.43 | ||
- _StencilComp: 7.17 | ||
- _StencilOp: 1.4 | ||
- _StencilReadMask: 226.7 | ||
- _StencilWriteMask: 256.18 | ||
- _Surface: 0 | ||
- _UseUIAlphaClip: 0 | ||
- _WorkflowMode: 1 | ||
- _XRMotionVectorsPass: 1 | ||
- _ZWrite: 1 | ||
m_Colors: | ||
- _AdditiveColor: {r: 0.426, g: 0.284142, b: 0.284142, a: 0.4509804} | ||
- _BaseColor: {r: 1, g: 1, b: 1, a: 1} | ||
- _Color: {r: 1, g: 1, b: 1, a: 1} | ||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} | ||
- _MultiplyColor: {r: 0.78699994, g: 0.7409521, b: 0.7409521, a: 1} | ||
- _SpecColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} | ||
- _TextureSampleAdd: {r: 0, g: 0, b: 0, a: 0} | ||
m_BuildTextureStacks: [] | ||
m_AllowLocking: 1 |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
Shader "Custom/BlurURP" | ||
{ | ||
Properties | ||
{ | ||
_Size ("Blur Radius" , Range(0,50)) = 5.0 | ||
_Samples ("Sample Count" , Range(4,32)) = 16 | ||
_MainTex ("Mask Texture (Alpha)" , 2D) = "white" {} | ||
_MultiplyColor ("Multiply Tint Color" , Color) = (1,1,1,1) | ||
_AdditiveColor ("Additive Tint Color" , Color) = (0,0,0,0) | ||
} | ||
|
||
SubShader | ||
{ | ||
Tags | ||
{ | ||
"Queue"="Transparent" "RenderType"="Transparent" | ||
"RenderPipeline"="UniversalPipeline" | ||
} | ||
|
||
Blend SrcAlpha OneMinusSrcAlpha | ||
ZWrite Off | ||
Cull Off | ||
|
||
Pass | ||
{ | ||
Name "ForwardBlur" | ||
Tags | ||
{ | ||
"LightMode" = "SRPDefaultUnlit" | ||
} | ||
|
||
HLSLPROGRAM | ||
#pragma vertex vert | ||
#pragma fragment frag | ||
#pragma target 3.0 | ||
|
||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" | ||
|
||
// -------- uniforms | ||
sampler2D _MainTex; | ||
float4 _MainTex_ST; | ||
sampler2D _CameraOpaqueTexture; | ||
float4 _CameraOpaqueTexture_TexelSize; | ||
sampler2D _CameraColorTexture; | ||
float4 _CameraColorTexture_TexelSize; | ||
Comment on lines
+44
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
float _Size; | ||
int _Samples; | ||
float4 _MultiplyColor, _AdditiveColor; | ||
|
||
// -------- vertex | ||
struct appdata | ||
{ | ||
float4 pos:POSITION; | ||
float2 uv:TEXCOORD0; | ||
}; | ||
|
||
struct v2f | ||
{ | ||
float4 pos:SV_POSITION; | ||
float2 uvMask:TEXCOORD0; | ||
float4 screenPos:TEXCOORD1; | ||
}; | ||
|
||
v2f vert(appdata v) | ||
{ | ||
v2f o; | ||
o.pos = TransformObjectToHClip(v.pos.xyz); | ||
o.uvMask = TRANSFORM_TEX(v.uv, _MainTex); | ||
|
||
// Use ComputeScreenPos for proper screen space coordinates | ||
// This handles world space UI canvases correctly | ||
o.screenPos = ComputeScreenPos(o.pos); | ||
|
||
return o; | ||
} | ||
|
||
// -------- fragment | ||
half4 frag(v2f i) : SV_Target | ||
{ | ||
// Convert screen position to UV coordinates | ||
float2 uvScreen = i.screenPos.xy / i.screenPos.w; | ||
|
||
half3 result = 0; | ||
float totalWeight = 0; | ||
|
||
// Blur sampling with simpler approach | ||
for (int x = -_Samples / 2; x <= _Samples / 2; x++) | ||
{ | ||
for (int y = -_Samples / 2; y <= _Samples / 2; y++) | ||
{ | ||
float2 offset = float2(x, y) * _Size * _CameraOpaqueTexture_TexelSize.xy; | ||
float distance = length(offset); | ||
|
||
// Gaussian weight based on distance | ||
float weight = exp(-distance * distance * 0.5); | ||
|
||
float2 sampleUV = uvScreen + offset; | ||
|
||
// Sample the opaque texture (which should contain all rendered content including world space UI) | ||
half3 sample = tex2D(_CameraOpaqueTexture, sampleUV).rgb; | ||
|
||
result += sample * weight; | ||
totalWeight += weight; | ||
} | ||
} | ||
Comment on lines
+87
to
+105
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current blur implementation uses a nested loop, which results in For a much more performant Gaussian blur, consider implementing a two-pass approach. This involves:
This reduces the number of texture samples from O(N²) to O(2N), providing a huge performance boost for a visually similar result. This would require changes to how the shader is used (e.g., using a
Comment on lines
+87
to
+105
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current blur implementation uses a single pass with a nested loop, which has a computational complexity of O(N²), where N is proportional to the A much more performant approach is to use a two-pass blur. This involves:
This reduces the complexity to O(2N), providing a significant performance boost for a visually similar result. Consider refactoring this to a two-pass shader for better performance. |
||
|
||
// Normalize by total weight | ||
half3 blur = result / totalWeight; | ||
half3 tinted = blur * _MultiplyColor.rgb + _AdditiveColor.rgb; | ||
half alpha = tex2D(_MainTex, i.uvMask).a * _MultiplyColor.a; | ||
return half4(tinted, alpha); | ||
} | ||
ENDHLSL | ||
} | ||
} | ||
FallBack Off | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
report
job runs on a separate runner frombuild-test
and won't have access to the test results file. Thebuild-test
job needs to upload the.trx
file as an artifact, and thisreport
job needs to download it before trying to use it. Without this, thedorny/test-reporter
action will fail as it won't find the test results.Here's how you can fix it:
In the
build-test
job, after running tests, upload the results:In this
report
job, before uploading results, download them: