summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.bashrc18
-rwxr-xr-x[-rw-r--r--].gitignore0
-rwxr-xr-x[-rw-r--r--].gitmodules0
-rwxr-xr-x[-rw-r--r--]3ner.cginc10
-rwxr-xr-x[-rw-r--r--]3ner.shader3
-rwxr-xr-x[-rw-r--r--]3ner.shader.meta0
-rwxr-xr-x[-rw-r--r--]DepthBlit.shader0
-rwxr-xr-x[-rw-r--r--]Images/plane_to_tube_to_plane.lorienbin158876 -> 158876 bytes
-rwxr-xr-x[-rw-r--r--]Images/plane_tube_deformation_derivation.pngbin607439 -> 607439 bytes
-rwxr-xr-x[-rw-r--r--]LUTS/dfg_cloth.exrbin67752 -> 67752 bytes
-rwxr-xr-x[-rw-r--r--]LUTS/dfg_cloth.exr.meta0
-rwxr-xr-x[-rw-r--r--]LUTS/dfg_standard.exrbin132014 -> 132014 bytes
-rwxr-xr-x[-rw-r--r--]LUTS/dfg_standard.exr.meta0
-rwxr-xr-x[-rw-r--r--]LightVolumes.cginc0
-rwxr-xr-x[-rw-r--r--]README.md0
-rwxr-xr-x[-rw-r--r--]Scripts/DataDecoder.asset0
-rwxr-xr-x[-rw-r--r--]Scripts/DataDecoder.asset.meta0
-rwxr-xr-x[-rw-r--r--]Scripts/DataDecoder.cs0
-rwxr-xr-x[-rw-r--r--]Scripts/DataDecoder.cs.meta0
-rwxr-xr-x[-rw-r--r--]Scripts/Fold/Editor/FoldEditorWindow.cs0
-rwxr-xr-x[-rw-r--r--]Scripts/Fold/Editor/FoldPipelineBuilder.cs0
-rwxr-xr-x[-rw-r--r--]Scripts/Fold/Editor/README.md0
-rwxr-xr-x[-rw-r--r--]Scripts/Fold/Editor/package-lock.json0
-rwxr-xr-x[-rw-r--r--]Scripts/Impostors.cs1
-rwxr-xr-x[-rw-r--r--]Scripts/approximate.py0
-rwxr-xr-x[-rw-r--r--]Scripts/make_dfg_lut.py0
-rwxr-xr-x[-rw-r--r--]UnityImageBasedLightingMinimal.cginc0
-rwxr-xr-x[-rw-r--r--]UnityStandardCoreMinimal.cginc0
-rwxr-xr-x[-rw-r--r--]brdf.cginc0
-rwxr-xr-x[-rw-r--r--]cnlohr.cginc0
-rwxr-xr-x[-rw-r--r--]etc/nginx/modules-available/rtmp.conf0
-rwxr-xr-x[-rw-r--r--]etc/nginx/nginx.conf0
-rwxr-xr-x[-rw-r--r--]etc/nginx/sites-available/yummers.dev0
-rwxr-xr-x[-rw-r--r--]etc/nginx/snippets/proxy-headers.conf0
-rwxr-xr-x[-rw-r--r--]etc/systemd/system/obsproxy.service0
-rwxr-xr-x[-rw-r--r--]features.cginc8
-rwxr-xr-x[-rw-r--r--]filamented.cginc0
-rwxr-xr-x[-rw-r--r--]filtering.cginc0
-rwxr-xr-x[-rw-r--r--]geometry.cginc0
-rwxr-xr-x[-rw-r--r--]globals.cginc0
-rwxr-xr-x[-rw-r--r--]impostor.cginc247
-rwxr-xr-x[-rw-r--r--]instancing.cginc0
-rwxr-xr-x[-rw-r--r--]interpolators.cginc0
-rwxr-xr-x[-rw-r--r--]lighting.cginc0
-rwxr-xr-x[-rw-r--r--]load_test.py0
-rwxr-xr-x[-rw-r--r--]lysenko.cginc0
-rwxr-xr-x[-rw-r--r--]math.cginc0
-rwxr-xr-x[-rw-r--r--]opt/obsproxy/requirements.txt0
-rwxr-xr-x[-rw-r--r--]pbr.cginc4
-rwxr-xr-x[-rw-r--r--]pbr_utils.cginc0
-rwxr-xr-x[-rw-r--r--]pema99.cginc0
-rwxr-xr-x[-rw-r--r--]ray_marching.cginc0
-rwxr-xr-x[-rw-r--r--]ray_marching_maps.slang0
-rwxr-xr-x[-rw-r--r--]sampling.cginc0
-rwxr-xr-x[-rw-r--r--]texture_utils.cginc0
-rwxr-xr-x[-rw-r--r--]vertex.cginc0
-rwxr-xr-x[-rw-r--r--]vertex_deformation.slang0
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
index 89affd2..89affd2 100644..100755
--- a/Images/plane_to_tube_to_plane.lorien
+++ b/Images/plane_to_tube_to_plane.lorien
Binary files differ
diff --git a/Images/plane_tube_deformation_derivation.png b/Images/plane_tube_deformation_derivation.png
index 9103ca7..9103ca7 100644..100755
--- a/Images/plane_tube_deformation_derivation.png
+++ b/Images/plane_tube_deformation_derivation.png
Binary files differ
diff --git a/LUTS/dfg_cloth.exr b/LUTS/dfg_cloth.exr
index b30a2a7..b30a2a7 100644..100755
--- a/LUTS/dfg_cloth.exr
+++ b/LUTS/dfg_cloth.exr
Binary files differ
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
index 016c35d..016c35d 100644..100755
--- a/LUTS/dfg_standard.exr
+++ b/LUTS/dfg_standard.exr
Binary files differ
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