D3D渲染技术之混合案例
在本篇内容中,我们将介绍用于获得特定效果的一些混合因子组合, 在这些示例中,我们仅查看RGB混合, Alpha混合的处理方式类似。
无颜色写入
假设我们想要保持原始目标像素的原样,而不是覆盖它或将其与当前光栅化的源像素混合。例如,如果我们只想写入深度/模板缓冲区,而不是后台缓冲区。 为此,请将源像素混合因子设置为D3D12_BLEND_ZERO,将目标混合因子设置为D3D12_BLEND_ONE,将混合运算符设置为D3D12_BLEND_OP_ADD。 通过此设置,混合等式可简化为:
在这里给读者举一个例子,实现的方法是将D3D12_RENDER_TARGET_BLEND_DESC :: RenderTargetWriteMask成员设置为0,这样就不会写入任何颜色通道。
上图中,添加源和目标颜色, 添加颜色后,添加会创建更亮的图像。
增加/减少
假设我们要添加具有目标像素的源像素(见上图所示)。 要执行此操作,请将源混合因子设置为D3D12_BLEND_ONE,将目标混合因子设置为D3D12_BLEND_ONE,将混合运算符设置为D3D12_BLEND_OP_ADD。 通过此设置,混合等式可简化为:
我们可以使用上面的混合因子从目标像素中减去源像素,并用D3D12_BLEND_OP_SUBTRACT替换混合操作(见下图所示)。
从目标颜色中减去源颜色, 由于颜色被移除,减法会产生较暗的图像。
相乘
假设我们想要将源像素与其对应的目标像素相乘(见下图所示), 为此,我们将源混合因子设置为D3D12_BLEND_ZERO,将目标混合因子设置为D3D12_BLEND_SRC_COLOR,将混合运算符设置为D3D12_BLEND_OP_ADD。 通过此设置,混合等式可简化为:
将源颜色和目标颜色相乘。
透明度
源α分量被认为是控制源像素的不透明度的百分比(例如,0α表示0%不透明,0.4表示40%不透明,1.0表示100%不透明)。 不透明度和透明度之间的关系只是T = 1 - A,其中A是不透明度,T是透明度。 例如,如果某些东西是0.4不透明的,则它是1 - 0.4 = 0.6透明, 现在假设我们想要根据源像素的不透明度混合源像素和目标像素, 要执行此操作,请将源混合因子设置为D3D12_BLEND_SRC_ALPHA,将目标混合因子设置为D3D12_BLEND_INV_SRC_ALPHA,将混合运算符设置为D3D12_BLEND_OP_ADD。 通过此设置,混合等式可简化为:
例如,假设为as= 0.25,也就是说源像素仅为25%不透明, 然后当源像素和目标像素混合在一起时,我们期望最终颜色将是源像素的25%和目标像素的75%(源像素“后面”的像素)的组合,因为源像素是 75%透明。 上面的等式恰恰说明了这一点:
使用这种混合方法,我们可以绘制透明对象,如前面图中所示。 应该注意的是,使用这种混合方法,绘制对象的顺序很重要。 我们使用以下规则:
绘制不使用混合的对象, 接下来,按照与摄像机的距离对使用混合的对象进行排序, 最后,绘制以前后顺序使用混合的对象。
从后到前绘制顺序的原因是对象与空间背后的对象混合, 因为如果一个物体是透明的,我们可以通过它看到它背后的场景。 因此,必须将透明对象后面的所有像素都写入后缓冲区,以便我们可以将透明源像素与其后面场景的目标像素混合。
对于无颜色写入介绍的混合方法,绘制顺序无关紧要,因为它只是阻止源像素写入后缓冲区。 对于增加/减少和相乘讨论的混合方法,我们仍然首先绘制非混合对象,最后绘制混合对象; 这是因为我们希望在开始混合之前首先将所有非混合几何体放置在后缓冲区上。 但是,我们不需要对使用混合的对象进行排序, 这是因为操作是可交换的。 也就是说,如果从后缓冲区像素颜色B开始,然后对该像素执行n加法/减法/乘法混合,则顺序无关紧要:
混合和深度缓冲
当与加法/减法/乘法混合混合时,深度测试会出现问题,我们将仅使用加法混合来解释,但是相同的想法适用于减法/乘法混合。如果我们使用加法混合渲染一组S对象,那么想法是S中的对象不会相互模糊;相反,它们的颜色只是累积(见下图所示)。因此,我们不希望在S中对象之间进行深度测试;因为如果我们这样做,没有从后到前的绘制顺序,S中的一个对象会遮挡S中的另一个对象,从而导致像素片段由于深度测试而被拒绝,这意味着对象的像素颜色不会被累积到混合总和中。我们可以通过在S中渲染对象时禁用对深度缓冲区的写入来禁用S中对象之间的深度测试。由于禁用了深度写入,因此使用加法混合绘制的S中对象的深度将不会写入深度缓冲区;因此,由于深度测试,该对象不会遮挡后面S中任何后来绘制的对象。请注意,我们仅在S中绘制对象时禁用深度写入(使用附加混合绘制的对象集)。深度测试仍然启用,这样,非混合几何体(在混合几何体之前绘制)仍将模糊其后面的混合几何体。例如,如果在墙后面有一组加法混合的对象,则不会看到混合对象,因为实心墙遮挡了它们。如何禁用深度写入,一般地说,配置深度测试设置将在下面博客中介绍。
通过添加混合,在更多颗粒重叠并加在一起的源点附近强度更大, 随着颗粒扩散,强度减弱,因为较少的颗粒重叠并被加在一起。
Alpha 通道
在透明中的示例显示源alpha分量可用于RGB混合以控制透明度, 混合方程中使用的源颜色来自像素着色器。 我们将漫反射材质的alpha值作为像素着色器的alpha输出返回, 因此,漫反射贴图的alpha通道用于控制透明度。
float4 PS(VertexOut pin) : SV_Target
{float4 diffuseAlbedo = gDiffuseMap.Sample(gsamAnisotropicWrap, pin.TexC) * gDiffuseAlbedo;…// Common convention to take alpha from diffuse albedo.litColor.a = diffuseAlbedo.a;return litColor;
}
通常可以在任何流行的图像编辑软件(如Adobe Photoshop)中添加Alpha通道,然后将图像保存为支持像DDS这样的Alpha通道的图像格式。
裁剪像素
有时我们希望不处理源像素, 这可以通过内在的HLSL裁剪(x)函数来完成, 此函数只能在像素着色器中调用,如果x <0,它将丢弃当前像素进一步处理。此函数对于渲染线栅纹理很有用,例如,如下图所示。 也就是说,渲染像素的像素是完全不透明或完全透明的。
与它的Alpha通道的铁丝网纹理, 具有黑色alpha值的像素将被裁剪功能不被绘制; 因此,只留下铁丝网。 实质上,alpha通道用于从纹理中屏蔽非栅栏像素。
在像素着色器中,我们抓取纹理的alpha分量, 如果它是一个接近0的小值,表示该像素是完全透明的,那么我们将该像素剪辑为进一步处理。
float4 PS(VertexOut pin) : SV_Target
{float4 diffuseAlbedo = gDiffuseMap.Sample(gsamAnisotropicWrap, pin.TexC) * gDiffuseAlbedo;#ifdef ALPHA_TEST// Discard pixel if texture alpha < 0.1. We do this test as soon // as possible in the shader so that we can potentially exit the// shader early, thereby skipping the rest of the shader code.clip(diffuseAlbedo.a - 0.1f);
#endif…// Common convention to take alpha from diffuse albedo.litColor.a = diffuseAlbedo.a;return litColor;
}
观察我们只在定义了ALPHA_TEST时裁剪, 这是因为我们可能不想为某些渲染项调用裁剪,因此我们需要能够通过使用专门的着色器来打开/关闭它。 此外,使用alpha测试需要付出代价,因此我们只应在需要时使用它。
请注意,使用混合可以获得相同的结果,首先,不需要进行混合计算(可以禁用混合), 此外,可以通过像素着色器丢弃像素。
由于过滤,alpha通道可能会有点模糊,因此在裁剪像素时应留下一些缓冲空间。 例如,剪切像素的alpha值接近0,但不一定恰好为零。
下图显示了“Blend”演示的屏幕截图, 它使用透明混合渲染半透明水,并使用裁剪测试渲染线栅栏盒, 值得一提的另一个变化是,因为我们现在可以通过带有栅栏纹理的方框看到,我们想要禁用alpha测试对象的背面剔除:
D3D12_GRAPHICS_PIPELINE_STATE_DESC alphaTestedPsoDesc = opaquePsoDesc;
alphaTestedPsoDesc.PS =
{ reinterpret_cast<BYTE*>(mShaders["alphaTestedPS"]->GetBufferPointer()),mShaders["alphaTestedPS"]->GetBufferSize()
};
alphaTestedPsoDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
ThrowIfFailed(md3dDevice->CreateGraphicsPipelineState(&alphaTestedPsoDesc, IID_PPV_ARGS(&mPSOs["alphaTested"])));
代码下载地址:链接:https://pan.baidu.com/s/1X0Vikf6qGYGPKU-Nwf-wYA
提取码:h79q
D3D渲染技术之混合案例相关推荐
- D3D12渲染技术之混合
本篇博客给读者介绍混合,见下图所示, 我们首先绘制地形,然后绘制木箱,然后将地形和木箱像素放在后面的缓冲区上. 我们使用混合将水面绘制到后面的缓冲区,以便水像素与地形混合,并在后面缓冲区上放置像素,使 ...
- D3D渲染技术之纹理
纹理映射是一种将图像数据映射到三角形上的技术,从而能增加场景的细节和真实感. 例如,我们可以通过在每一侧绘制板条纹理来构建一个立方体并将其转换为板条箱如下图所示. 在这里给读者教读者如何学习纹理技术: ...
- D3D渲染技术之简易框架
在上一篇博客中,我们介绍了D3D12初始化流程实现过程,本篇博客我们搭建一个简易的迷你型小框架用于实现D3D12的初始化流程,在游戏编程中,都需要定时器的封装,比如骨骼动画需要,联网也需要定期判断是否 ...
- D3D渲染遇到的问题
D3D渲染作为windows平台游戏及视频开发的一把利剑,做游戏是必须要用D3D这个渲染引擎,使用GUP来渲染,保证流畅度,GDI+真的不适合做大屏渲染和高帧率渲染,效率实在很差,毕竟是一款简单易用的 ...
- 第一回 开篇 D3D渲染流程简介
第一回 开篇 D3D渲染流程简介 http://developer.178.com/201004/65293187592.html 开发这个3D engine已经两年半了,从06年8月刚开始统计的4万 ...
- 高并发图片实时渲染技术在阿里妈妈的大规模应用
个性化推荐已经广泛应用到新媒体.电商.游戏等领域,当你打开手机淘宝的时候,淘宝会根据你的浏览和购买等历史行为,提供个性化的商品推荐.那么,这些形式多样.风格各异的个性化商品展示是怎样最终呈现到APP中 ...
- unity着色器和屏幕特效开发秘笈_Oculus研发分享:开发移动VR内容时应避免的PC渲染技术...
查看引用/信息源请点击:映维网 开发移动VR内容时应避免的PC渲染技术 (映维网 2019年11月25日)有不少开发者都是以与PC相同的方式来开发Quest游戏,但这可能会导致优化性能方面出现大量困难 ...
- 《OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例》一第6章 让场景更逼真——光照效果...
本节书摘来异步社区<OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例>一书中的第6章,第6.1节,作者: 吴亚峰 责编: 张涛,更多章节内容可以访问云栖社区"异步社 ...
- 毛发及眼球的渲染技术
前言 这是关于角色渲染技术的第二篇,前一篇关于皮肤的渲染方法可见这里. 实际上为了逼真地还原一个角色,除了渲染技术外,在很多游戏中还使用了动画.物理仿真等其他方面的技术,这些技术也非常重要.譬如今年的 ...
最新文章
- Facebook数据丑闻后续:“罪魁”剑桥分析破产,但它还留了一手数据
- 密织“地网” 南充“试水”智慧安防
- ICPC 徐州 H Yuuki and a problem (树状数组套主席树)
- laravel mysql pdo,更改Laravel中的基本PDO配置
- 数组转List的3种方法和使用对比!
- 9 FI配置-财务会计-维护会计年度变式
- CSS/CSS3常用样式与web移动端资源
- 通过url判断当前页,动态给导航加样式
- idea如何设置类头注释和方法注释
- 「代码随想录」322. 零钱兑换 【动态规划】力扣详解!
- python字体描边_使用 python 将文泉驿字体导出为 fnt 格式的bitmap font
- 计算机怎么退出远程桌面连接,怎么退出远程桌面控制?远程桌面软件哪个好?
- pythonjam教程_colorama(pythonjam官网)
- CKA-1.26 模拟试题
- .net core word转pdf_Enolsoft PDF to Word with OCR for Mac(PDF转Word软件)
- Packet Tracer(第二期)--4RIP
- 把时间当作朋友——第3章 管理
- 何为Robocode
- 飞机馆_熟知航空知识,传承航空文化:杭集小学生走进扬州航空馆
- 在冥冥中那些昵称是见识到