我是着色器的新手,我昨天开始和他们中的一些玩弄.它们在我的Windows PC上正常编译,但是当它们在Mac上运行时,两者都有错误:
错误:0:14:'=':无法从'const int'转换为'float的4分量向量'
在Android上只有第二个着色器给我一个错误.它有一个错误,提到没有匹配的功能点重载.
它们使用相同的顶点着色器:
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec4 vColor;
varying vec2 vTexCoord;
void main() {
vColor = a_color;
vTexCoord = a_texCoord0;
gl_Position = u_projTrans * a_position;
}
Run Code Online (Sandbox Code Playgroud)
一个片段着色器(Mac上出错):
#ifdef GL_ES
#define LOWP lowp
precision mediump float;
#else
#define LOWP
#endif
varying LOWP vec4 vColor;
varying vec2 vTexCoord;
uniform sampler2D u_texture;
void main() {
vec4 texColor = texture2D(u_texture, vTexCoord);
texColor.rgb = 1.0 - texColor.rgb;
gl_FragColor = texColor * vColor; …Run Code Online (Sandbox Code Playgroud) 我非常希望提出一个简洁的问题,允许一个明确的答案,但我担心有太多的小问题,我不完全理解我需要清理的FBO初始化.我正在编写一个针对OpenGL 4.3和OpenGL ES 3.0的延迟着色器,前者的行为完全符合我的预期,但后者给我的问题我无法确定其来源.
首先,我将描述我对GL 4.2和ES 3.0建立MRT FBO的理解/混淆,并希望有人能够纠正任何误解.
OpenGL ES 3.0规范说它支持"四个或更多渲染目标",但没有提及(我能找到)这些渲染目标的规范.对这些渲染目标的大小有什么安全假设?我可以简单地假设它可以具有RGBA32F(四个32位浮点通道)的内部格式吗?在我看来,这是着色器写入RT的关键假设/知识.常见程序:尝试创建具有特定规格的FBO,然后测试FBO完整性?如果失败:减少要求并使用替代着色器来补偿减小的位深度?
精密预选赛是说"用OpenGL ES援助代码的可移植性,与常规的OpenGL没有影响",但我觉得很难理解究竟这些是什么highp,mediump,lowp,用于,以及他们如何与的位深度一起玩渲染目标.首先,我认为的渲染目标位深度确定,并在FBO配置,而且精度预选赛自动匹配这一点,这让我觉得high,medium和low具有某种关系的32,16,8深度位.我已经看过了OpenGL ES 3.0 specs,对此并不是很清楚.
使用glTexStorage2D(with target=GL_TEXTURE_2D,levels=1)配置FBO的纹理附件,我认为这里使用的更正确glTexImage2D,因为只有internalformat应该重要.
然后COLOR_ATTACHMENT使用将附加的(3.)配置纹理附加到FBO glFramebufferTexture2D.
packHalf2x16/ unpackHalf2x16):假设我使用两个颜色附件设置FBO,第一个(RT1)使用内部格式,GL_RGBA32UI第二个(RT2)使用GL_RGBA32F.对象以两遍传递.第一个是FBO RT,然后是两个由默认帧缓冲区处理的全屏四边形.
为了简化,我将只关注在两个阶段之间传递RGB颜色数据.我试图以三种不同的方式这样做:
[适用于GL&ES]使用RT2,将颜色数据定期存储为浮动,将其作为浮动纹理读取并将其输出到默认帧缓冲区.
[适用于GL&ES]使用 …
以下着色器方法:
float[1] GetArray()
{
float array[1];
array[0] = 1.0;
return array;
}
Run Code Online (Sandbox Code Playgroud)
给我:错误:0:1:'GetArray':语法错误:数组大小必须出现在变量名之后
我已经成功地在GLSL(OpenGL ES)上实现了几个分形,但我似乎无处可去Mandelbrot集的变化,其中指数是任意正数.
我在复杂的极坐标中进行取幂,但算法在某处是错误的,因为指数= 2比经典的Mandelbrot集出现的其他东西.
目前的代码如下:
precision mediump float;
uniform sampler2D palette;
uniform float centerX;
uniform float centerY;
uniform float scale;
uniform float iterations;
uniform vec2 resolution;
uniform float exponent;
#define maxiter 65535
vec2 cplx_polar(vec2 z) {
return vec2(length(z), atan(z.y,z.x));
}
vec2 cplx_polar_add(vec2 z1, vec2 z2) {
//https://math.stackexchange.com/a/1365938
return vec2(sqrt(z1.x*z1.x + z2.x*z2.x + 2.*z1.x*z2.x*cos(z2.y-z1.y)),
z1.y+atan(z2.x*sin(z2.y-z1.y),(z1.x+z2.x*cos(z2.y-z1.y))));
}
vec2 exponentiate(vec2 z) {
return pow(z.x, exponent)* vec2(cos(z.y), sin(z.y));
}
void main() {
vec2 center = vec2(centerX, centerY);
vec2 coord = vec2(gl_FragCoord.x, gl_FragCoord.y) / resolution; …Run Code Online (Sandbox Code Playgroud) 这里是着色器的新手,有点疑惑.
我想指定在渲染精灵数组时使用的纹理.所以我在它们的顶点数据中放置一个纹理索引,并将它作为一个平面值从我的顶点着色器传递到我的片段着色器,但不能用它来按预期索引一个采样器数组,因为编译器认为它是"非常数" ".相反,我不得不求助于下面令人作呕的代码.谁能解释一下这里发生了什么?
const int numTextures = 2;
uniform sampler2D textures[numTextures];
in vec2 uv;
flat in int tex;
out vec4 colour;
void main(void)
{
// this caused the compiler error
/// "sampler arrays indexed with non-constant expressions"
// colour = texture( textures[ tex ], uv );
// hence this (ugh) ...
switch ( tex )
{
case 0:
colour = texture( textures[0], uv );
break;
case 1:
colour = texture( textures[1], uv );
break;
default:
colour = vec4( 0.3f, 0.3f, …Run Code Online (Sandbox Code Playgroud) 我试图通过将带有柏林噪声的置换贴图应用于球体来创建小行星。除了球体的两极扭曲之外,一切都按预期工作。看起来好像极点上的顶点是断开的。
前视图:看起来符合预期
俯视图:看起来很丑;-)

起初,我认为这与我的置换贴图以及我将其应用于球面这一事实有关,但如果我将其应用于立方体,则面之间也会存在间隙。
我不确定,我能做些什么来弥补这些差距。在后面的步骤中,置换贴图一般应该通过渲染到纹理并使用随机种子生成噪声,因此我不能使用 Blender 或 Photoshop 等外部程序来修改置换贴图。我在着色器中做错了什么,还是这是“正常”行为?我能做些什么来避免这种情况吗?我读过立方体贴图。这可能是一个解决方案吗?如果是这样,是否有适用于 Three.js r57 或更高版本的工作示例?
这是我的着色器代码:
vertexShader: [
'uniform sampler2D displacementMap;',
'varying vec3 vColor;',
'void main() {',
'vec4 newVertexPos;',
'vec4 dv;',
'float df;',
'dv = texture2D( displacementMap, uv.xy );',
'df = 0.30*dv.x + 0.59*dv.y + 0.11*dv.z;',
'//newVertexPos = vec4(normal * df * 1.0, 0.0) + vec4( position, 1.0 );',
'newVertexPos = vec4( normalize( position ) * df * 1.0 ) + vec4( position, 1.0 );',
'vColor = vec3( dv.x, dv.y, dv.z );',
'gl_Position …Run Code Online (Sandbox Code Playgroud) 这个问题与这里的问题非常相关(如何将vec4 rgba值转换为浮点数?).
已经有一些与此问题相关的文章或问题,但我想知道大多数文章都没有确定哪种类型的浮动值.只要我能想到,下面有一些浮动值包装/拆包公式.
然而,实际上这只是两个案例.其他包装/拆包可以通过这两种方法处理.
我想将已签名的浮动值打包并解压缩到vec3或vec2中.
对于我的情况,浮动值不能确保标准化,所以我不能使用简单的位移方式.
在OpenGL程序中,通常在顶点着色器中声明类似这样的内容
varying bool aBooleanVariable;
Run Code Online (Sandbox Code Playgroud)
然后在片段着色器中读取该值。您如何在SCNShadable入口点的框架内执行此操作?例如从SCNShaderModifierEntryPointGeometry到SCNShaderModifierEntryPointFragment。
接收到该参数似乎是通过使用pragma参数定义的,我提供我的测试SCNShaderModifierEntryPointFragment进行说明。
#pragma arguments
bool clipFragment
#pragma body
if (clipFragment) {
discard_fragment();
}
Run Code Online (Sandbox Code Playgroud)
但是,参数pragma不适用于在SCNShaderModifierEntryPointGeometry入口点输出值 。
我发现有一篇文章建议可以使用GLSL语法来完成,但是我试图找到Metal的方式,但我什至无法重现结果。
我正在编写一个 Qt OpenGL 应用程序,刚刚从 GLSL 开始,并尝试编译一个我在网络上的示例中找到的“简单”片段着色器:
#version 320 es
out vec4 fColor;
void main()
{
fColor = vec4 (0.0, 0.0, 1.0, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
但是当尝试从源添加此着色器时,我从 Qt 收到此错误消息addShaderFromSourceFile():
QOpenGLShader::compile(Fragment):
0:3(12): 警告:GL_ARB_fragment_coord_conventions片段着色器中不支持扩展
0:1(1): 错误: 在此范围内没有为类型指定精度vec4
声明 type 精度的正确语法是什么vec4?
我似乎找不到如何做到这一点的示例vec4,并尝试这样的事情:
precision mediump vec4;
Run Code Online (Sandbox Code Playgroud)
...导致语法错误。
请注意,我希望着色器在嵌入式系统上运行,因此#version 320 es开头有“”行。
我正在尝试制作一个使用 NDK 和 JNI 在 Android Studio 中绘制图像的应用程序,以使用 OpenGL ES 调用 C++ 代码。我已经阅读了如何在 OpenGL 中执行此操作的教程:https : //learnopengl.com/#!Getting-started/Textures,它使用 GLSL 330 核心。但是,Android 模拟器不支持 OpenGL ES 3.0(此链接中的注意事项:https : //developer.android.com/ndk/guides/stable_apis.html)。
因此,我必须使用 GLSL ES #version 100 ,它不支持下面着色器中的“布局”、“输入”和“输出”。我应该如何编辑它们以便它们可以在 #version 100 中运行,如果我编辑它们,源代码是否有任何变化?感谢您的关注和帮助。
更新:搜索后,我发现我可以使用 glGetAttributeLocation 来获取顶点着色器中变量的位置,而不是使用 layout(location=0)。但是,GLSL ES #version 100 中没有 VAO,所以我仍然无法弄清楚它在没有 VAO 的情况下是如何工作的。
我的顶点着色器:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec2 texCoord;
out vec3 ourColor;
out vec2 …Run Code Online (Sandbox Code Playgroud)