【发布时间】:2017-07-03 07:01:04
【问题描述】:
我编写了以下着色器来渲染带有一堆同心圆的图案。最终我想让每个旋转的球体成为一个发光体,沿着these lines 创造一些东西。
当然,现在我只是在做最基本的部分来渲染不同的对象。
不幸的是,着色器速度非常慢(在高端 macbook 上为 16fps 全屏)。我很确定这是由于我在着色器中有许多 for 循环和分支。我想知道如何以更优化的方式实现我想要实现的几何图形:
编辑:您可以在此处运行着色器:https://www.shadertoy.com/view/lssyRH
我缺少的一个明显优化是,目前所有片段都针对整个 24 个周围的圆圈进行检查。通过检查片段是否与图表的外部边界相交来完全放弃这些检查将非常快速和容易。我想我只是想了解如何做这样的事情的最佳实践。
#define N 10
#define M 5
#define K 24
#define M_PI 3.1415926535897932384626433832795
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
float aspectRatio = iResolution.x / iResolution.y;
float h = 1.0;
float w = aspectRatio;
vec2 uv = vec2(fragCoord.x / iResolution.x * aspectRatio, fragCoord.y / iResolution.y);
float radius = 0.01;
float orbitR = 0.02;
float orbiterRadius = 0.005;
float centerRadius = 0.002;
float encloseR = 2.0 * orbitR;
float encloserRadius = 0.002;
float spacingX = (w / (float(N) + 1.0));
float spacingY = h / (float(M) + 1.0);
float x = 0.0;
float y = 0.0;
vec4 totalLight = vec4(0.0, 0.0, 0.0, 1.0);
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
// compute the center of the diagram
vec2 center = vec2(spacingX * (float(i) + 1.0), spacingY * (float(j) + 1.0));
x = center.x + orbitR * cos(iGlobalTime);
y = center.y + orbitR * sin(iGlobalTime);
vec2 bulb = vec2(x,y);
if (length(uv - center) < centerRadius) {
// frag intersects white center marker
fragColor = vec4(1.0);
return;
} else if (length(uv - bulb) < radius) {
// intersects rotating "light"
fragColor = vec4(uv,0.5+0.5*sin(iGlobalTime),1.0);
return;
} else {
// intersects one of the enclosing 24 cylinders
for(int k = 0; k < K; k++) {
float theta = M_PI * 2.0 * float(k)/ float(K);
x = center.x + cos(theta) * encloseR;
y = center.y + sin(theta) * encloseR;
vec2 encloser = vec2(x,y);
if (length(uv - encloser) < encloserRadius) {
fragColor = vec4(uv,0.5+0.5*sin(iGlobalTime),1.0);
return;
}
}
}
}
}
}
【问题讨论】:
-
你能预先计算出无数的 sin() 和 cos() 并以某种方式将它们发送到着色器,而不是在着色器中计算它们吗?
-
您的着色器甚至无法正常工作,至少对我来说有很多伪影,并且您有很多未使用的变量...
标签: opengl-es glsl webgl shader raytracing