我正在尝试深入研究着色器语言,为我的 iOS 9+ / Sprite-Kit 应用程序编写一些简单的片段着色器。但我已经坚持尝试调用一个简单的函数。这是我的着色器代码,我使用 Sprite-Kit 中的 SKShader 对象将其绑定到 Swift 2.2 应用程序中:
void main(void) {
gl_FragColor = getColor();
}
float getColor() {
return vec4(1.0, 1.0, 1.0, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
当尝试编译时,我收到以下错误:
2016-06-22 12:53:35.606 ShaderTestGLSL[8425:2478215] Jet: Error Domain=MTLLibraryErrorDomain Code=3 "Compilation failed:
program_source:8:12: error: use of undeclared identifier 'getColor'
return getColor();
^
program_source:12:7: warning: no previous prototype for function 'getColor'
float getColor() {
^
program_source:13:16: error: excess elements in scalar initializer
return vec4(1.0, 1.0, 1.0, 1.0);
^ ~~~~~~~~~~~~~~~~
" UserInfo={NSLocalizedDescription=Compilation failed:
program_source:8:12: error: …Run Code Online (Sandbox Code Playgroud) 作为参考,我正在遵循本教程。现在假设我有一个具有多种类型模型的小应用程序,如果我理解正确的话,我必须将每个模型的 MPV 矩阵从 CPU 发送到 GPU(换句话说,发送到我的顶点着色器),因为每个模型可能有不同的模型矩阵从一个到另一个。
现在看看教程和这篇文章,我明白应该为每个帧和每个模型调用将矩阵发送到我的着色器 ( glUniformMatrix4fv(myMatrixID, 1, GL_FALSE, &myModelMVP[0][0])) ,因为每次它都会覆盖我的 MVP 的先前值(我的最后一个值)模型)。但是,考虑到我的应用程序的性能,我不想通过总线发送无用的数据,如果我理解正确的话,我的模型矩阵对于每个模型都是恒定的。
我正在考虑为每个模型的 MVP 矩阵制定一个制服,但我认为它不可扩展,如果我的视图或投影矩阵发生变化,我还必须更新所有这些......有没有办法避免多次发送我的模型矩阵并且仅在更改时发送我的视图和投影矩阵?
我有一个 2 阶段体积渲染器,我使用 DVR 方法来渲染体积,但深度缓冲区不适合该体积,因为我使用来自盒子的光线投射。
实际上我有一个盒子,我应该根据体积数据计算正确的深度值。
我在顶点着色器中有这个:
out float DEPTH ;
...
DEPTH = gl_Position.z / gl_Position.w;
Run Code Online (Sandbox Code Playgroud)
并在片段中:
gl_FragDepth = (1.0 - 0.0) * 0.5 * DEPTH + (1.0 + 0.0) * 0.5;
Run Code Online (Sandbox Code Playgroud)
它们非常适合盒子,我的主要问题是如何在深度上添加一点来获得正确的深度值?
我也用了 from (distanceToAdd/100 + DEPTH),但是是错误的。
任何想法?
我已经使用自己的迷你管道(使用 mipmap)成功地在几何体上显示纹理,但我决定不使用 mip-map,因为我的软件实际上不需要对细节级别进行任何更改。它是 2d 的并且使用像素艺术。细节不应该改变。我要补充一点,我正在尝试在纹理图集中循环纹理,并且禁用 mip 映射可能会有助于避免问题。
但是,不调用glGenerateMipmap会产生空白屏幕。调用它会产生正确的纹理。
是否还有另一个我必须调用的函数?
以下是我的纹理生成函数(我传递一个指向已创建的纹理 id 的指针。)
GLboolean GL_texture_load(Texture* texture_id, const char* const path, const GLboolean alpha, const GLint param_edge)
{
// load image
SDL_Surface* img = nullptr;
if (!(img = IMG_Load(path))) {
fprintf(stderr, "SDL_image could not be loaded %s, SDL_image Error: %s\n",
path, IMG_GetError());
return GL_FALSE;
}
glBindTexture(GL_TEXTURE_2D, *texture_id);
// image assignment
GLuint format = (alpha) ? GL_RGBA : GL_RGB;
glTexImage2D(GL_TEXTURE_2D, 0, format, img->w, img->h, 0, format, GL_UNSIGNED_BYTE, img->pixels);
glGenerateMipmap(GL_TEXTURE_2D); …Run Code Online (Sandbox Code Playgroud) vec2 uv = vec2(位置.x / 360.0 + 0.5, 位置.y / 180.0 + 0.5);
\n\n什么时候使用uv,什么时候使用位置?它们之间可以转换吗\xef\xbc\x9f
\n返回的值是多少:
\n\ndot(normalize(a), normalize(b))\nRun Code Online (Sandbox Code Playgroud)\n\n假设向量 a 和 b 之间的角度为 45\xc2\xb0。
\n\n自 GLSL 4.20 起const,限定变量不再需要通过常量表达式进行初始化。但是,当我实际尝试定义const由非常量表达式初始化的全局限定变量时,Mesa 会发出错误。这是示例代码:
#version 420
uniform vec2 v;
const float x=v.x;
out vec4 color;
void main()
{
color=vec4(x,v.y,0,1);
}
Run Code Online (Sandbox Code Playgroud)
以下是我测试编译的方法(以避免任何 OpenGL 代码):
#version 420
uniform vec2 v;
const float x=v.x;
out vec4 color;
void main()
{
color=vec4(x,v.y,0,1);
}
Run Code Online (Sandbox Code Playgroud)
如果我将const float x=v.x;行移到函数体中main,编译将成功结束。
OTOH,nvidia 驱动程序(像往常一样)更加宽容,接受原始代码而不发出警告。
那么,GLSL 4.20+ 实际上是否禁止const在全局范围内使用 -限定变量的非常量表达式初始值设定项,或者这个错误是 Mesa 错误吗?
我使用一个缓冲区来传递我的 C++ 结构
struct Node {
Node(int size, glm::ivec3 position);
bool isEmpty();
int getSubIndex(const glm::ivec3& vec);
void divide(std::vector<Node> &nodes);
void setColor(glm::vec4 color);
int getSubNodeIndex(const glm::ivec3& vec);
int getSubNodeIndex(int subIndex);
glm::ivec4 position;
glm::vec4 color;
int halfSize;
int sub;
int leaf;
};
Run Code Online (Sandbox Code Playgroud)
在着色器中看起来像这样
struct Node {
vec4 position;
vec4 color;
int data[3];
};
layout(std430, binding=4) readonly buffer Octree_data {
Node nodes[];
};
Run Code Online (Sandbox Code Playgroud)
在计算过程中,我发现数组的所有元素(除了第一个元素)都有不正确的数据(很可能是移位的),我会犯什么错误?
根据Vulkan 规范,
以下功能已被删除:
- 默认制服(不在统一块内的统一变量)
例如,GLSL 中禁止以下行为:
layout(set = 0, binding = 0) uniform mat4 projectionMatrix;
Run Code Online (Sandbox Code Playgroud)
相反,似乎鼓励程序员创建一个统一的块:
layout(set = 0, binding = 0) uniform Projection {
mat4 matrix;
} projection;
Run Code Online (Sandbox Code Playgroud)
使用单值制服有时对于较小的应用程序很有用。删除该功能的理由是什么?