找回密码
 注册帐号

扫一扫,访问微社区

特定平台的渲染差异

2015-1-8 15:54| 发布者: 杨炎| 查看: 1786| 评论: 0|原作者: 蛮牛|来自: unity3d脚本manual

摘要: 特定平台的渲染差异unity 在不同的平台上运行,而且在某些情况下存在运行差异。大部分时间里 unity 都向您隐藏差异,但有时您仍然可以撞见它们。渲染纹理坐标垂直纹理坐标的惯例与 direct3d、opengl 和 opengl es 不 ...

特定平台的渲染差异

unity 在不同的平台上运行,而且在某些情况下存在运行差异。大部分时间里 unity 都向您隐藏差异,但有时您仍然可以撞见它们。

渲染纹理坐标

垂直纹理坐标的惯例与 direct3dopengl 和 opengl es 不同:

在 direct3d 中,坐标顶部为零,向下增加。

在 opengl 和 opengl es 中,坐标底部为零,向上增加。

大多数时候这都无关紧要,除了渲染到渲染纹理时。在此情况下,unity 渲染到 direct3d 上的纹理时,在内部翻转渲染,以便平台之间的惯例匹配。

当使用图像效果和抗锯齿 (anti-aliasing) 时,不会出现这种情况。在此情况下,unity 渲染到屏幕以获得抗锯齿选项,然后将渲染“解析”为 rendertexture 以便用图像效果 (image effect) 进一步处理。产生的图像效果的源纹理在 direct3d 上没有翻转(不同于其他所有的渲染纹理 (render texture))。

如果图像效果 (image effect) 简单(一次处理一个纹理),这无关紧要,因为graphics.blit会进行处理。

然而,如果在图像效果 (image effect) 中同时处理一个以上的 rendertexture,它们很可能会在不同的垂直方向出现(仅在类似 direct3d 的平台上,并且仅在使用抗锯齿选项时)。您需要在顶点着色器中手动“翻转”屏幕纹理,像这样:

//在 d3d 上使用 aa 时,主纹理与场景深度纹理

//将在不同垂直方向出现。

//因此在这种情况下翻转纹理采样(主纹理

//纹理元件大小将为 y 轴负值)。

#if unity_uv_starts_at_top

if (_maintex_texelsize.y < 0)

uv.y = 1-uv.y;

#endif

请在着色器替换样例工程中查看边缘检测 (edge detection) 场景以了解这样的示例。此处的边缘检测同时使用屏幕纹理和相机的深度 + 法线纹理。

alpha 测试 (alphatest) 和可编程着色器

某些平台,尤其是手机 (opengl es 2.0) 和 direct3d 11,没有固定函数alpha 测试功能。使用可编程着色器时,建议改为使用像素着色器的 cg/hlslclip()函数。

direct3d 11 着色器编译器对语法更挑剔

direct3d 9 和 opengl 使用 nvidia 的 cg 来编译着色器,但 direct3d 11(和 xbox 360)使用 microsoft 的 hlsl 着色器编译器。hlsl 编译器对着色器各种细微错误更挑剔。例如,它不接受没有适当初始化的函数输出值。

您会遇到此类情况的最常见位置是:

有一个“输出”参数的表面着色器顶点修改器。确保像这样初始化输出:

void vert (inout appdata_full v, out input o)

{

unity_initialize_output(input,o);

// ...

}

部分初始化的值,例如返回 float4 的函数,但代码仅设置它的 .xyz 值。确保设置所有的值,或如果只需要这些值,就将其改为 float3。

在顶点着色器中使用tex2d由于顶点着色器中不存在 uv 导数,因此 tex2d 无效;您需要抽取一个详细的纹理层次,例如使用tex2dlod (tex, float4(uv,0,0))。您还需要添加#pragma glsl,使其在 opengl 上运行。

directx 11 hlsl 语法和表面着色器 (surface shader)

当前表面着色器编译管线的有些部分无法理解特定于 dx11 的 hlsl 语法。如果是诸如 structuredbuffers、rwtextures 和其他非 dx9 语法的 hlsl 功能,则您必须将其纳入只有 dx11 的预处理宏:

#ifdef shader_api_d3d11

// 特定于 dx11 的编码,如

structuredbuffermycolors;

rwtexture2dmyrandomwritetexture;

#endif

使用带 opengl es 2.0 的 opengl 着色语言 (glsl) 着色器

opengl es 2.0 只为 opengl 着色语言 (glsl) 提供有限的本地支持,例如 opengl es 2.0 层不为着色器提供内置参数。

unity 执行内置参数的方式与 opengl 完全相同,但缺失以下内置参数:

gl_clipvertex

gl_secondarycolor

gl_depthrange

gl_lightsourceparameters结构的halfvector属性

gl_frontfacing

gl_frontlightmodelproduct

gl_backlightmodelproduct

gl_backmaterial

gl_point

gl_pointsize

gl_clipplane

gl_eyeplaner,gl_eyeplanes,gl_eyeplanet,gl_eyeplaneq

gl_objectplaner,gl_objectplanes,gl_objectplanet,gl_objectplaneq

gl_fog

ipad2、msaa 和 alpha 混合几何结构

当 msaa 已激活并且用 rgba colormask 绘制 alpha 混合几何结构时,apple 驱动程序有产生假象的错误。为避免出现假象,遇到此配置时我们强制使用 rgba colormask,尽管它会将内置 glow fx 渲染成无法使用(因为它需要 dst_alpha 获取强度值)。同时,如果您自己编写程序,请更新着色器(请参阅pass docs)中的“渲染设置 (render setup) -> colormask”。)

相关阅读

文章点评
相关文章