我一直在为 VR 项目开发 Unity 着色器设置,该设置包含两种视觉效果。
这个过程的红色部分似乎没有按预期工作。当我在片段的计算屏幕位置对
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 渲染的一个常见问题,即屏幕空间坐标并不总是在两只眼睛之间正确对齐。这是因为每只眼睛从稍微不同的角度渲染场景,因此给定片段的屏幕空间坐标对于每只眼睛来说可能略有不同。
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 坐标。如果不是,那么可能还有其他问题。
我希望这有帮助!如果您还有任何疑问,请随时提问。
-$