OpenGL着色语言(GLSL)是OpenGL中着色器的标准编程语言。该语言有许多版本,每个版本对应一个OpenGL版本。 OpenGL ES 2.0及更高版本具有单独的GLSL版本。
假设我们在 CG/HLSL 中几乎没有函数重写,并且这些函数需要一些大且几乎相同的文档,那么如何在不重复相同文本的情况下为每个重写获取它? /** * 长
所以,在我的顶点着色器中我正在做这样的事情: 无效主(){ gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy, 0, 1); } 但现在我在片段着色器中,我想访问...
在我的光线行进着色器中,当物体经过原点光源附近时,为什么阴影会反转?
我正在使用有符号距离函数 (SDF) 在 OpenGL 着色器中实现光线行进阴影。光源放置在原点 (0,0,0),我使用光线行进来计算 sh...
我正在尝试制作电影《黑客帝国》中字母掉落的效果。我在shadertoy.com网站上找到了最好的参考,但是当我尝试至少在...
是否有办法优化下一个算法使其更快,即使只是小幅提高速度? const mat3 因子 = mat3(1.0, 1.0, 1.0, 2.112, 1.4, 0.0, 0.0, 2.18, -2.21); vec3 计算...
我正在设计一个使用内置变量 gl_VertexID 的着色器程序: gl_VertexID — 包含当前顶点的索引 该变量被定义为有符号...
为什么使用常量值时写入 gl_FragDepth 很快,但使用变化值时写入 gl_FragDepth 却很慢?
我有以下情况:我想将深度值从具有 1 个样本的帧缓冲区传输到具有 8 个样本的不同帧缓冲区。我认为,实现这一目标的唯一方法是
我想为场景添加雾。但我不想根据片段与相机的距离向片段颜色添加雾,而是想采用更现实的方法。我想计算距离,...
我希望通过管道传输 2 个几何着色器。第一个获取一个点并释放多个点。第二个获取这些点之一并向片段着色器释放一个矩形。 几何着色器 1:
在 GLSL 着色器中,我想创建一个看起来有点像这样的函数: void MyFunction(out float results[9]) { 浮点值0 = 3.1546; 浮点值1 = 42; // 无论什么值 /* ...
如何在GLSL(OpenGL ES 2.0)中定义常量数组?
我只想存储每个片段计算所需的权重数组。 这: 浮点权重[5] = 浮点[5](3.4, 4.2, 5.0, 5.2, 1.1); 只是抛出这个: 错误:0:30:']':语法错误...
GLSL 有许多预定义的全局变量,例如 gl_LightSource。它们是全局的,因为任何着色器都可以访问它们。 如何在 GLSL 中定义自定义全局变量?
在做了一些没有额外库+GLSL着色器的“常规”WebGL之后,我开始使用ThreeJS的WebGL渲染器。我现在正在尝试在我的 ThreeJS 程序中编写自定义着色器,我注意到......
C++ 风格的引用可以使代码更加简洁,但 GLSL 没有。 例如。这段代码: 对于 (int i=0; i C++ 风格的引用可以使代码更加简洁,但 GLSL 没有。 例如。此代码: for (int i=0; i<numCascades; ++i) { if (eyeDistance < shadow.cascade[i].end) { vec3 sc = eyePos*shadow.cascade[i].transform; // ...many more references to "shadow.cascade[i]" here } } 如果我可以输入以下内容会更整洁: for (int i=0; i<numCascades; ++i) { const ShadowCascade& cascade = shadow.cascade[i]; if (eyeDistance < cascade.end) { vec3 sc = eyePos*cascade.transform; // ...many more references to "cascade" here } } 我可以输入这个(与上面相同,但没有“&”): for (int i=0; i<numCascades; ++i) { const ShadowCascade cascade = shadow.cascade[i]; if (eyeDistance < cascade.end) { vec3 sc = eyePos*cascade.transform; // ...many more references to "cascade" here } } 这会导致性能损失吗?级联结构是否会被复制到局部变量中(就像在 C++ 中一样)? 人们如何在 GLSL 中整理此类代码? (使用#define?(呃!)) 是的,你是对的,你不能像在 C++ 中那样在 GLSL 中创建引用或指针。 在最后一个示例中,您复制了整个结构(const ShadowCascade cascade = shadow.cascade[i];)。但你呢?在编译器理论中,有一种称为复制传播的优化技术。这意味着,当您访问 cascade.transform 时,您将获得与访问 shadow.cascade[i].transform 相同的值。为什么?因为您复制了结构,并且从那时起就没有更改任何一个结构。如果它一直选择shadow.cascade[i].transform,则变量cascade永远不会被使用,因此它可以消除初始化和复制。因此,理论上编译器可以计算出,如果它始终使用原始数组,则不必复制结构。 但是,当您使用例如 glCompileShader 时,您将在驱动程序中使用编译器。 Nvidia、AMD 和 Intel 有不同的编译器,可能不同的驱动程序版本包含不同的编译器,也可能它们在不同的 GPU 上的工作方式不同。因此很难判断编译器是否使用了这种优化。我的建议是将 GLSL 着色器编译为 SPIR-V。它类似于 C# 的 IL,或者 Java 的 Java 字节码。它是一种架构中立的中间语言。这样,在编译着色器后,您可以检查结果,并检查副本是否存在。 SPIR-V 还有很多其他优点,例如减少运行时编译时间(因为从 SPIR-V 编译为机器代码比从 GLSL 编译更快)。 但是,SPIR-V 并非随处可用。它始终在 Vulkan、OpenGL 4.6 和 OpenGL ES 3.2 中可用。它通常在较旧的 OpenGL 和带有扩展的 OpenGL ES 版本中可用,但它在网络上永远不可用。在任何地方都有效的解决方案是宏(正如您所提到的)。在我学习编程的大学里,教授们说宏是邪恶的。是的,错误地使用宏和其他预处理器指令并不难。然而,后来,当我担任图形程序员时,我看到人们经常使用这些东西,因为有时没有真正的替代品,或者这是性能最高的。因此,虽然我理解您对使用宏犹豫不决,并且您绝对不应该将它们用于所有事情,但我认为编写这样的内容不是问题:#define CASCADE(i) shadow.cascade[i]。它将适用于所有 GLSL 版本、所有供应商、驱动程序,您不必处理 SPIR-V 等。 总之,我建议您使用 SPIR-V、宏或两者。
我有一个像这样的统一缓冲区(GLSL/GPU): 布局(std140)统一UConstantBufferPS1 { 浮动m_LuminanceHistory[8]; }; 我像这样上传数据(C++/CPU): SHistoryBuffer* pHistogramHisto...
我正在开发 GLSL 着色器,并在使用 while 循环遍历像素时遇到问题。相同的代码在桌面设备上运行良好,但在移动设备上产生不同的结果(两者
分别调用多少次vertex-shader、geometry-shader和fragment-shader来绘制一帧?
为了绘制一帧,或者说给定一个顶点数组,当这个数组正在传输并通过着色程序的各个阶段时,各个顶点之间是否存在严格的对应关系...
我控制片段着色器调用的数量,其中 VkPipelineInputAssemblyStateCreateInfo.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST 通过将 gl_PointSize 设置为 3 来调用 9 次。理想情况下
从GL_TEXTURE_EXTERNAL_OES纹理线性rgb读取的值是吗?
我使用 MediaCodec 解码来自服务器的 h264 流并渲染帧。服务器编码的帧为 sRGB。解码器将结果存储到oes纹理中。我知道 SamplerExternalOES 会
从自定义 GLSL 统一阴影投射的阴影与“surf”方法输出不匹配
问题: 我编写了一个自定义着色器,用于从精灵表制作动画精灵(没有深入探讨为什么我要这样做,而不是在这个项目中使用 Unity 的动画播放器”)。 效果很好,...