标签: glsl

如何使用C++软件实际运送GLSL着色器

在OpenGL初始化期间,程序应该执行以下操作:

<Get Shader Source Code>
<Create Shader>
<Attach Source Code To Shader>
<Compile Shader>
Run Code Online (Sandbox Code Playgroud)

获取源代码可能就像将它放在一个字符串中一样简单:(示例摘自SuperBible,第6版)

static const char * vs_source[] =
{
    "#version 420 core                             \n"
    "                                              \n"
    "void main(void)                               \n"
    "{                                             \n"
    "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);   \n"
    "}                                             \n"
};
Run Code Online (Sandbox Code Playgroud)

问题是很难直接在字符串中编辑,调试和维护GLSL着色器.因此,从文件中获取字符串中的源代码更容易开发:

std::ifstream vertexShaderFile("vertex.glsl");
std::ostringstream vertexBuffer;
vertexBuffer << vertexShaderFile.rdbuf();
std::string vertexBufferStr = vertexBuffer.str();
// Warning: safe only until vertexBufferStr is destroyed or modified
const GLchar *vertexSource = vertexBufferStr.c_str();
Run Code Online (Sandbox Code Playgroud)

现在的问题是如何使用您的程序发送着色器?实际上,使用您的应用程序运送源代码可能是个问题.OpenGL支持"预编译的二进制着色器",但Open Wiki声明:

程序二进制格式不打算传输.期望不同的硬件供应商接受相同的二进制格式是不合理的.期望来自同一供应商的不同硬件接受相同的二进制格式是不合理的.[...]

如何使用C++软件实际运送GLSL着色器?

c++ opengl glsl

46
推荐指数
6
解决办法
3万
查看次数

如何计算Tangent和Binormal?

在OpenGL着色语言(GLSL)中讨论凹凸贴图,镜面高光和这些东西

我有:

  • 顶点数组(例如{0.2,0.5,0.1,0.2,0.4,0.5,...})
  • 法线数组(例如{0.0,0.0,1.0,0.0,1.0,0.0,...})
  • 点光源在世界空间中的位置(例如{0.0,1.0,-5.0})
  • 观众在世界空间中的位置(例如{0.0,0.0,0.0})(假设观众位于世界的中心)

现在,我如何计算每个顶点的Binormal和Tangent?我的意思是,计算Binormals的公式是什么,我必须根据这些信息使用什么?和切线相关?

无论如何我都会构建TBN矩阵,所以如果你知道根据这些信息直接构造矩阵的公式会很好!

哦,是的,如果需要,我也有纹理坐标.正如我所说的GLSL,我认为,每个顶点解决方案都是不错的,它不需要一次访问多个顶点信息.

----更新-----

我找到了这个解决方案

vec3 tangent;
vec3 binormal;

vec3 c1 = cross(a_normal, vec3(0.0, 0.0, 1.0));
vec3 c2 = cross(a_normal, vec3(0.0, 1.0, 0.0));

if (length(c1)>length(c2))
{
    tangent = c1;
}
else
{
    tangent = c2;
}

tangent = normalize(tangent);

binormal = cross(v_nglNormal, tangent);
binormal = normalize(binormal);

但我不知道它是否100%正确.

opengl math 3d glsl

43
推荐指数
3
解决办法
4万
查看次数

在OpenGL中有一种方法可以获得着色器程序使用的所有制服和属性的列表吗?

我想得到一个着色器程序对象使用的所有制服和属性的列表. glGetAttribLocation()&glGetUniformLocation()可以用来将字符串映射到一个位置,但我真正想要的是字符串列表而不必解析glsl代码.

注意:在OpenGL 2.0中glGetObjectParameteriv()被替换为glGetProgramiv().而enum是GL_ACTIVE_UNIFORMS&GL_ACTIVE_ATTRIBUTES.

opengl 3d shader glsl

42
推荐指数
3
解决办法
2万
查看次数

用于GLSL编辑的工具

我正在寻找一种与GLSL一起使用的工具.我想在WebGL应用程序中试验着色器,所以我正在寻找的东西就像RenderMonkey.据我所知 - RenderMonkey不再受支持,因此必须有一些其他工具才能占据它的位置.

如果我能像RM一样完成"效果组合"和原始GLSL代码开发,那将是最好的.

ide opengl-es glsl webgl

42
推荐指数
6
解决办法
3万
查看次数

如何在OpenGL ES 2.0中获得"Glow"着色器效果?

