gpt4 book ai didi

opengl - OpenGL Pixel Shader:如何在每个像素上生成0和1的随机矩阵?

转载 作者:行者123 更新时间:2023-12-02 08:54:34 26 4
gpt4 key购买 nike

因此,我需要的很简单:每次执行着色器(在每个像素上表示含义)时,我都需要计算10resolution == originalImageResolution的随机矩阵。怎么做这样的事情?

到目前为止,我为shadertoy随机矩阵创建了一个分辨率,该分辨率设置为15 x 15,因为当我尝试200 x 200之类的东西时,gpu会使chrome掉色,而实际上我需要完整的图像分辨率

#ifdef GL_ES
precision highp float;
#endif

uniform vec2 resolution;
uniform float time;
uniform sampler2D tex0;

float rand(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * (43758.5453+ time));
}
vec3 getOne(){
vec2 p = gl_FragCoord.xy / resolution.xy;
vec3 one;
for(int i=0;i<15;i++){
for(int j=0;j<15;j++){
if(rand(p)<=0.5)
one = (one.xyz + texture2D(tex0,vec2(j,i)).xyz)/2.0;
}
}
return one;
}

void main(void)
{
gl_FragColor = vec4(getOne(),1.0);
}


还有一个适用于Adobe像素弯曲器的功能:

<languageVersion: 1.0;> 

kernel random
< namespace : "Random";
vendor : "Kabumbus";
version : 3;
description : "not as random as needed, not as fast as needed"; >
{

input image4 src;
output float4 outputColor;

float rand(float2 co, float2 co2){
return fract(sin(dot(co.xy ,float2(12.9898,78.233))) * (43758.5453 + (co2.x + co2.y )));
}

float4 getOne(){
float4 one;
float2 r = outCoord();
for(int i=0;i<200;i++){
for(int j=0;j<200;j++){
if(rand(r, float2(i,j))>=1.0)
one = (one + sampleLinear(src,float2(j,i)))/2.0;
}
}
return one;
}
void
evaluatePixel()
{
float4 oc = getOne();
outputColor = oc;
}
}


因此,我真正的问题是-我的着色器使我的GPU衍生工具掉落了。如何将GLSL用于与我现在相同的目的,但不会失败,并且如果可能的话会更快?

更新:
我要创建的称为 Single-Pixel Camera(Google压缩成像或压缩传感),我想创建基于gpu的软件实现。

想法很简单:


我们有一个图像- NxM
对于图像中的每个像素,我们希望GPU执行以下操作:


生成随机值的 NxM矩阵- 0 s和 1 s。
计算原始图像上坐标对应于我们随机 1矩阵中 NxM s坐标的所有像素的 arithmetic mean
将算术平均值的输出结果作为像素颜色。



我试图在着色器中实现的是模拟这个警惕的过程。

在gpu上尝试这样做的真正愚蠢之处是:


压缩感测并不能使我们计算出这样的算术平均值的 NxM矩阵,它只是满足于和平(例如 1/3)。因此,我对GPU施加了不必要的压力。但是,对更多数据进行测试并不总是一个坏主意。

最佳答案

感谢您添加更多详细信息以澄清您的问题。我的评论太长了,所以我要回答。将评论移到此处以使它们保持在一起:

抱歉,请放慢速度,但我想了解问题和目标。在您的GLSL示例中,我看不到正在生成矩阵。我看到单个vec3是通过对15 x 15纹理(矩阵)的单元格的随机选择(随时间变化)求和而生成的。并且针对每个像素重新计算vec3。然后,将vec3用作像素颜色。

因此,我不清楚您是要创建矩阵还是只为每个像素计算一个值。从某种意义上讲,后者是一个“矩阵”,但是计算200 x 200像素的简单随机值不会使图形驱动程序劳损。您还说过您想使用矩阵。所以我认为那不是你的意思。

我试图理解为什么您要一个矩阵-为所有像素保留一致的随机基础?如果是这样,您可以预先计算一个随机纹理,或者使用与rand()中相同的一致伪随机函数,只是不使用时间。您清楚地知道这一点,所以我想我仍然不明白目标。为什么要对每个像素从纹理中随机选择单元格呢?

我相信您的着色器崩溃的原因是您的main()函数超出了其时间限制-对于单个像素还是整个像素集。每个像素调用rand() 40,000次(在200 * 200嵌套循环中)肯定可以解释这一点!
如果您有200 x 200像素,并且每个像素调用sin()40k次,则每帧160,000,000次调用。可怜的GPU!

我希望,如果我们对目标有更好的了解,我们将能够推荐一种更有效的方法来获得所需的效果。

更新。

(删除该部分,因为它是错误的。即使源矩阵中​​的许多单元可能各自对结果的贡献少于视觉上可检测的颜色量,但许多单元的总数仍可以对视觉上可检测的颜色量进行贡献。)

基于更新的问题的新更新。

好的,(这里想“大声”,这样您就可以检查我是否正确理解了……)由于您只需要一次随机的NxM值,因此实际上并不需要将它们存储在矩阵中。这些值可以简单地按需计算然后丢弃。这就是您上面的示例代码实际上未生成矩阵的原因。

这意味着我们无法避免每帧生成(NxM)^ 2个随机值,即每像素NxM个随机值,并且有NxM个像素。因此对于N = M = 200,每帧有1.6亿个随机值。

但是,我们仍然可以优化一些东西。


首先,由于您的随机值只需要一个位(您只需要一个布尔值答案即可决定是否将源纹理中的每个单元都包括到混合中),因此您可以使用便宜的伪随机数生成器。您使用的那个每次呼叫输出的随机数据要多于一位。例如,您可以调用与现在使用的PRNG函数相同的函数,但是要存储该值并从中提取32个随机位。或至少几个,具体取决于有多少随机性。另外,如果您具有扩展名GL_EXT_gpu_shader4(用于按位运算符),则可以使用something like this而不是使用sin()函数:




int LFSR_Rand_Gen(in int n)
{
// <<, ^ and & require GL_EXT_gpu_shader4.
n = (n << 13) ^ n;
return (n * (n*n*15731+789221) + 1376312589) & 0x7fffffff;
}



其次,当前您正在对每个包含的单元( /2.0)执行一次除法运算,这可能相对昂贵,除非编译器和GPU能够将其优化为位移(对于浮点运算有可能吗?)。如上所述,这也不会给出输入值的算术平均值。它将在后面的值上分配更多的权重,而在前面的值上分配很少的权重。解决方案是,对包含的值进行计数,并在循环完成后除以该计数一次。


我不知道这些优化是否足以使您的GPU驱动程序每帧驱动200x200 * 200x200像素。它们绝对应该使您能够大幅提高分辨率。

这些就是我想到的想法。不过,我远不是GPU专家。如果有更多资格的人可以提出建议,那就太好了。

附言在您的评论中,您开玩笑(?)提到了预先计算N * M NxM随机矩阵的选项。也许这不是一个坏主意?? 40,000x40,000是一个很大的纹理(至少40MB),但是,如果每个单元存储32位随机数据​​,则将减少到1250 x 40,000个单元。糟糕的原始GLSL不能帮助您使用按位运算符来提取数据,但是即使您没有GL_EXT_gpu_shader4扩展名,您仍然可以伪造它。 (也许您还需要特殊扩展名才能用于非正方形纹理?)

关于opengl - OpenGL Pixel Shader:如何在每个像素上生成0和1的随机矩阵?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6269319/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com