diff options
| -rw-r--r-- | .bashrc | 18 | ||||
| -rwxr-xr-x[-rw-r--r--] | .gitignore | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | .gitmodules | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | 3ner.cginc | 10 | ||||
| -rwxr-xr-x[-rw-r--r--] | 3ner.shader | 3 | ||||
| -rwxr-xr-x[-rw-r--r--] | 3ner.shader.meta | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | DepthBlit.shader | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | Images/plane_to_tube_to_plane.lorien | bin | 158876 -> 158876 bytes | |||
| -rwxr-xr-x[-rw-r--r--] | Images/plane_tube_deformation_derivation.png | bin | 607439 -> 607439 bytes | |||
| -rwxr-xr-x[-rw-r--r--] | LUTS/dfg_cloth.exr | bin | 67752 -> 67752 bytes | |||
| -rwxr-xr-x[-rw-r--r--] | LUTS/dfg_cloth.exr.meta | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | LUTS/dfg_standard.exr | bin | 132014 -> 132014 bytes | |||
| -rwxr-xr-x[-rw-r--r--] | LUTS/dfg_standard.exr.meta | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | LightVolumes.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | README.md | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | Scripts/DataDecoder.asset | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | Scripts/DataDecoder.asset.meta | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | Scripts/DataDecoder.cs | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | Scripts/DataDecoder.cs.meta | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | Scripts/Fold/Editor/FoldEditorWindow.cs | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | Scripts/Fold/Editor/FoldPipelineBuilder.cs | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | Scripts/Fold/Editor/README.md | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | Scripts/Fold/Editor/package-lock.json | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | Scripts/Impostors.cs | 1 | ||||
| -rwxr-xr-x[-rw-r--r--] | Scripts/approximate.py | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | Scripts/make_dfg_lut.py | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | UnityImageBasedLightingMinimal.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | UnityStandardCoreMinimal.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | brdf.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | cnlohr.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | etc/nginx/modules-available/rtmp.conf | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | etc/nginx/nginx.conf | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | etc/nginx/sites-available/yummers.dev | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | etc/nginx/snippets/proxy-headers.conf | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | etc/systemd/system/obsproxy.service | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | features.cginc | 8 | ||||
| -rwxr-xr-x[-rw-r--r--] | filamented.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | filtering.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | geometry.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | globals.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | impostor.cginc | 247 | ||||
| -rwxr-xr-x[-rw-r--r--] | instancing.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | interpolators.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | lighting.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | load_test.py | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | lysenko.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | math.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | opt/obsproxy/requirements.txt | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | pbr.cginc | 4 | ||||
| -rwxr-xr-x[-rw-r--r--] | pbr_utils.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | pema99.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | ray_marching.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | ray_marching_maps.slang | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | sampling.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | texture_utils.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | vertex.cginc | 0 | ||||
| -rwxr-xr-x[-rw-r--r--] | vertex_deformation.slang | 0 |
57 files changed, 146 insertions, 145 deletions
diff --git a/.bashrc b/.bashrc deleted file mode 100644 index c526160..0000000 --- a/.bashrc +++ /dev/null @@ -1,18 +0,0 @@ -function check_live { - ssh yummers.dev 'sudo journalctl -u obsproxy -n 30 -f' -} -function start_live { - ssh yummers.dev 'sudo systemctl start obsproxy' -} -function stop_live { - ssh yummers.dev 'sudo systemctl stop obsproxy' -} -function restart_live { - ssh yummers.dev 'sudo systemctl restart obsproxy' -} -function get_live { - live_url=$(ssh yummers.dev "journalctl -u obsproxy -n 10000 | grep 'HLS:' | awk '{print \$NF}'" | tail -n 1) - echo $live_url | clip.exe - echo "Copied to clipboard: $live_url" -} - diff --git a/.gitignore b/.gitignore index e26abbf..e26abbf 100644..100755 --- a/.gitignore +++ b/.gitignore diff --git a/.gitmodules b/.gitmodules index 0aff67f..0aff67f 100644..100755 --- a/.gitmodules +++ b/.gitmodules diff --git a/3ner.cginc b/3ner.cginc index 18c23ee..02081a9 100644..100755 --- a/3ner.cginc +++ b/3ner.cginc @@ -253,12 +253,12 @@ void geom(triangle v2f tri_in[3], //endex float4 frag(v2f i, uint facing : SV_IsFrontFace -#if defined(_IMPOSTORS) +#if defined(_IMPOSTORS_DEPTH) , out float depth : SV_DepthLessEqual #endif ) : SV_Target { UNITY_SETUP_INSTANCE_ID(i); -#if defined(SHADOW_CASTER_PASS) && !(_IMPOSTORS) +#if defined(SHADOW_CASTER_PASS) && !defined(_IMPOSTORS_DEPTH) return 0; #endif @@ -279,17 +279,21 @@ float4 frag(v2f i, uint facing : SV_IsFrontFace #if defined(_IMPOSTORS) i.normal = pbr.normal; +#if defined(_IMPOSTORS_DEPTH) i.objPos = pbr.objPos; propagateObjPos(i); - float4 imp_clip_pos = UnityObjectToClipPos(i.objPos); depth = imp_clip_pos.z / imp_clip_pos.w; #endif +#endif #if defined(_DEBUG_VIEW_UNLIT) return pbr.albedo; #elif defined(_DEBUG_VIEW_WORLD_SPACE_NORMALS) return float4((pbr.normal + 1.0f) * 0.5f, 1); +#elif defined(_DEBUG_VIEW_OBJECT_SPACE_NORMALS) + float3 normalOS = normalize(mul((float3x3)unity_WorldToObject, pbr.normal)); + return float4((normalOS + 1.0f) * 0.5f, 1); #elif defined(_DEBUG_VIEW_METALLIC_GLOSS) return float4(pbr.metallic, pbr.smoothness, 0, 1); #elif defined(_DEBUG_VIEW_DEPTH) diff --git a/3ner.shader b/3ner.shader index c2ece89..d7663ef 100644..100755 --- a/3ner.shader +++ b/3ner.shader @@ -391,6 +391,8 @@ Shader "yum_food/3ner" _Impostors_Cutoff("Alpha Cutoff", Range(0, 1)) = 0.5 _Impostors_Parallax("Parallax Strength", Range(0, 1)) = 1 + [ThryToggle(_IMPOSTORS_DEPTH)] _Impostors_Depth_Enabled("Enable depth", Float) = 0 + [Toggle] _Impostors_Debug_Mode("Debug Mode", Float) = 0 [Toggle] _Impostors_Debug_Depth("Debug Depth", Float) = 0 [HideInInspector] m_end_Impostors("Impostors", Float) = 0 @@ -417,6 +419,7 @@ Shader "yum_food/3ner" [HideInInspector] m_start_Debug_Views("Debug Views", Float) = 0 [ThryToggle(_DEBUG_VIEW_UNLIT)] _Debug_View_Unlit("Unlit", Float) = 0 [ThryToggle(_DEBUG_VIEW_WORLD_SPACE_NORMALS)] _Debug_View_World_Space_Normals("World space normals", Float) = 0 + [ThryToggle(_DEBUG_VIEW_OBJECT_SPACE_NORMALS)] _Debug_View_Object_Space_Normals("Object space normals", Float) = 0 [ThryToggle(_DEBUG_VIEW_METALLIC_GLOSS)] _Debug_View_Metallic_Gloss("Metallic gloss", Float) = 0 [ThryToggle(_DEBUG_VIEW_DEPTH)] _Debug_View_Depth("Depth", Float) = 0 [HideInInspector] m_end_Debug_Views("Debug Views", Float) = 0 diff --git a/3ner.shader.meta b/3ner.shader.meta index 6cfcf99..6cfcf99 100644..100755 --- a/3ner.shader.meta +++ b/3ner.shader.meta diff --git a/DepthBlit.shader b/DepthBlit.shader index b2a512f..b2a512f 100644..100755 --- a/DepthBlit.shader +++ b/DepthBlit.shader diff --git a/Images/plane_to_tube_to_plane.lorien b/Images/plane_to_tube_to_plane.lorien Binary files differindex 89affd2..89affd2 100644..100755 --- a/Images/plane_to_tube_to_plane.lorien +++ b/Images/plane_to_tube_to_plane.lorien diff --git a/Images/plane_tube_deformation_derivation.png b/Images/plane_tube_deformation_derivation.png Binary files differindex 9103ca7..9103ca7 100644..100755 --- a/Images/plane_tube_deformation_derivation.png +++ b/Images/plane_tube_deformation_derivation.png diff --git a/LUTS/dfg_cloth.exr b/LUTS/dfg_cloth.exr Binary files differindex b30a2a7..b30a2a7 100644..100755 --- a/LUTS/dfg_cloth.exr +++ b/LUTS/dfg_cloth.exr diff --git a/LUTS/dfg_cloth.exr.meta b/LUTS/dfg_cloth.exr.meta index a3630b0..a3630b0 100644..100755 --- a/LUTS/dfg_cloth.exr.meta +++ b/LUTS/dfg_cloth.exr.meta diff --git a/LUTS/dfg_standard.exr b/LUTS/dfg_standard.exr Binary files differindex 016c35d..016c35d 100644..100755 --- a/LUTS/dfg_standard.exr +++ b/LUTS/dfg_standard.exr diff --git a/LUTS/dfg_standard.exr.meta b/LUTS/dfg_standard.exr.meta index 68554f4..68554f4 100644..100755 --- a/LUTS/dfg_standard.exr.meta +++ b/LUTS/dfg_standard.exr.meta diff --git a/LightVolumes.cginc b/LightVolumes.cginc index d10a190..d10a190 100644..100755 --- a/LightVolumes.cginc +++ b/LightVolumes.cginc diff --git a/README.md b/README.md index 01f9f89..01f9f89 100644..100755 --- a/README.md +++ b/README.md diff --git a/Scripts/DataDecoder.asset b/Scripts/DataDecoder.asset index b8be961..b8be961 100644..100755 --- a/Scripts/DataDecoder.asset +++ b/Scripts/DataDecoder.asset diff --git a/Scripts/DataDecoder.asset.meta b/Scripts/DataDecoder.asset.meta index 25606cf..25606cf 100644..100755 --- a/Scripts/DataDecoder.asset.meta +++ b/Scripts/DataDecoder.asset.meta diff --git a/Scripts/DataDecoder.cs b/Scripts/DataDecoder.cs index 4773886..4773886 100644..100755 --- a/Scripts/DataDecoder.cs +++ b/Scripts/DataDecoder.cs diff --git a/Scripts/DataDecoder.cs.meta b/Scripts/DataDecoder.cs.meta index 38f5d72..38f5d72 100644..100755 --- a/Scripts/DataDecoder.cs.meta +++ b/Scripts/DataDecoder.cs.meta diff --git a/Scripts/Fold/Editor/FoldEditorWindow.cs b/Scripts/Fold/Editor/FoldEditorWindow.cs index ab02781..ab02781 100644..100755 --- a/Scripts/Fold/Editor/FoldEditorWindow.cs +++ b/Scripts/Fold/Editor/FoldEditorWindow.cs diff --git a/Scripts/Fold/Editor/FoldPipelineBuilder.cs b/Scripts/Fold/Editor/FoldPipelineBuilder.cs index 3731cf8..3731cf8 100644..100755 --- a/Scripts/Fold/Editor/FoldPipelineBuilder.cs +++ b/Scripts/Fold/Editor/FoldPipelineBuilder.cs diff --git a/Scripts/Fold/Editor/README.md b/Scripts/Fold/Editor/README.md index d2b7494..d2b7494 100644..100755 --- a/Scripts/Fold/Editor/README.md +++ b/Scripts/Fold/Editor/README.md diff --git a/Scripts/Fold/Editor/package-lock.json b/Scripts/Fold/Editor/package-lock.json index 5562b07..5562b07 100644..100755 --- a/Scripts/Fold/Editor/package-lock.json +++ b/Scripts/Fold/Editor/package-lock.json diff --git a/Scripts/Impostors.cs b/Scripts/Impostors.cs index 9769aa1..3212341 100644..100755 --- a/Scripts/Impostors.cs +++ b/Scripts/Impostors.cs @@ -492,6 +492,7 @@ public class Impostors : MonoBehaviour if (shader == null) { Debug.LogError("Shader not found"); return; } impostorMaterial = new Material(shader); + impostorMaterial.enableInstancing = true; for (int i = 0; i < textures.Length; i++) impostorMaterial.SetTexture(exportSettings[i].materialProp, textures[i]); impostorMaterial.SetInt("_Impostors_Grid_Resolution", gridResolution); diff --git a/Scripts/approximate.py b/Scripts/approximate.py index fb39283..fb39283 100644..100755 --- a/Scripts/approximate.py +++ b/Scripts/approximate.py diff --git a/Scripts/make_dfg_lut.py b/Scripts/make_dfg_lut.py index b4faf0f..b4faf0f 100644..100755 --- a/Scripts/make_dfg_lut.py +++ b/Scripts/make_dfg_lut.py diff --git a/UnityImageBasedLightingMinimal.cginc b/UnityImageBasedLightingMinimal.cginc index fb8b8f3..fb8b8f3 100644..100755 --- a/UnityImageBasedLightingMinimal.cginc +++ b/UnityImageBasedLightingMinimal.cginc diff --git a/UnityStandardCoreMinimal.cginc b/UnityStandardCoreMinimal.cginc index 8f2135d..8f2135d 100644..100755 --- a/UnityStandardCoreMinimal.cginc +++ b/UnityStandardCoreMinimal.cginc diff --git a/brdf.cginc b/brdf.cginc index 682f6a0..682f6a0 100644..100755 --- a/brdf.cginc +++ b/brdf.cginc diff --git a/cnlohr.cginc b/cnlohr.cginc index 709c7ac..709c7ac 100644..100755 --- a/cnlohr.cginc +++ b/cnlohr.cginc diff --git a/etc/nginx/modules-available/rtmp.conf b/etc/nginx/modules-available/rtmp.conf index e1fad29..e1fad29 100644..100755 --- a/etc/nginx/modules-available/rtmp.conf +++ b/etc/nginx/modules-available/rtmp.conf diff --git a/etc/nginx/nginx.conf b/etc/nginx/nginx.conf index ab7aff4..ab7aff4 100644..100755 --- a/etc/nginx/nginx.conf +++ b/etc/nginx/nginx.conf diff --git a/etc/nginx/sites-available/yummers.dev b/etc/nginx/sites-available/yummers.dev index 5eb4fef..5eb4fef 100644..100755 --- a/etc/nginx/sites-available/yummers.dev +++ b/etc/nginx/sites-available/yummers.dev diff --git a/etc/nginx/snippets/proxy-headers.conf b/etc/nginx/snippets/proxy-headers.conf index 6df4834..6df4834 100644..100755 --- a/etc/nginx/snippets/proxy-headers.conf +++ b/etc/nginx/snippets/proxy-headers.conf diff --git a/etc/systemd/system/obsproxy.service b/etc/systemd/system/obsproxy.service index b145a17..b145a17 100644..100755 --- a/etc/systemd/system/obsproxy.service +++ b/etc/systemd/system/obsproxy.service diff --git a/features.cginc b/features.cginc index 8ebd19a..ebcf8a7 100644..100755 --- a/features.cginc +++ b/features.cginc @@ -45,6 +45,10 @@ #pragma shader_feature_local _DEBUG_VIEW_WORLD_SPACE_NORMALS //endex +//ifex _Debug_View_Object_Space_Normals==0 +#pragma shader_feature_local _DEBUG_VIEW_OBJECT_SPACE_NORMALS +//endex + //ifex _Debug_View_Metallic_Gloss==0 #pragma shader_feature_local _DEBUG_VIEW_METALLIC_GLOSS //endex @@ -129,4 +133,8 @@ #pragma shader_feature_local _IMPOSTORS //endex +//ifex _Impostors_Depth_Enabled==0 +#pragma shader_feature_local _IMPOSTORS_DEPTH +//endex + #endif // __FEATURES_INC diff --git a/filamented.cginc b/filamented.cginc index 62ec4c3..62ec4c3 100644..100755 --- a/filamented.cginc +++ b/filamented.cginc diff --git a/filtering.cginc b/filtering.cginc index 18fcad3..18fcad3 100644..100755 --- a/filtering.cginc +++ b/filtering.cginc diff --git a/geometry.cginc b/geometry.cginc index 9ddb011..9ddb011 100644..100755 --- a/geometry.cginc +++ b/geometry.cginc diff --git a/globals.cginc b/globals.cginc index c50e7fc..c50e7fc 100644..100755 --- a/globals.cginc +++ b/globals.cginc diff --git a/impostor.cginc b/impostor.cginc index e84f9db..048eaf6 100644..100755 --- a/impostor.cginc +++ b/impostor.cginc @@ -30,11 +30,11 @@ void BillboardBasis(float3 fwd, out float3 right, out float3 up) { float2 GridFromDir(float3 viewDir, float gridRes) { float2 uv = HemiOctEncode(viewDir) * 0.5 + 0.5; - return clamp(uv * (gridRes - 1), 0, gridRes - 1); + return clamp(uv * (gridRes - 1.0), 0.0, gridRes - 1.0); } float3 DirFromCell(float2 cell, float gridRes) { - float2 uv = cell / max(1.0, gridRes - 1) * 2.0 - 1.0; + float2 uv = cell * rcp(max(1.0, gridRes - 1.0)) * 2.0 - 1.0; return HemiOctDecode(uv); } @@ -61,8 +61,7 @@ float2 VirtualPlaneUV(float3 frameDir, float3 pivotToCam, float3 vertexToCam) { float3 offset = vertexToCam * ratio - pivotToCam; - float2 uv = float2(dot(planeX, offset), dot(planeY, offset)); - return uv * -1.0 + 0.5; + return 0.5 - float2(dot(planeX, offset), dot(planeY, offset)); } #if defined(_IMPOSTORS) @@ -72,10 +71,8 @@ float DecodeImpostorDepth(float linearDepth) { return lerp(_Impostors_Near_Clip, _Impostors_Far_Clip, linearDepth); } -float2 ClampUvInCell(float2 uv) { - uv = saturate(uv); - float2 halfTexelInCell = 0.5 * _Impostors_Atlas_TexelSize.xy * (float)_Impostors_Grid_Resolution; - return clamp(uv, halfTexelInCell, 1.0 - halfTexelInCell); +float2 ClampUvInCell(float2 uv, float2 halfTexelInCell) { + return clamp(saturate(uv), halfTexelInCell, 1.0 - halfTexelInCell); } struct ImpostorSample { @@ -94,59 +91,51 @@ struct ImpostorResult { float debug; }; -float SampleImpostorDepthCell(float2 cell, float2 uvInCell, float gridRes) { - uvInCell = ClampUvInCell(uvInCell); - float invGridRes = rcp(gridRes); - float2 atlasUv = (cell + uvInCell) * invGridRes; - float2 gradX = ddx(uvInCell) * invGridRes; - float2 gradY = ddy(uvInCell) * invGridRes; - // 0 = near clip plane, 1 = far clip plane - return _Impostors_Depth_Atlas.SampleGrad(bilinear_clamp_s, atlasUv, gradX, gradY).r; +// Unified sampling with cached gradient calculations +struct AtlasUvGrad { + float2 atlasUv; + float2 gradX; + float2 gradY; +}; + +AtlasUvGrad PrepareAtlasUvGrad(float2 cell, float2 uvInCell, float invGridRes) { + AtlasUvGrad result; + result.atlasUv = (cell + uvInCell) * invGridRes; + result.gradX = ddx(uvInCell) * invGridRes; + result.gradY = ddy(uvInCell) * invGridRes; + return result; } -float SampleImpostorAlphaCell(float2 cell, float2 uvInCell, float gridRes) { - uvInCell = ClampUvInCell(uvInCell); - float invGridRes = rcp(gridRes); - float2 atlasUv = (cell + uvInCell) * invGridRes; - float2 gradX = ddx(uvInCell) * invGridRes; - float2 gradY = ddy(uvInCell) * invGridRes; - return _Impostors_Atlas.SampleGrad(bilinear_clamp_s, atlasUv, gradX, gradY).a; +float SampleImpostorDepthCell(float2 cell, float2 uvInCell, float invGridRes) { + AtlasUvGrad uv = PrepareAtlasUvGrad(cell, uvInCell, invGridRes); + return _Impostors_Depth_Atlas.SampleGrad(bilinear_clamp_s, uv.atlasUv, uv.gradX, uv.gradY).r; } -ImpostorSample SampleImpostorCell(float2 cell, float2 uvInCell, float gridRes) { - uvInCell = ClampUvInCell(uvInCell); - float invGridRes = rcp(gridRes); - float2 atlasUv = (cell + uvInCell) * invGridRes; - float2 gradX = ddx(uvInCell) * invGridRes; - float2 gradY = ddy(uvInCell) * invGridRes; +float SampleImpostorAlphaCell(float2 cell, float2 uvInCell, float invGridRes) { + AtlasUvGrad uv = PrepareAtlasUvGrad(cell, uvInCell, invGridRes); + return _Impostors_Atlas.SampleGrad(bilinear_clamp_s, uv.atlasUv, uv.gradX, uv.gradY).a; +} +ImpostorSample SampleImpostorCell(float2 cell, float2 uvInCell, float invGridRes) { + AtlasUvGrad uv = PrepareAtlasUvGrad(cell, uvInCell, invGridRes); ImpostorSample s; - s.albedo = _Impostors_Atlas.SampleGrad(bilinear_clamp_s, atlasUv, gradX, gradY); - s.normal = _Impostors_Normal_Atlas.SampleGrad(bilinear_clamp_s, atlasUv, gradX, gradY); - s.metallicGloss = _Impostors_Metallic_Gloss_Atlas.SampleGrad(bilinear_clamp_s, atlasUv, gradX, gradY).xzzy; + s.albedo = _Impostors_Atlas.SampleGrad(bilinear_clamp_s, uv.atlasUv, uv.gradX, uv.gradY); + s.normal = _Impostors_Normal_Atlas.SampleGrad(bilinear_clamp_s, uv.atlasUv, uv.gradX, uv.gradY); + s.metallicGloss = _Impostors_Metallic_Gloss_Atlas.SampleGrad(bilinear_clamp_s, uv.atlasUv, uv.gradX, uv.gradY); return s; } -float2 ImpostorParallaxOffsetForFrame(float3 frameDir, float3 pivotToCamOS, float2 uvBase, float encodedDepth) { - float3 planeX, planeY, planeN; - FrameBasis(frameDir, planeX, planeY, planeN); - +// Optimized version using pre-computed frame basis +float2 ImpostorParallaxOffsetForFrameFast(float3 planeX, float3 planeY, float3 planeN, float3 pivotToCamOS, float encodedDepth, float objRadiusScaled, float objNearScaled) { float2 camXY = float2(dot(pivotToCamOS, planeX), dot(pivotToCamOS, planeY)); float camZ = dot(pivotToCamOS, planeN); camZ = (abs(camZ) < 1e-4) ? (camZ < 0 ? -1e-4 : 1e-4) : camZ; - // Convert world-space depth to object space to match scaled impostor. - float objScale = max(2.0 * _Impostors_Sphere_Radius, 1e-4); - float objRadius = _Impostors_Sphere_Radius / objScale; - float objNear = _Impostors_Near_Clip / objScale; - float worldSpaceDepth = DecodeImpostorDepth(encodedDepth); - float objectSpaceDepth = worldSpaceDepth / objScale; - float depth01 = (objectSpaceDepth - objNear) / (2.0 * objRadius); - // Convert to signed "height" where nearer pixels shift more (matches typical bump-offset convention). - float zSurface = (depth01 - 0.5); - float2 planeCoord = 0.5 - uvBase; - - return (planeCoord - camXY) * (zSurface / camZ); + float worldSpaceDepth = lerp(_Impostors_Near_Clip, _Impostors_Far_Clip, encodedDepth); + float depth01 = (worldSpaceDepth - objNearScaled) * objRadiusScaled; // Pre-divided rcp(2*objRadius) + float height = 0.5 - depth01; + + return (camXY / camZ) * height; } // Reconstruct object-space offset from impostor center. @@ -156,12 +145,13 @@ float3 ReconstructObjectOffsetFromFrame(float3 frameDir, float2 uv, float encode float3 planeX, planeY, planeN; FrameBasis(frameDir, planeX, planeY, planeN); - float objScale = max(2.0f * _Impostors_Sphere_Radius, 1e-4); - float objRadius = _Impostors_Sphere_Radius / objScale; - float objNear = _Impostors_Near_Clip / objScale; - float objFar = _Impostors_Far_Clip / objScale; + float objScale = max(2.0 * _Impostors_Sphere_Radius, 1e-4); + float rcpObjScale = rcp(objScale); + float objRadius = _Impostors_Sphere_Radius * rcpObjScale; + float objNear = _Impostors_Near_Clip * rcpObjScale; + float objFar = _Impostors_Far_Clip * rcpObjScale; - float2 offsetXY = (0.5f - uv) * 2.0f * objRadius; + float2 offsetXY = (0.5 - uv) * (2.0 * objRadius); float objectSpaceDepth = lerp(objNear, objFar, encodedDepth); float offsetZ = (objRadius + objNear) - objectSpaceDepth; @@ -172,16 +162,16 @@ ImpostorSample BlendImpostorSamples(ImpostorSample s0, ImpostorSample s1, Impost ImpostorSample result; float3 alpha = float3(s0.albedo.a, s1.albedo.a, s2.albedo.a); float alphaOut = dot(alpha, bw); - float3 premul = - s0.albedo.rgb * (alpha.x * bw.x) + - s1.albedo.rgb * (alpha.y * bw.y) + - s2.albedo.rgb * (alpha.z * bw.z); - float3 rgbOut = premul / max(alphaOut, 1e-4); - result.albedo = float4(rgbOut, alphaOut); - - // Weight normal/metallicGloss by alpha to avoid blending with transparent (zero) pixels + + // Premultiplied alpha blending float3 alphaBw = alpha * bw; - alphaBw /= max(alphaBw.x + alphaBw.y + alphaBw.z, 0.001); + float3 premul = s0.albedo.rgb * alphaBw.x + s1.albedo.rgb * alphaBw.y + s2.albedo.rgb * alphaBw.z; + result.albedo = float4(premul * rcp(max(alphaOut, 1e-4)), alphaOut); + + // Weight normal/metallicGloss by alpha to avoid blending with transparent pixels + float alphaBwSum = dot(alphaBw, 1.0); + float rcpAlphaBwSum = rcp(max(alphaBwSum, 1e-3)); + alphaBw *= rcpAlphaBwSum; result.normal = s0.normal * alphaBw.x + s1.normal * alphaBw.y + s2.normal * alphaBw.z; result.metallicGloss = s0.metallicGloss * alphaBw.x + s1.metallicGloss * alphaBw.y + s2.metallicGloss * alphaBw.z; @@ -198,13 +188,13 @@ void impostor_vert(inout float3 vertexOS) { float3 camPos = _WorldSpaceCameraPos; #endif - // Billboard facing the camera direction (world space, then convert back to object space). + // Billboard facing the camera direction float3 viewWS = normalize(camPos - center); float3 right, up; BillboardBasis(viewWS, right, up); float radiusScale = _Impostors_Sphere_Radius * 2.0; - float3 worldPos = center + vertexOS.x * right * radiusScale + vertexOS.y * up * radiusScale; - vertexOS = mul(unity_WorldToObject, float4(worldPos, 1)).xyz; + float3 worldPos = center + (vertexOS.x * right + vertexOS.y * up) * radiusScale; + vertexOS = mul(unity_WorldToObject, float4(worldPos, 1.0)).xyz; } // Sample impostor atlas with view-dependent blending @@ -220,25 +210,27 @@ ImpostorResult impostor_frag(float3 worldPos) { #else float3 camPos = _WorldSpaceCameraPos; #endif + float3 camToCenter = camPos - center; float3 viewDir = normalize(worldPos - camPos); - float radiusWS = _Impostors_Sphere_Radius; - - float3 originToRo = camPos - center; - float b = dot(originToRo, viewDir); - float c = dot(originToRo, originToRo) - radiusWS * radiusWS; + float b = dot(camToCenter, viewDir); + float c = dot(camToCenter, camToCenter) - _Impostors_Sphere_Radius * _Impostors_Sphere_Radius; clip(b * b - c); - // For lattice lookup, use the camera-to-impostor-center direction (matches billboard orientation). + // For lattice lookup, use the camera-to-impostor-center direction float3x3 worldToObject = (float3x3)unity_WorldToObject; - float3 viewOS = normalize(mul(worldToObject, normalize(camPos - center))); + float3 viewOS = normalize(mul(worldToObject, normalize(camToCenter))); - // Get continuous grid position and find the 3 nearest frames + // Cache frequently used values float gridRes = (float)_Impostors_Grid_Resolution; + float invGridRes = rcp(gridRes); + float2 halfTexelInCell = 0.5 * _Impostors_Atlas_TexelSize.xy * gridRes; + + // Get continuous grid position and find the 3 nearest frames float2 grid = GridFromDir(viewOS, gridRes); float2 gridFloor = floor(grid); float2 gridFrac = frac(grid); - + // Determine triangle and weights bool isBottomRight = gridFrac.x > gridFrac.y; float3 bw = BarycentricWeights3(gridFrac, isBottomRight); @@ -249,7 +241,7 @@ ImpostorResult impostor_frag(float3 worldPos) { float2 cell2 = clamp(gridFloor + float2(1,1), 0, gridRes - 1); // Compute shared vectors for virtual plane UV calculation - float3 pivotToCamOS = mul(worldToObject, camPos - center); + float3 pivotToCamOS = mul(worldToObject, camToCenter); float3 vertexPosOS = mul(worldToObject, worldPos - center); float3 vertexToCamOS = pivotToCamOS - vertexPosOS; @@ -257,21 +249,22 @@ ImpostorResult impostor_frag(float3 worldPos) { float3 frameDir1 = DirFromCell(cell1, gridRes); float3 frameDir2 = DirFromCell(cell2, gridRes); - float2 uvBase0 = ClampUvInCell(VirtualPlaneUV(frameDir0, pivotToCamOS, vertexToCamOS)); - float2 uvBase1 = ClampUvInCell(VirtualPlaneUV(frameDir1, pivotToCamOS, vertexToCamOS)); - float2 uvBase2 = ClampUvInCell(VirtualPlaneUV(frameDir2, pivotToCamOS, vertexToCamOS)); + float2 uvBase0 = ClampUvInCell(VirtualPlaneUV(frameDir0, pivotToCamOS, vertexToCamOS), halfTexelInCell); + float2 uvBase1 = ClampUvInCell(VirtualPlaneUV(frameDir1, pivotToCamOS, vertexToCamOS), halfTexelInCell); + float2 uvBase2 = ClampUvInCell(VirtualPlaneUV(frameDir2, pivotToCamOS, vertexToCamOS), halfTexelInCell); - float baseAlpha0 = SampleImpostorAlphaCell(cell0, uvBase0, gridRes); - float baseAlpha1 = SampleImpostorAlphaCell(cell1, uvBase1, gridRes); - float baseAlpha2 = SampleImpostorAlphaCell(cell2, uvBase2, gridRes); - float baseAlphaBlended = baseAlpha0 * bw.x + baseAlpha1 * bw.y + baseAlpha2 * bw.z; + float baseAlpha0 = SampleImpostorAlphaCell(cell0, uvBase0, invGridRes); + float baseAlpha1 = SampleImpostorAlphaCell(cell1, uvBase1, invGridRes); + float baseAlpha2 = SampleImpostorAlphaCell(cell2, uvBase2, invGridRes); + float baseAlphaBlended = dot(float3(baseAlpha0, baseAlpha1, baseAlpha2), bw); float parallaxStrength = _Impostors_Parallax * smoothstep(_Impostors_Cutoff, 1.0, baseAlphaBlended); - float depth0 = SampleImpostorDepthCell(cell0, uvBase0, gridRes); - float depth1 = SampleImpostorDepthCell(cell1, uvBase1, gridRes); - float depth2 = SampleImpostorDepthCell(cell2, uvBase2, gridRes); - float depthBlended = depth0 * bw.x + depth1 * bw.y + depth2 * bw.z; + float depth0 = SampleImpostorDepthCell(cell0, uvBase0, invGridRes); + float depth1 = SampleImpostorDepthCell(cell1, uvBase1, invGridRes); + float depth2 = SampleImpostorDepthCell(cell2, uvBase2, invGridRes); + float depthBlended = dot(float3(depth0, depth1, depth2), bw); + [branch] if (_Impostors_Debug_Depth > 0.5) { result.albedo = float4(depthBlended.xxx, 1); return result; @@ -280,41 +273,53 @@ ImpostorResult impostor_frag(float3 worldPos) { float2 uv0 = uvBase0; float2 uv1 = uvBase1; float2 uv2 = uvBase2; + + // Pre-compute frame bases and scale factors for parallax + [branch] if (parallaxStrength > 0.001) { - uv0 = uvBase0 + ImpostorParallaxOffsetForFrame(frameDir0, pivotToCamOS, uvBase0, depthBlended) * parallaxStrength; - uv1 = uvBase1 + ImpostorParallaxOffsetForFrame(frameDir1, pivotToCamOS, uvBase1, depthBlended) * parallaxStrength; - uv2 = uvBase2 + ImpostorParallaxOffsetForFrame(frameDir2, pivotToCamOS, uvBase2, depthBlended) * parallaxStrength; + float objScale = max(2.0 * _Impostors_Sphere_Radius, 1e-4); + float objRadiusScaled = rcp(2.0 * (_Impostors_Sphere_Radius / objScale)); + float objNearScaled = _Impostors_Near_Clip / objScale; + + float3 planeX0, planeY0, planeN0; + float3 planeX1, planeY1, planeN1; + float3 planeX2, planeY2, planeN2; + FrameBasis(frameDir0, planeX0, planeY0, planeN0); + FrameBasis(frameDir1, planeX1, planeY1, planeN1); + FrameBasis(frameDir2, planeX2, planeY2, planeN2); + + uv0 = uvBase0 + ImpostorParallaxOffsetForFrameFast(planeX0, planeY0, planeN0, pivotToCamOS, depthBlended, objRadiusScaled, objNearScaled) * parallaxStrength; + uv1 = uvBase1 + ImpostorParallaxOffsetForFrameFast(planeX1, planeY1, planeN1, pivotToCamOS, depthBlended, objRadiusScaled, objNearScaled) * parallaxStrength; + uv2 = uvBase2 + ImpostorParallaxOffsetForFrameFast(planeX2, planeY2, planeN2, pivotToCamOS, depthBlended, objRadiusScaled, objNearScaled) * parallaxStrength; } - float2 uv0Final = uv0; - float2 uv1Final = uv1; - float2 uv2Final = uv2; + uv0 = ClampUvInCell(uv0, halfTexelInCell); + uv1 = ClampUvInCell(uv1, halfTexelInCell); + uv2 = ClampUvInCell(uv2, halfTexelInCell); - ImpostorSample s0 = SampleImpostorCell(cell0, uv0Final, gridRes); - ImpostorSample s1 = SampleImpostorCell(cell1, uv1Final, gridRes); - ImpostorSample s2 = SampleImpostorCell(cell2, uv2Final, gridRes); + ImpostorSample s0 = SampleImpostorCell(cell0, uv0, invGridRes); + ImpostorSample s1 = SampleImpostorCell(cell1, uv1, invGridRes); + ImpostorSample s2 = SampleImpostorCell(cell2, uv2, invGridRes); - // Parallax can push UVs into transparent pixels at silhouettes; fall back to unshifted UVs when that happens. + // Parallax fallback: use base UVs if parallax pushed into transparent region + [branch] if (parallaxStrength > 0.001) { - if (s0.albedo.a < _Impostors_Cutoff && baseAlpha0 > _Impostors_Cutoff) { - uv0Final = uvBase0; - s0 = SampleImpostorCell(cell0, uv0Final, gridRes); - } - if (s1.albedo.a < _Impostors_Cutoff && baseAlpha1 > _Impostors_Cutoff) { - uv1Final = uvBase1; - s1 = SampleImpostorCell(cell1, uv1Final, gridRes); - } - if (s2.albedo.a < _Impostors_Cutoff && baseAlpha2 > _Impostors_Cutoff) { - uv2Final = uvBase2; - s2 = SampleImpostorCell(cell2, uv2Final, gridRes); - } + float3 needFallback = float3( + (s0.albedo.a < _Impostors_Cutoff && baseAlpha0 > _Impostors_Cutoff) ? 1.0 : 0.0, + (s1.albedo.a < _Impostors_Cutoff && baseAlpha1 > _Impostors_Cutoff) ? 1.0 : 0.0, + (s2.albedo.a < _Impostors_Cutoff && baseAlpha2 > _Impostors_Cutoff) ? 1.0 : 0.0 + ); + + if (needFallback.x > 0.5) s0 = SampleImpostorCell(cell0, uvBase0, invGridRes); + if (needFallback.y > 0.5) s1 = SampleImpostorCell(cell1, uvBase1, invGridRes); + if (needFallback.z > 0.5) s2 = SampleImpostorCell(cell2, uvBase2, invGridRes); } // Blend 3 samples ImpostorSample blended = BlendImpostorSamples(s0, s1, s2, bw); + [branch] if (_Impostors_Debug_Mode > 0.5) { - // Debug view of weights result.albedo = float4(bw, 1); return result; } @@ -322,23 +327,19 @@ ImpostorResult impostor_frag(float3 worldPos) { clip(blended.albedo.a - _Impostors_Cutoff); result.albedo = blended.albedo; - result.normal = normalize(blended.normal.xyz * 2.0 - 1.0); + // Decode and transform normal + float3 normalOS = blended.normal.xyz * 2.0 - 1.0; + result.normal = normalize(mul((float3x3)unity_ObjectToWorld, normalOS)); result.metallic = blended.metallicGloss.r; result.smoothness = blended.metallicGloss.a; - // Reconstruct object-space position from each frame's UV and depth, then blend. - float depth0Pos = SampleImpostorDepthCell(cell0, uv0Final, gridRes); - float depth1Pos = SampleImpostorDepthCell(cell1, uv1Final, gridRes); - float depth2Pos = SampleImpostorDepthCell(cell2, uv2Final, gridRes); - - // Use object-space frame directions (same space as UV computation) - float3 offset0 = ReconstructObjectOffsetFromFrame(frameDir0, uv0Final, depth0Pos); - float3 offset1 = ReconstructObjectOffsetFromFrame(frameDir1, uv1Final, depth1Pos); - float3 offset2 = ReconstructObjectOffsetFromFrame(frameDir2, uv2Final, depth2Pos); - float3 objOffset = offset0 * bw.x + offset1 * bw.y + offset2 * bw.z; - - // Return object-space position (offset from origin) - result.objPos = objOffset; +#if defined(_IMPOSTORS_DEPTH) + // Reuse depth samples for position reconstruction + float3 offset0 = ReconstructObjectOffsetFromFrame(frameDir0, uv0, depth0); + float3 offset1 = ReconstructObjectOffsetFromFrame(frameDir1, uv1, depth1); + float3 offset2 = ReconstructObjectOffsetFromFrame(frameDir2, uv2, depth2); + result.objPos = offset0 * bw.x + offset1 * bw.y + offset2 * bw.z; +#endif return result; } diff --git a/instancing.cginc b/instancing.cginc index eb8e25b..eb8e25b 100644..100755 --- a/instancing.cginc +++ b/instancing.cginc diff --git a/interpolators.cginc b/interpolators.cginc index 6611039..6611039 100644..100755 --- a/interpolators.cginc +++ b/interpolators.cginc diff --git a/lighting.cginc b/lighting.cginc index 87a3dfc..87a3dfc 100644..100755 --- a/lighting.cginc +++ b/lighting.cginc diff --git a/load_test.py b/load_test.py index 0abc3c3..0abc3c3 100644..100755 --- a/load_test.py +++ b/load_test.py diff --git a/lysenko.cginc b/lysenko.cginc index d3c51f0..d3c51f0 100644..100755 --- a/lysenko.cginc +++ b/lysenko.cginc diff --git a/math.cginc b/math.cginc index 02d0fe0..02d0fe0 100644..100755 --- a/math.cginc +++ b/math.cginc diff --git a/opt/obsproxy/requirements.txt b/opt/obsproxy/requirements.txt index c1a9042..c1a9042 100644..100755 --- a/opt/obsproxy/requirements.txt +++ b/opt/obsproxy/requirements.txt diff --git a/pbr.cginc b/pbr.cginc index 076cf65..b7392f7 100644..100755 --- a/pbr.cginc +++ b/pbr.cginc @@ -24,7 +24,7 @@ struct Pbr { float cl_strength; float3 cl_color; #endif -#if defined(_IMPOSTORS) +#if defined(_IMPOSTORS_DEPTH) float3 objPos; float debug; // TODO rm #endif @@ -170,8 +170,10 @@ Pbr getPbr(v2f i) { pbr.normal = imp.normal; pbr.smoothness = imp.smoothness; pbr.metallic = imp.metallic; +#if defined(_IMPOSTORS_DEPTH) pbr.objPos = imp.objPos; pbr.debug = imp.debug; +#endif #else pbr.albedo = _MainTex.Sample(aniso16_trilinear_repeat_s, uv_parallax * _MainTex_ST.xy + _MainTex_ST.zw); pbr.albedo *= _Color; diff --git a/pbr_utils.cginc b/pbr_utils.cginc index c8c10cc..c8c10cc 100644..100755 --- a/pbr_utils.cginc +++ b/pbr_utils.cginc diff --git a/pema99.cginc b/pema99.cginc index 96fba0d..96fba0d 100644..100755 --- a/pema99.cginc +++ b/pema99.cginc diff --git a/ray_marching.cginc b/ray_marching.cginc index aeb35a1..aeb35a1 100644..100755 --- a/ray_marching.cginc +++ b/ray_marching.cginc diff --git a/ray_marching_maps.slang b/ray_marching_maps.slang index 1b8fe84..1b8fe84 100644..100755 --- a/ray_marching_maps.slang +++ b/ray_marching_maps.slang diff --git a/sampling.cginc b/sampling.cginc index 01d385f..01d385f 100644..100755 --- a/sampling.cginc +++ b/sampling.cginc diff --git a/texture_utils.cginc b/texture_utils.cginc index 9d7bf2f..9d7bf2f 100644..100755 --- a/texture_utils.cginc +++ b/texture_utils.cginc diff --git a/vertex.cginc b/vertex.cginc index 77412a9..77412a9 100644..100755 --- a/vertex.cginc +++ b/vertex.cginc diff --git a/vertex_deformation.slang b/vertex_deformation.slang index 1cb002f..1cb002f 100644..100755 --- a/vertex_deformation.slang +++ b/vertex_deformation.slang |