我正在为iOS编写3D应用程序.我是OpenGL ES 2.0的新手,所以我还在自己编写基本的着色器.我真的需要根据纹理对我的一些模型实现"辉光"效果.

这是一个示例:

Bloom/Glow来自www.skillmanmedia.com/realbasic/bloomsnapshot.jpg .

我正在寻找OpenGL ES 2.0的代码示例.我在互联网上找到的大多数代码都是桌面OpenGL或D3D.

有任何想法吗?

shader opengl-es glsl ios opengl-es-2.0

40
推荐指数
2
解决办法
4万
查看次数

我应该在GPU或CPU上计算矩阵吗?

我是否更愿意在CPU或GPU上计算矩阵?

假设我有以下矩阵P * V * M,我应该在CPU上计算它们以便我可以将最终矩阵发送到GPU(GLSL),还是应该将这三个矩阵分别发送到GPU以便GLSL可以计算最终矩阵?

我的意思是在这种情况下,GLSL必须为每个顶点计算MVP矩阵,因此在CPU上预先计算它可能更快.

但是,让我们说GLSL只需要计算一次MVP矩阵,GPU会比CPU更快地计算出最终矩阵吗?

opengl glsl computer-vision

40
推荐指数
2
解决办法
2万
查看次数

如何提高自定义OpenGL ES 2.0深度纹理生成的性能?

我有一个开源iOS应用程序,它使用自定义OpenGL ES 2.0着色器来显示分子结构的三维表示.它通过使用在矩形上绘制的程序生成的球体和圆柱体冒充者来实现这一点,而不是使用大量顶点构建的这些相同形状.这种方法的缺点是这些冒名顶替对象的每个片段的深度值需要在片段着色器中计算,以便在对象重叠时使用.

不幸的是,OpenGL ES 2.0 不允许你写入gl_FragDepth,所以我需要将这些值输出到自定义深度纹理.我使用帧缓冲对象(FBO)对场景进行传递,仅渲染出与深度值对应的颜色,并将结果存储到纹理中.然后将此纹理加载到渲染过程的后半部分,在此过程中生成实际的屏幕图像.如果该阶段的片段处于存储在屏幕上该点的深度纹理中的深度级别,则显示该片段.如果没有,它就会被抛出.有关该过程的更多信息,包括图表,可以在我的帖子中找到.

这种深度纹理的生成是我渲染过程中的一个瓶颈,我正在寻找一种方法来加快它的速度.它似乎比它应该慢,但我无法弄清楚为什么.为了实现正确生成此深度纹理​​,GL_DEPTH_TEST禁用,GL_BLEND启用glBlendFunc(GL_ONE, GL_ONE),并glBlendEquation()设置为GL_MIN_EXT.我知道以这种方式输出的场景在基于图块的延迟渲染器上并不是最快的,比如iOS设备中的PowerVR系列,但我想不出更好的方法.

我对球体的深度片段着色器(最常见的显示元素)看起来是这个瓶颈的核心(仪器中的渲染器利用率固定在99%,表明我受片段处理的限制).目前看起来如下:

precision mediump float;

varying mediump vec2 impostorSpaceCoordinate;
varying mediump float normalizedDepth;
varying mediump float adjustedSphereRadius;

const vec3 stepValues = vec3(2.0, 1.0, 0.0);
const float scaleDownFactor = 1.0 / 255.0;

