GPU Pro 2 ------ Volume Decals_volume decal shader代码-程序员宅基地

技术标签: 图形引擎  游戏引擎  手机游戏  技术理论  渲染效果  GPU  其它文章  游戏开发  

花了$60买了正版的GPU Pro2。坚持每天学一点。

边学习边翻译,希望也能对别人有些益处。从Volume Decals 开始,可以从Emil Persson 的官网上下到源代码 http://www.humus.name/index.php?page=3D&ID=83


Volume Decals

                           Emil Persson

5.1 介绍

贴花通常应用于放置在场景几何体面上的贴图。在大部分情况下,这个应用都表现的很好。用贴图四边形来做贴花会造成Z-fighting的问题。在下面的几何体可能不平坦,造成贴花就绘制在了几向体的下面。在边缘处,贴花也有可能出现悬挂的情况。解决这个问题通常的办法是对贴花引入裁剪或者在这种情况下就不做贴花。将贴花合适的贴在任意的模型上需要很复杂的代码,必须要取得模型的顶点。在PC上意味着如果要取得很好的性能,就必须把模型几何体信息拷贝一份到内存中。有一个典型的例子,向一块石头射击,贴花可能没有跟对齐中心。这篇文章用体积贴花投影到场景几何体上的方法解决了所有的问题,这里面用到了深度缓存。


5.2 体积贴花

5.2.1 找到场景坐标

这个技术的想法是在选中的区域把贴花当成一个体积来渲染。任何一种凸的几何体都可以,但一般都用球或者盒子。通过采样深度缓存,fragment shader 计算在下面的几何体的位置。可以通过下面的方法实现:

// texCoord is the pixel's normalized screen position
float depth = DepthTex.Sample(Filter, texCoord);
float4 scrPos = float4(texCoord, depth, 1.0);
float4 wPos = mul(scrPos, ScreenToWorld);

图 5.1 贴花实例

float3 pos = wPos.xyz /wPos.w;
// pos now contains pixel position in world space

ScreenToWorld 矩阵是一个复合矩阵,包含了两个转换:从屏幕坐标系到裁剪坐标系,从裁剪坐标系到世界坐标系。从世界坐标到裁剪坐标是由ViewProjection矩阵完成的,所以这里要用这个矩阵的逆。裁剪空间范围x和y是从-1到1,然而贴图坐标是从0到1,所以我们需要一个对齐的操作。由以下的代码完成:

float4 ScaleToWorld = Scale(2, -2, 1) * Tranlate(-1, 1, 0) * Inverse(ViewProj);

我们感兴趣的是体积贴花和这个局部位置的关系。这个局部位置会被当成贴图坐标去采样一个体积贴花。因为这个贴花是个体积贴图,它会非常好的包裹着非连续性的特殊的图形(图5.2)。为了给每一个贴花唯一表现,可以给这个矩阵加一个随机的旋转。可以通过下面来构造:


float4 ScreenToLocal = Scale(2, -2, 1) * Translate(-1, 1, 0) * Inverse(ViewProj) * DecalTranslation * DecalScale * DecalRotation;

全部的fragment shader如下:

Texture2D<float> DepthTex;
SamplerState DepthFilter;

Texture3D<float4> DecalTex;
SamplerState DecalFilter;

cbuffer Constants
{
    float4x4 ScreenToLocal;
    float2 PixelSize;
};

float4 main(PsIn in) : SV_Target
{
    // Compute normalized screen position
    float2 texCoord = In.Position.xy * PixelSize;

    // Comput local position of scene geometry
    float depth = DepthTex.Sample(DepthFilter, texCoord);
    float4 scrPos = float4(texCoord, depth, 1.0f);
    float4 wPos = mul(scrPos, ScreenToLocal);

    // Sample decal
    float3 coord = wPos.xyz / wPos.w;
    return DecalTex.Sample(DecalFilter, coord);
}

5.2.2 开发和问题

这个系统可以在延迟渲染技术中实现的相当完美。贴花可以在geometry buffer (G-buffer) pass之后渲染,而且还可以将一些diffuse color,specularity color应用上去。这个技术同样适用于预渲染,意味着在贴花中还可以应用光照信息。

