VR 中片段着色器的示例屏幕空间纹理?

问题描述 投票:0回答:1

我一直在为 VR 项目开发 Unity 着色器设置,该设置包含两种视觉效果。

  • 模糊的轮廓发光。这很好用。
  • “内发光”类型的效果。这在 VR/立体中不起作用,但在单视场渲染中工作得很好。

Images and schematic here.

这个过程的红色部分似乎没有按预期工作。当我在片段的计算屏幕位置对

Prepass
RenderTexture 进行采样时,它在渲染时与模型不对齐。结果,“内发光”被抵消。应该在彩色区域内的样本落在外面,反之亦然。

代码

“红色”垂直着色器:

v2f vert (appdata v)
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex);

            // Get screen position of vertex so we can sample _GlowPrePassTex in screenspace
            o.screenpos = ComputeScreenPos(o.vertex);
            return o;
        }

“红色”碎片着色器:

fixed4 frag (v2f i) : SV_Target
        {               
            // Get rim component
            half tDot = saturate(dot(i.normal, i.viewdir));

            // Sample from _GlowPrePassTex at the fragment's screenspace position
            float2 screenUV = i.screenpos.xy / i.screenpos.w;

            #if UNITY_SINGLE_PASS_STEREO
                float4 scaleOffset = unity_StereoScaleOffset[unity_StereoEyeIndex];
                screenUV = (screenUV - scaleOffset.zw) / scaleOffset.xy;    // I don't know?
            #endif

            fixed4 hlSample = tex2D(_GlowPrePassTex, screenUV);

            // Standard hard rim
            fixed4 col = _RimColor * pow(1.0 - tDot, _RimExponent);

            // Modulate hlSample by (softer) rim strength and add to result
            col += hlSample * pow(1.0 - tDot, _HLExponent);

            return col;
        }

我尝试过的事情:

我查看了这个Unity手册页上的示例并尝试了相关的示例(上面的片段着色器中包含一个),但无济于事。我不确定每个目标应该实现什么以及以什么顺序使用它们。附带问题:如果我们切换到单通道立体声,许多其他效果将停止工作并且需要调整。

我还编写了一个版本,可以在“红色”片段着色器本身内重新计算 Prepass 结果,并且该版本有效。然而,此时我们基本上执行了两次相同的(昂贵的)计算。如果可能的话,我想避免这种解决方案。

问题:

  • 我是否正在尝试做一些在 VR/立体中根本不起作用的事情?
  • 如果没有,如何获取给定片段的正确屏幕空间 UV 坐标,以从 VR 中的纹理进行采样?

提前非常感谢!

unity-game-engine fragment-shader virtual-reality
1个回答
0
投票

看到这个问题永远不会得到答案,以未来的方式跳跃,以防将来有人遇到这种情况;

您似乎遇到了 VR 渲染的一个常见问题,即屏幕空间坐标并不总是在两只眼睛之间正确对齐。这是因为每只眼睛从稍微不同的角度渲染场景,因此给定片段的屏幕空间坐标对于每只眼睛来说可能略有不同。

UNITY_SINGLE_PASS_STEREO 宏和 unity_StereoScaleOffset 变量是 Unity 处理此问题的方法。在单通道立体渲染中,双眼同时渲染,因此需要为每只眼睛调整屏幕空间坐标。

您突出显示的代码行:


    float4 scaleOffset = unity_StereoScaleOffset[unity_StereoEyeIndex];
screenUV = (screenUV - scaleOffset.zw) / scaleOffset.xy;    // I don't know?

正是这样做的。它根据当前正在渲染的眼睛来调整屏幕空间坐标。 unity_StereoEyeIndex 变量为 0 或 1,具体取决于渲染的是左眼还是右眼。 unity_StereoScaleOffset 变量是一个由两个 float4 值组成的数组,每只眼睛一个,其中包含调整屏幕空间坐标所需的比例和偏移值。

如果此调整无法正常工作,可能是因为 unity_StereoScaleOffset 值设置不正确。这可能是由于多种原因造成的,例如 VR 相机配置错误或 VR 渲染设置存在问题。

至于你的问题:

不,你想要做的事情应该可以在 VR/立体中实现。这只是正确处理每只眼睛的屏幕空间坐标的问题。

您发布的代码应该为您提供 VR 中给定片段的正确屏幕空间 UV 坐标。如果不是,那么可能还有其他问题。

我希望这有帮助!如果您还有任何疑问,请随时提问。

-$

© www.soinside.com 2019 - 2024. All rights reserved.