我正在尝试为网站上的图像创建 RGB 偏移效果。我有基本功能,但问题是通道与纹理的 uv 发生偏移。因此,如果图像尺寸不同,则每个图像的偏移量在视觉上并不相同。
这是我的片段着色器。
uniform sampler2D texture;
varying vec2 vUv; // vertex uv
void main() {
vec2 uv = vUv;
float red = texture2D(texture, vec2(uv.x, uv.y - .1)).r;
float green = texture2D(texture, uv).g;
float blue = texture2D(texture, vec2(uv.x, uv.y + .1)).b;
float alpha = texture2D(texture, uv).a;
gl_FragColor = vec4(vec3(red, green, blue), alpha);
}
Run Code Online (Sandbox Code Playgroud)
以及它呈现在页面上的样子。

我将如何在不必传递统一值的情况下标准化 uv 偏移?
我正在学习 OpenGL,当我运行该程序时,有时可以工作(红色三角形),有时则不能(白色三角形且没有三角形)。我正在使用 makefiles 使用 msvc(命令行中的 cl.exe)来编译它。这是该程序的简化版本,请告诉我您是否也遇到同样的奇怪行为。
预期结果(运行的 10%)
越野车结果(90% 的运行)
主程序
#define SDL_MAIN_HANDLED
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#include <GL/glew.h>
#include <SDL2/SDL.h>
//Loading the file, I suspect that the shaders sometimes are not loaded properly but I'm not sure.
std::string loadFile(const std::string filepath)
{
std::ifstream file(filepath.c_str());
if(!file.is_open())
{
std::cerr << "Error loading Shader" << std::endl;
std::exit(1);
}
std::string output = std::string((std::istreambuf_iterator<char>(file)),std::istreambuf_iterator<char>());
return output;
}
//Just error checking (Probably I should include the shader …Run Code Online (Sandbox Code Playgroud) 我试图在片段着色器中混合两种纹理的颜色.但不幸的是,我在实际工作之前就被卡住了.
这是着色器设置:
const char* vertex = "void main(){ \n\
gl_Position = ftransform(); \n\
gl_TexCoord[0] = gl_MultiTexCoord0;\n\
gl_TexCoord[1] = gl_MultiTexCoord1;\n\
}\n";
const char* fragment = "\
uniform sampler2D userT;\
uniform sampler2D videoTex; \
\n\
void main(){\n\
vec4 texel = texture2D(userT, gl_TexCoord[0].st);\n\
gl_FragColor = texel;\n\
}\n";
m_vertexShader = glCreateShader(GL_VERTEX_SHADER);
m_fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource( m_vertexShader, 1, &vertex, NULL );
glShaderSource( m_fragmentShader, 1, &fragment, NULL );
glCompileShader( m_vertexShader );
glCompileShader( m_fragmentShader );
m_silhouetteShaderProg = glCreateProgram();
glAttachShader( m_silhouetteShaderProg, m_vertexShader );
glAttachShader( m_silhouetteShaderProg, m_fragmentShader );
glLinkProgram( …Run Code Online (Sandbox Code Playgroud) 片段着色器使用两个原子计数器.它可能会或可能不会增加第一个,可能会或可能不会增加第二个(但从不两者).但是,在修改计数器之前,总会读取它们的当前值,如果计数器稍后被修改,那些先前读取的值将用于某些自定义逻辑.所有这些都发生在(很可能是不可滚动的)循环中.
设想一个大致如下的流程:
问题:着色器查询当前计数器值 - 它是否始终获得"最新"值?我是否在这里失去了碎片着色器的大规模并行性(仅就当代和未来的GPU和驱动程序而言)?
至于分支(如果x) -我比较另一纹素(readonly restrict uniform)uimage1D的(uniform)uint.因此,一个操作数肯定是一个统一的标量,但另一个是一个imageLoad().x虽然图像是统一的 - 这种分支仍然是"完全并行化"的吗?你可以看到两个分支都是两个,几乎相同的指令.假设一个"完美优化"的GLSL编译器,这种分支是否会引入停顿?
我有一个与OpenGL相关的问题.每当我尝试使用顶点缓冲区中的四个顶点绘制一个简单的多边形时......没有任何反应.但是,它会以GL_TRIANGLES或GL_TRIANGLE_STRIP模式绘制形状,尽管是扭曲的.难道我做错了什么?
相关代码:
顶点阵列:http://i.imgur.com/nEcbw.png
GL_POLYGON:http://i.imgur.com/idfFT.png
GL_TRIANGLES:http://imgur.com/84ey3,idfFT,nEcbw#0
GL_TRIANGLE_STRIP:http://i.imgur.com/JU3Zl.png
如果我的vec4为NULL,我正在尝试检查着色器(GLSL)内部.我需要这个有几个原因,主要是为了让特定的显卡兼容,因为它们中的一些在gl_FragColor中传递了前一种颜色,而有些则没有(提供需要覆盖的空vec4).好吧,在一台相当新的Mac上,有人遇到了这个错误:
java.lang.RuntimeException: Error creating shader: ERROR: 0:107: '==' does not operate on 'vec4' and 'int'
ERROR: 0:208: '!=' does not operate on 'mat3' and 'int'
Run Code Online (Sandbox Code Playgroud)
这是我在片段着色器中的代码:
void main()
{
if(gl_FragColor == 0) gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); //Line 107
vec4 newColor = vec4(0.0, 0.0, 0.0, 0.0);
[...]
if(inverseViewMatrix != 0) //Line 208
{
[do stuff with it; though I can replace this NULL check with a boolean]
}
[...]
gl_FragColor.rgb = mix(gl_FragColor.rgb, newColor.rgb, newColor.a);
gl_FragColor.a += newColor.a;
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我在开始时对gl_FragColor进行了0/NULL检查,因为有些图形卡会在那里传递有价值的信息,但有些则没有.现在,在那个特殊的mac上,它没有用.我做了一些研究,但找不到有关如何在GLSL中进行正确的NULL检查的任何信息.有没有,或者我真的需要在这里制作单独的着色器吗?
我正在使用GPUImage框架开发iOS项目.我不能让我的着色器得到遵守.
我的片段着色器中有一个函数:
const vec2 boundMin = vec2(0.0, 0.0);
const vec2 boundMax = vec2(1.0, 1.0);
bool inBounds (vec2 p) {
return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));
}
Run Code Online (Sandbox Code Playgroud)
着色器编译日志:
ERROR: 0:1: '_Bool' : syntax error syntax error
Run Code Online (Sandbox Code Playgroud)
当我替换所有调用函数
inBounds(vec2 p)
同
all(lessThan(boundMin, p)) && all(lessThan(p, boundMax))
它很棒!
问题:
OpenGL ES 2.0 Fragment Shader支持bool功能吗?如果是的话,我哪里出错了?如果不是,为什么会出现类似的功能all(),lessThan()等等.
环境:iPad mini,iOS 7,OpenGL ES 2.0,Xcode 5.0.2
我希望在2D OpenGL应用程序上实现着色器.我的计划是将场景渲染到帧缓冲对象,然后使用着色器将该帧缓冲对象渲染到屏幕.
这是场景,我已经绘制到帧缓冲对象,然后从那里到屏幕.使用箭头键使月亮移动(我为此感到自豪!)

