是否可以使用着色器计算某些值,然后将它们返回以供进一步使用?
例如,我将网格向下发送到GPU,有一些关于如何修改它的参数(改变顶点的位置),并收回结果网格?我认为这是不可能的,因为我没有看到任何从着色器到CPU的通信变量.我正在使用GLSL,所以只有统一,属性和变化.我应该使用属性还是制服,渲染后它们是否仍然有效?我可以更改这些变量的值并在CPU中读回吗?有一些方法可以在GPU中映射数据但是这些方法会被更改和有效吗?
这是我正在考虑的方式,虽然可能有其他方式,这对我来说是不可知的.如果有人能解释我的话,我会很高兴,因为我刚读了一些关于GLSL的书,现在我想编写更复杂的着色器,我不想放弃目前不可能的方法.
谢谢
第一; 如何编译OpenGL着色器?它们是在CPU或GPU上编译的,还是因实现而有所不同?不同的供应商有不同的二进制输出; 如果是这样,是否有可能在另一个GPU上交叉编译一个GPU类型的二进制文件?我正在开发一款我计划在英特尔GFX芯片,ATI卡和NVidia卡上运行的游戏.我宁愿只发送着色器的二进制部分,而不必在客户端计算机上编译源代码.这可能吗?着色器编译过程如何工作?
我有一个顶点着色器,它接受以下属性:
a_posCoord:顶点位置a_texCoord:纹理坐标(传递给片段着色器)a_alpha:透明度因子(传递给片段着色器)我正在渲染的对象都是"广告牌"(一对直角三角形来制作一个矩形).
我正在使用单个调用来glDrawArrays渲染许多广告牌,每个广告牌都可能具有唯一的alpha值.单个广告牌有6个顶点.这里有一些伪代码来说明我如何为单个广告牌组织顶点属性缓冲区:
vertexAttributes = [
px1,py1,pz1, // vertex 1: a_posCoord
tx1,ty1, // vertex 1: a_texCoord
alpha, // vertex 1: a_alpha
px2,py2,pz2, // vertex 2: a_posCoord
tx2,ty2, // vertex 2: a_texCoord
alpha, // vertex 2: a_alpha
px3,py3,pz3, // vertex 3: a_posCoord
tx3,ty3, // vertex 3: a_texCoord
alpha, // vertex 3: a_alpha
px4,py4,pz4, // vertex 4: a_posCoord
tx4,ty4, // vertex 4: a_texCoord
alpha, // vertex 4: a_alpha
px5,py5,pz5, // vertex 5: …Run Code Online (Sandbox Code Playgroud) 我正在查看使用着色器的OpenGL应用程序的来源.一个特殊的着色器看起来像这样:
uniform float someConstantValue;
void main()
{
// Use someConstantValue
}
Run Code Online (Sandbox Code Playgroud)
统一是从代码设置一次,并且在整个应用程序运行时都不会更改.
在什么情况下我想宣布someConstantValue为a uniform而不是const float?
编辑: 只是为了澄清,常数值是物理常数.
每次我醉酒浏览,所以我看到一个未解答的宽带问题.它让我想知道它实际上是做什么的.
阅读文档是:abs(dFdx(p))+ abs(dFdy(p)).
因此,经典的mip选择不是max(dx,dy).是替代mip选择吗?但我找不到abs(dx)+ abs(dy)会更好的情况.必须有一些siggraph纸或常见的算法,我完全没有使用该功能.它必须非常受欢迎,因为它使它成为GLSL.我唯一能想到的是我失踪的一些2d后置滤镜.
但是什么?我相信这里有人知道,一旦你看到它,这是显而易见的.那么:什么算法使用abs(dx)+ abs(dy)?
我一直在研究这个问题,而且我似乎无法理解它已经足够解决它所以我认为我不妨把它扔出去并且聪明的一堆可能有一些想法.:P
基本上我一直在研究一个iPhone项目,我有幸使用所有最新的框架和目标5.1.所以我一直在使用GLKit和GLKBaseEffect,这对我来说一直很好.我开始使用GLKBaseEffect而不是编写自己的着色器的原因是我不太了解glsl.然而,要求变得更加精确,基本效果似乎不再削减它.
因为我已经使用基本效果进行了所有变换,所以如果我可以保持基本效果不变,但是如果有意义的话,可以在顶部添加glsl-type着色器.
我的旧方法看起来像这样(这是一个循环渲染所有对象,其中一个对象包含变换,网格和其他一些不太重要的东西,如纹理,材料等)
ObjectBase *obj = [ResourceManager.shared getObjectNamed:name inScene:sceneName];
GLKMatrix4 modelview = effect.transform.modelviewMatrix;
effect.transform.modelviewMatrix = GLKMatrix4Multiply(effect.transform.modelviewMatrix, obj.transform);
[effect prepareToDraw];
[obj render];
effect.transform.modelviewMatrix = modelView;
Run Code Online (Sandbox Code Playgroud)
在这里,我们获取一个对象来渲染和变换(即平移,旋转和缩放)对象,然后我们渲染它,渲染本身获取对象的网格,绑定缓冲区并渲染它.
到现在为止还挺好.
然而,我想要做的是,在[obj render];调用期间,我希望对象也可以执行类似glUseProgram(someProgram);添加更专业的着色器代码的操作.
我想有人可能会争辩说我正在尝试为我的顶点着色器使用基本效果,并希望为我的片段着色器使用"普通"着色器.至少那是我认为我想做的事情.
我一直在尝试一些事情.
我试图创建片段着色器并glUseProgram在其上,但它说我在设置和编译时需要一个顶点和一个片段着色器.我也尝试创建一个空的顶点着色器,但结果并不好,我不知道会发生什么,但我猜它会否决基本效果.
最后,我倾向于接受它可能最好丢掉基本效果并且一直编写我自己的着色器.我觉得窗外有很多工作,所以我想知道我能节省多少钱.
我明白我对着色器的理解是给我带来最大问题的部分,所以请耐心等待.
我正在尝试将属性传递给我的顶点着色器但是由于某种原因它在第三个属性位置上给我一个-1我要求openGl通过glGetAttribLocation()来检索.目前它一直给我一个-1的texCoord属性,如果我切换texAttrib和colAttrib(切换代码中的行)它给我一个-1颜色属性而不是纹理,我不明白为什么?由于-1传递给glVertexAttribPointer,我得到1281 OpenGL错误:GL_INVALID_VALUE.
我的顶点着色器:
#version 150
in vec3 position;
in vec3 color;
in vec2 texcoord;
out vec3 Color;
out vec2 Texcoord;
void main()
{
Color = color;
Texcoord = texcoord;
gl_Position = vec4(position.x, position.y, position.z, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
OpenGL代码:
basicShader.Use();
// Buffers and shaders
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
// Make it active vbo
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// Build basic triangle
float vertices[] = {
// position // color // textures
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, …Run Code Online (Sandbox Code Playgroud) 我正在尝试在GLSL中编写一个函数,该函数返回到矩形的符号距离.矩形是轴对齐的.我觉得有点卡住; 我无法绕过我需要做的事情才能让它发挥作用.
我想出的最好的是:
float sdAxisAlignedRect(vec2 uv, vec2 tl, vec2 br)
{
// signed distances for x and y. these work fine.
float dx = max(tl.x - uv.x, uv.x - br.x);
float dy = max(tl.y - uv.y, uv.y - br.y);
dx = max(0.,dx);
dy = max(0.,dy);
return sqrt(dx*dx+dy*dy);
}
Run Code Online (Sandbox Code Playgroud)
这会生成一个看起来像这样的矩形:

线条显示距矩形的距离.它工作正常,但只适用于矩形外的距离.在矩形内部,距离是静态的0..
如何使用统一的公式在矩形内获得精确的距离?
在Unity中,在编写着色器时,
是否有可能着色器本身"知道"屏幕分辨率是什么,实际上着色器控制单个物理像素?
我只考虑为"2D"对象编写着色器的情况(例如UI使用,或者在使用正射相机的任何事件中).
(当然,通常在屏幕上显示一个物理像素完美的PNG,你只需要一个400像素的PNG,你就可以安排缩放,以便着色器恰好可以绘制到400个物理像素.我想知道什么about是一个只绘制的着色器,例如物理像素完美的黑线 - 它必须"知道"物理像素的确切位置.)
为此获得赏金......
我有一个顶点着色器,其中包含一个包含一个浮点数的push-constant块:
layout(push_constant) uniform pushConstants {
float test1;
} u_pushConstants;
Run Code Online (Sandbox Code Playgroud)
一个片段着色器与另一个具有不同浮点值的push-constant块:
layout(push_constant) uniform pushConstants {
float test2;
} u_pushConstants;
Run Code Online (Sandbox Code Playgroud)
test1和test2应该是不同的.
管道布局的推 - 常量范围定义如下:
std::array<vk::PushConstantRange,2> ranges = {
vk::PushConstantRange{
vk::ShaderStageFlagBits::eVertex,
0,
sizeof(float)
},
vk::PushConstantRange{
vk::ShaderStageFlagBits::eFragment,
sizeof(float), // Push-constant range offset (Start after vertex push constants)
sizeof(float)
}
};
Run Code Online (Sandbox Code Playgroud)
然后在渲染过程中推送实际常量,如下所示:
std::array<float,1> constants = {123.f};
commandBufferDraw.pushConstants(
pipelineLayout,
vk::ShaderStageFlagBits::eVertex,
0,
sizeof(float),
constants.data()
);
std::array<float,1> constants = {456.f};
commandBufferDraw.pushConstants(
pipelineLayout,
vk::ShaderStageFlagBits::eFragment,
sizeof(float), // Offset in bytes
sizeof(float),
constants.data()
);
Run Code Online (Sandbox Code Playgroud)
但是,在检查着色器内部的值时,两者都具有值123.似乎完全忽略了偏移量.我不正确地使用它们吗?