在前向渲染系统中,贴花必须在光照计算之后。举例说一些情况,爆炸后的烧焦的样子呀,贴花可以很好的与目标缓存进行试算。更复杂的一些情况是,用alpha 进行混合,常用于子弹打出一个洞,这种情况下,必须考虑到光照。其中一个解决方案是,当渲染时,在shader中的alpha通道中保存所有光照的亮度;在贴花时能将每个颜色通道预乘以alpha,在混合器中与目标透明度相乘以得到较好的效果。这并没有将灯光的颜色考虑在内,但如果灯光是清楚的白色,结果还是很好的。另一个解决办法是利用最近一个灯光的衰减数,不考虑法线。相应的,法线可以从深度缓存中得到,尽管这会很慢。

这种贴花技术有一个问题是,会在体积贴花内的所有的物体上应用上贴花。对于静态物体这没有问题,但如果你有一个巨大的贴花,然后有一些动态的物体在其内移动,这些动态的物体会得到贴花污点在其上面,举个例子,比如之前有一个炸弹在道路上弹了,之后有一个汽车从上面开过。这个问题可以通过在贴花之后渲染动态物体来解决。一个更好的解决办法是按出现的先后顺序去渲染,这样之后移动到贴花上的物体就不会受到贴花的影响。还有一个解决办法,是使用物体的ID号,贴花可以记录会应用贴图的物体。


5.2.3 优化

在一些平台上支持depth-bounds测试,depth-bounds测试会用于提高性能 。在其它一些平台上,动态分支会用于仿真这一功能,通过对比采样的深度缓存和depth-bounds。无论如何,这样Shader会短一些,很大一部分fragment 可以避免做深度测试。在一些情况下,如果不裁剪任何东西会更快一些。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/pizi0475/article/details/48156307

智能推荐

Springboot+Websocket Client+断线重连的例子_org.java_websocket.client.websocketclient 实现断开 重试、-程序员宅基地

文章浏览阅读3.4k次,点赞3次,收藏14次。# 开发环境IDEA+JDK1.8pom引入 <!--websocket作为客户端--> <dependency> <groupId>org.java-websocket</groupId> <artifactId>Java-WebSocket</artifactId> <version>1.3.5</version>_org.java_websocket.client.websocketclient 实现断开 重试、重连机制

详解Python字典的底层原理——哈希表(Python面试必备)_python中字典的底层实现原理-程序员宅基地

文章浏览阅读1w次,点赞22次,收藏93次。详解Python字典的底层原理————哈希表(Python面试必备)作者:Loren no hurry2019-06-9Python面试经常会被问到:你能说一说Python字典的底层实现原理吗?这个问题可以从三个方面来回答:1.python字典及其特性字典是Python的一种可变、无序容器数据结构,它的元素以键值对的形式存在,键值唯一,它的特点搜索速度很快:数据量增加10000倍,..._python中字典的底层实现原理

CSAPP深入理解操作系统 课程实验 bomb 反向编译 汇编(3)_boompack 反编译-程序员宅基地

文章浏览阅读5.5k次,点赞8次,收藏29次。第四关: 首先也是栈开辟:然后由第三关以及前面对sscanf函数的分析可知,这里应该也是要输入两个数。参数1从-0xc(%ebp)加载,参数2从-0x10(%ebp)处加载。0x804a23e应该里面的内容也是sscanf的输入格式之类的。返回值要等于2,不然会引爆炸弹。接一下来一段说明输入的第一个参数的范围要在0-14之间接下来,赋初始_boompack 反编译

Java8新特性 - ZoneDateTime 了解_java zoneddatetime-程序员宅基地

文章浏览阅读1.6k次。1.地理知识 : 时区图2. ZoneDateTime 类ZoneDateTime : 是带时区的日期时间类。区别于 LocalDateTime 类,LocalDateTime 类是 默认时区的日期时间类,中国默认的 时区是 【东八区】。因此,当LocalDateTime 手动指定 时区后 就变成了ZoneDateTime。时区id 可以通过ZoneId类的API 直接获取。3. 相关的API 代码下面简单演示一下相关的操作package com.northcastle.K_Date_java zoneddatetime

研究生课题_fdsst-程序员宅基地