但是,当我尝试使用着色器程序将framebuffer对象渲染到屏幕时,我得到了这个:

这是非常可悲的.这个片段着色器是我从教程中得到的,我确定问题必须是统一变量.
这是片段着色器:
#version 330
in vec2 texCoord;
out vec4 outputColor;
uniform sampler2D gSampler;
void main()
{
outputColor = texture2D(gSampler, texCoord);
}
Run Code Online (Sandbox Code Playgroud)
以下是我设置统一变量的方法:
gSampler = glGetUniformLocation(mProgramID, "gSampler");
glUniform1i(gSampler, GL_TEXTURE0);
Run Code Online (Sandbox Code Playgroud)
以下是使用我的着色器程序(mProgramID)将Framebuffer(fbo_texture)渲染到屏幕的方法
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0 );
glUseProgram(mProgramID);
glColor3f(1.0, 1.0, 1.0);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, fbo_texture);
glBegin(GL_QUADS);x1= 0.0;x2= 400.0;y1= 0.0;y2 = 400.0;
glTexCoord2f(0.0f, 1.0f); glVertex2f(x1, y1);
glTexCoord2f(0.0f, 0.0f); glVertex2f(x1, y2);
glTexCoord2f(1.0f, 0.0f); glVertex2f(x2, y2);
glTexCoord2f(1.0f, 1.0f); glVertex2f(x2, y1);
glEnd();glDisable(GL_TEXTURE_2D);
SDL_GL_SwapBuffers();
Run Code Online (Sandbox Code Playgroud)
所以我的问题是 - 纹理和采样器之间的联系是什么?如果着色器已经对纹理进行采样,是否需要渲染纹理四边形?如果着色器正在纹理化,为什么不渲染空白四边形呢?
编辑:这是顶点着色器:
void main()
{
gl_TexCoord[0] …Run Code Online (Sandbox Code Playgroud) 我有一个使用OpenGL的OSX应用程序.我正在使用GL_TEXTURE_2D类型的纹理绘制我的大多数东西,只要我坚持使用GL_TEXTURE_2D,一切正常.但我需要有几个GL_TEXTURE_RECTANGLE_ARB类型的纹理.
要创建GL_TEXTURE_RECTANGLE_ARB类型的纹理,请执行以下操作:
// 4x4 RGBA texture data
GLubyte TexData[4*4*4] =
{
0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff,
0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff,
0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff,
0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff,
0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff,
0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
};
GLuint myArbTexture;
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glGenTextures(1, …Run Code Online (Sandbox Code Playgroud) 我有一个发光alpha纹理,其中每个像素有两个字节,第一个字节是发光,第二个字节是alpha.
是否可以将其上传到GPU中(在片段着色器中)alpha组件将始终引用alpha,无论使用何种纹理,而不会浪费绿色和蓝色通道的纹理内存?
// fragment shader
vec4 px = texture(tex, uv);
px.r; // is luminescence
px.a; // is alpha (note that .a is used, not .g which would be green for 32bit RGBA textures)
Run Code Online (Sandbox Code Playgroud)
我想避免使用GL_RG作为内部格式的原因是因为这需要我在着色器中使用32位RGBA纹理的单独代码路径,并且我想避免为不同的纹理类型设置制服/条件.
(如果普通的GPU能够消除G和B通道的内存开销,如果它们是RGBA内部格式的空/冗余,那也没关系)