- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在片段着色器中的网格上进行光线跟踪。我已经编写了下面的着色器来做到这一点(顶点着色器只是绘制一个屏幕四边形)。
#version 150
uniform mat4 mInvProj, mInvRot;
uniform vec4 vCamPos;
varying vec4 vPosition;
int test(vec3 p)
{
if (p.x > -4.0 && p.x < 4.0
&& p.y > -4.0 && p.y < 4.0
&& ((p.z < -4.0 && p.z > -8.0) || (p.z > 4.0 && p.z < 8.0)))
return 1;
return 0;
}
void main(void) {
vec4 cOut = vec4(0, 0, 0, 0);
vec4 vWorldSpace = mInvRot * mInvProj * vPosition;
vec3 vRayOrg = vCamPos.xyz;
vec3 vRayDir = normalize(vWorldSpace.xyz);
// http://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm
vec3 adelta = abs(vRayDir);
int increaser;
vec3 gradient, sgradient;
if (adelta.x > adelta.y && adelta.x > adelta.z)
{
increaser = 0;
gradient = vec3(vRayDir.x > 0.0? 1.0: -1.0, vRayDir.y / vRayDir.x, vRayDir.z / vRayDir.x);
sgradient = vec3(0.0, gradient.y > 0.0? 1.0: -1.0, gradient.z > 0.0? 1.0: -1.0);
}
else if (adelta.y > adelta.x && adelta.y > adelta.z)
{
increaser = 1;
gradient = vec3(vRayDir.x / vRayDir.y, vRayDir.y > 0.0? 1.0: -1.0, vRayDir.z / vRayDir.y);
sgradient = vec3(gradient.x > 0.0? 1.0: -1.0, 0.0, gradient.z > 0.0? 1.0: -1.0);
}
else
{
increaser = 2;
gradient = vec3(vRayDir.x / vRayDir.z, vRayDir.y / vRayDir.z, vRayDir.z > 0.0? 1.0: -1.0);
sgradient = vec3(gradient.x > 0.0? 1.0: -1.0, gradient.y > 0.0? 1.0: -1.0, 0.0);
}
vec3 walk = vRayOrg;
for (int i = 0; i < 64; ++i)
{
vec3 fwalk = floor(walk);
if (test(fwalk) > 0)
{
vec3 c = abs(fwalk) / 4.0;
cOut = vec4(c, 1.0);
break;
}
vec3 nextwalk = walk + gradient;
vec3 fnextwalk = floor(nextwalk);
bool xChanged = fnextwalk.x != fwalk.x;
bool yChanged = fnextwalk.y != fwalk.y;
bool zChanged = fnextwalk.z != fwalk.z;
if (increaser == 0)
{
if ((yChanged && test(fwalk + vec3(0.0, sgradient.y, 0.0)) > 0)
|| (zChanged && test(fwalk + vec3(0.0, 0.0, sgradient.z)) > 0)
|| (yChanged && zChanged && test(fwalk + vec3(0.0, sgradient.y, sgradient.z)) > 0))
{
vec3 c = abs(fwalk) / 4.0;
cOut = vec4(c, 1.0);
break;
}
}
else if (increaser == 1)
{
if ((xChanged && test(fwalk + vec3(sgradient.x, 0.0, 0.0)) > 0)
|| (zChanged && test(fwalk + vec3(0.0, 0.0, sgradient.z)) > 0)
|| (xChanged && zChanged && test(fwalk + vec3(sgradient.x, 0.0, sgradient.z)) > 0))
{
vec3 c = abs(fwalk) / 4.0;
cOut = vec4(c, 1.0);
break;
}
}
else
{
if ((xChanged && test(fwalk + vec3(sgradient.x, 0.0, 0.0)) > 0)
|| (yChanged && test(fwalk + vec3(0.0, sgradient.y, 0.0)) > 0)
|| (xChanged && yChanged && test(fwalk + vec3(sgradient.x, sgradient.y, 0.0)) > 0))
{
vec3 c = abs(fwalk) / 4.0;
cOut = vec4(c, 1.0);
break;
}
}
walk = nextwalk;
}
gl_FragColor = cOut;
}
最佳答案
简短的回答是:着色器中的分支和循环是(可能)邪恶的。
但它远不止于此:阅读此主题以获取更多信息:Efficiency of branching in shaders
它是这样的:
图形适配器有一个或多个 GPU,一个 GPU 有多个内核。每个内核都设计为运行多个线程,但这些线程只能运行完全相同的代码(取决于实现)。
因此,如果 10 个线程必须执行不同的循环,那么只要最大的循环需要运行,这 10 个线程都必须运行(取决于实现,循环可能会比必要的更进一步,或者线程可能会停止) .
与分支相同:如果线程有一个 if,则可能(取决于实现)两个分支都被执行并使用其中一个的结果。
因此,总而言之,如果您希望根据某些条件删除一些计算,那么做更多的数学运算并使用 0 因子可能(并且可能主要是)比编写条件本身和分支更好。
例如:
(using useLighting = 0.0f or 1.0f)
return useLighting * cLightColor * cMaterialColor + (1.0 - useLighting) * cMaterialColor;
if (useLighting < 0.5)
return cMaterialColor;
else
return cLightColor * cMaterialColor;
关于performance - 为什么这个 GLSL 着色器这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16337723/
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!