文章浏览阅读352次,点赞2次,收藏2次。FXGroup研究生课题_fdsst

CMake与Make最简单直接的区别_cmake与qcmake的区别-程序员宅基地

文章浏览阅读793次。原文:https://blog.csdn.net/weixin_42491857/article/details/80741060写程序大体步骤为:1.用编辑器编写源代码,如.c文件。2.用编译器编译代码生成目标文件,如.o。3.用链接器连接目标代码生成可执行文件,如.exe。但如果源文件太多,一个一个编译时就会特别麻烦,于是人们想到,为什么不设计一种类似批处理的程序,来批处理..._cmake与qcmake的区别

随便推点

android 触摸监听重写_自定义View中重写onTouchEvent后设置点击监听onClick()方法无效冲突解决...-程序员宅基地

文章浏览阅读834次。想来也好久没到简书发东西了,其实一直在写着些有的没的,倒有想着年底把它们都发出来.今天之所以写下这篇是觉得有必要记录一下这种奇奇怪怪的问题,花费了我大半时间不说还没半点技术性质可言...好了废话不多说场景重现:因项目需要,开发者x某在充分了解了原型图后自定义了符合功能要求的自定义view(继承view而非ViewGroup),按着各个重写方法定制界面,事件处理(onTouchEvent())后测试..._android 自定义view onclick

export CROSS_COMPILE=arm-linux-gnueabi- 之后,无法编译kernel-程序员宅基地

文章浏览阅读8.5k次。打算编译另一个kernel,一不小心export CROSS_COMPILE=arm-linux-gnueabi- 结果回到popmetal编译时候,提示arm-linux-gnueabi- gcc no such file 好吧,arm-linux-gnueabi- gcc -v 试试,提示安装 安装之后,再次执行make i.img -j4之后报错看来原来_export cross_compile=

uboot 代码执行顺序-程序员宅基地

文章浏览阅读154次。ref:http://blog.chinaunix.net/uid-30352139-id-5128405.htmluboot: 2014.071.1 U-boot相关文件boards.cfg:   ARCH = ARM   CPU = ARMv7   SOC = exynos   BOARD = smdkc210   VENDER ..._ldr r0, =_start mcr p15, 0, r0, c12, c0, 0 @set vbar

Cadence 16.6基本操作技巧(一)-程序员宅基地

文章浏览阅读2.5w次,点赞23次,收藏198次。都是工作上碰到的需要学习的知识,比较实用。1、修改Pin脚网络set up --user preference EditorLogic--net logicOption处选择网络,然后find处选择Pins,之后点击要修改网络的Pin即可将原来的网络修改为所选择的网络。2、在使用测量工具的时候,...

收藏 | 90+深度学习开源数据集整理:包括目标检测、工业缺陷、图像分割等多个方向(附下载)...-程序员宅基地

文章浏览阅读7.2k次,点赞2次,收藏14次。来源:极市平台本文多干货,建议收藏本文整理汇总了90+深度学习各方向的开源数据集,包含了小目标检测、目标检测、工业缺陷检测、人脸识别、姿态估计、图像分割、图像识别等方向。附下载链接。小目标检测1. AI-TOD航空图像数据集数据集下载地址:http://m6z.cn/5MjlYkAI-TOD 在 28,036 张航拍图像中包含 8 个类别的 700,621 个对象实例..._bmp图片测试集下载

LVS-NAT 负载均衡 轮询模式 从安装部署到访问网站_lvs-nat访问不到网页-程序员宅基地

文章浏览阅读378次。文章目录话不多说!实验环境实验目的来吧!!展示!!!配置NFS文件服务器配置节点服务器配置 LVM验证实验关于负载均衡的原理,我I在上一篇写的很详细~~(大概吧)~~ 了链接在这:博客地址点我话不多说!实验环境使用 VM虚拟机进行演示共使用 六 台虚拟机:1、负载均衡调度器,同时作为进出口网关 CentOS7.62、三台 节点服务器 CentOS7.63、一台 NFS 文件服务器 CentOS7.64、一台 客户端 使用 Win10实验目的客户端20端访问服务器群集,验证轮询_lvs-nat访问不到网页

推荐文章

热门文章

相关标签