void main()
{
    float distanceFromCenter = length(impostorSpaceCoordinate);
    if (distanceFromCenter > 1.0)
    {
        gl_FragColor = vec4(1.0);
    }
    else
    {
        float calculatedDepth = sqrt(1.0 - distanceFromCenter * distanceFromCenter);
        mediump float …
Run Code Online (Sandbox Code Playgroud)

iphone opengl-es glsl ipad ios

39
推荐指数
3
解决办法
1万
查看次数

GLSL多个着色程序VS制服开关

我正在研究着色器管理器架构,我有几个问题需要更高级的人员.我目前的选择反对两种设计:


1.每个材质着色器程序

=>为程序中使用的每种材质创建一个着色器程序.

潜在的缺点:

  • 考虑到每个对象可能都有自己的材质,它涉及很多glUseProgram调用.
  • 意味着创建了许多着色器程序对象.
  • 更复杂的架构#2.

优点:

  • 可以专门为材料中使用的每个"选项"生成着色器代码.
  • 如果我没错,制服必须只设置一次(创建着色器程序时).


2.全局着色器程序

=>为每个着色器功能(闪电,反射,视差映射......)创建一个着色器程序,并根据要渲染的材质使用配置变量启用或放弃选项.

潜在的缺点:

  • 每帧必须多次更换制服.

优点:

  • 较低的着色器程序计数.
  • 减少SP swich(glUseProgram).


您可能会注意到我目前的趋势是#1,但我想知道您对此的看法.

  • 初始制服设置是否会抵消glUseProgram呼叫开销(我不是特别速度怪胎)?
  • 在#1的情况下,对于任何内存或性能考虑,我应该在创建SP时只调用一次glLinkProgram,还是每次调用glUseProgram时都必须取消链接/链接?
  • 有更好的解决方案吗?

谢谢!

architecture shader glsl

39
推荐指数
2
解决办法
8356
查看次数

GLSL中的顶点着色器属性映射

我正在使用GLSL着色器编写一个小型渲染引擎:

每个网格(井,子网格)都有一些顶点流(例如位置,法线,纹理,切线等)到一个大的VBO和一个MaterialID中.

每个材质都有一组纹理和属性(例如镜面反射颜色,漫反射颜色,颜色纹理,法线贴图等)

然后我有一个GLSL着色器,它的制服和属性.让我们说:

uniform vec3 DiffuseColor;
uniform sampler2D NormalMapTexture;
attribute vec3 Position;
attribute vec2 TexCoord;
Run Code Online (Sandbox Code Playgroud)

我试图为GLSL着色器设计一种方法来定义属性和制服的流映射(语义),然后将顶点流绑定到适当的属性.

对网格说法的内容:"将您的位置流放在属性"位置"中,将您的tex坐标放在"TexCoord"中.还将材质的漫反射颜色放在"DiffuseColor"中,将材质的第二个纹理放在"NormalMapTexture"中

目前我正在使用硬编码的名称作为属性(即顶点pos始终是"位置"等)并检查每个统一和属性名称以了解着色器使用它的内容.

我想我正在寻找一种创建"顶点声明"的方法,但也包括制服和纹理.

所以我只是想知道人们如何在大型渲染引擎中做到这一点.

编辑:

回顾建议的方法:

1.属性/统一语义由变量名称给出 (我现在正在做什么)为每个可能的属性使用预定义的名称.GLSL绑定器将查询每个属性的名称并基于该属性链接顶点数组.变量名称:

//global static variable

semantics (name,normalize,offset) = {"Position",false,0} {"Normal",true,1},{"TextureUV,false,2}

 ...when linking
for (int index=0;index<allAttribs;index++)
{
   glGetActiveAttrib(program,index,bufSize,length,size[index],type[index],name);      
   semantics[index]= GetSemanticsFromGlobalHardCodedList(name);
} 
... when binding vertex arrays for render
 for (int index=0;index<allAttribs;index++)
{
    glVertexAttribPointer(index,size[index],type[index],semantics[index]->normalized,bufferStride,semantics[index]->offset);

}  
Run Code Online (Sandbox Code Playgroud)

2.每个语义的预定义位置

GLSL绑定器将始终将顶点数组绑定到相同的位置.着色器可以使用相应的名称进行匹配.(这看起来非常类似于方法1,但除非我误解,否则这意味着绑定所有可用的顶点数据,即使着色器不使用它)

.. when linking the program...
glBindAttribLocation(prog, 0, "mg_Position");
glBindAttribLocation(prog, 1, "mg_Color");
glBindAttribLocation(prog, 2, "mg_Normal");
Run Code Online (Sandbox Code Playgroud)

3.来自Material,Engine globals,Renderer和Mesh的可用属性的字典

维护活动材质,引擎全局,当前渲染器和当前场景节点发布的可用属性列表.

例如:

 Material has (uniformName,value) = …
Run Code Online (Sandbox Code Playgroud)

opengl glsl rendering-engine

37
推荐指数
2
解决办法
3万
查看次数

归一化价值意味着什么?

我目前正在研究OpenGL中的照明,它使用GLSL中的一个函数,称为normalize.根据OpenGL文档,它说它"计算两个向量的标准化乘积".但是,它仍然无法解释"正常化"的含义.我已经尝试过在Google上查找标准化产品,但我似乎无法找到任何相关信息.任何人都可以解释正常化的含义并提供一些标准化值的例子吗?

opengl glsl normalization

37
推荐指数
2
解决办法
3万
查看次数