标签: shader

将纹理(绘制为平面3D对象)转换为模仿深度时,黑色线条会随机出现

我们正在使用XNA开发一个自上而下的RPG.最近我们在编写显示地图的代码时陷入了挫折.在绘制地图时,使用正常变换矩阵的自上而下视图,一切似乎都很好.当使用非平面变换矩阵时,例如挤压顶部或底部以模拟深度,当相机改变位置时,出现黑线(顶部或底部的行,当向左或向右挤压时的列).移动和放置似乎是随机的.(图片进一步提供.)

背景资料

地图由瓷砖组成.原始纹理具有由32x32像素组成的图块.我们通过创建2个三角形并在这些三角形上显示原始纹理的一部分来绘制切片.着色器为我们做了这个.有三层三角形.首先,我们绘制所有不透明的瓷砖和所有半透明和部分透明瓷砖的所有不透明像素,然后是所有半透明和部分透明的瓷砖和像素.这样可以正常工作(但是当我们使用浮点因子进行缩放时,有时颜色混合的线条位于切片行和/或列之间).

绘制状态

我们对所有瓷砖使用相同的rasterizerState,并且在绘制实体或半透明瓷砖时我们在两者之间切换.

_rasterizerState = new RasterizerState();
_rasterizerState.CullMode = CullMode.CullCounterClockwiseFace;

_solidDepthState = new DepthStencilState();
_solidDepthState.DepthBufferEnable = true;
_solidDepthState.DepthBufferWriteEnable = true;

_alphaDepthState = new DepthStencilState();
_alphaDepthState.DepthBufferEnable = true;
_alphaDepthState.DepthBufferWriteEnable = false;
Run Code Online (Sandbox Code Playgroud)

在阴影中,我们将SpriteBlendMode设置如下:

第一个固体层1使用

AlphaBlendEnable = False; 
SrcBlend = One; 
DestBlend = Zero; 
Run Code Online (Sandbox Code Playgroud)

所有其他实心和透明层(稍后绘制)使用

AlphaBlendEnable = True; 
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha; 
Run Code Online (Sandbox Code Playgroud)

其他着色器也使用它.在SpriteBatchSpriteFonts使用的,使用默认设置.

生成的纹理

一些图块即时生成并保存到文件中.加载地图时会加载该文件.这是使用RenderTarget如下创建完成的:

RenderTarget2D rt = new RenderTarget2D(sb.GraphicsDevice, 768, 1792, false, 
    SurfaceFormat.Color, DepthFormat.None);
    sb.GraphicsDevice.SetRenderTarget(rt);
Run Code Online (Sandbox Code Playgroud)

生成后,文件将被保存并加载(因此,当设备重置时,我们不会丢失它,因为它不再存在于a RenderTarget).我尝试使用mipmapping,但它是一个spritesheet.没有关于瓷砖放置位置的信息,因此mipmapping是无用的,并没有解决问题.

顶点

我们遍历每个位置.这里没有浮点,但位置是Vector3(Float3).

for (UInt16 …
Run Code Online (Sandbox Code Playgroud)

c# graphics shader xna

51
推荐指数
2
解决办法
1461
查看次数

WebGL/GLSL - ShaderToy如何工作?

我一直在敲Shadertoy - https://www.shadertoy.com/ - 最近,为了更多地了解OpenGL和GLSL.

据我所知,到目前为止,OpenGL用户首先必须准备要使用的所有几何体并配置OpenGL服务器(允许的光源数量,纹理存储等).一旦完成,用户就必须在OpenGL程序编译之前提供至少一个顶点着色器程序和一个片段着色器程序.

但是,当我查看Shadertoy上的代码示例时,我只看到一个着色器程序,并且大多数使用的几何图形似乎直接写入GLSL代码.

这是如何运作的?

我猜测顶点着色器已经预先准备好了,可编辑/样本着色器只是一个片段着色器.但是,这并没有解释一些更复杂的例子中的几何...

谁能解释Shadertoy是如何工作的?

javascript shader glsl webgl pixel-shader

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

为什么我的OpenGL Phong着色器表现得像平面着色器?

过去几周我一直在学习OpenGL,我在实现Phong着色器方面遇到了一些麻烦.尽管使用了smooth限定符,但似乎在顶点之间没有插值.我在这里错过了什么吗?为了给予信用到期的信用,顶点和片段着色器的代码严重影响了OpenGL SuperBible第五版.我强烈推荐这本书!

顶点着色器:

#version 330
in vec4 vVertex;
in vec3 vNormal;
uniform mat4 mvpMatrix;  // mvp = ModelViewProjection
uniform mat4 mvMatrix; // mv = ModelView
uniform mat3 normalMatrix;
uniform vec3 vLightPosition;
smooth out vec3 vVaryingNormal;
smooth out vec3 vVaryingLightDir;

void main(void) {
 vVaryingNormal = normalMatrix * vNormal;
 vec4 vPosition4 = mvMatrix * vVertex;
 vec3 vPosition3 = vPosition4.xyz / vPosition4.w;
 vVaryingLightDir = normalize(vLightPosition - vPosition3);
 gl_Position = mvpMatrix * vVertex;
}
Run Code Online (Sandbox Code Playgroud)

片段着色器:

#version 330
out vec4 vFragColor; …
Run Code Online (Sandbox Code Playgroud)

opengl shader glsl pyopengl

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

什么可能导致glDrawArrays生成GL_INVALID_OPERATION错误?

我一直在尝试使用OpenGL和GLSL编写Marching Cubes算法的两遍GPU实现,类似于GPU Gems 3第一章中详述的算法.但是,glDrawArrays在我的第一次传球中的呼叫始终失败了GL_INVALID_OPERATION.

我查找了所有可以找到的文档,并发现这些条件glDrawArrays可以抛出该错误:

  1. GL_INVALID_OPERATION如果非零缓冲区对象名称绑定到已启用的数组或GL_DRAW_INDIRECT_BUFFER绑定,并且缓冲区对象的数据存储当前已映射,则会生成.
  2. GL_INVALID_OPERATION如果glDrawArrays在执行glBegin和相应的执行之间执行,则生成glEnd.
  3. GL_INVALID_OPERATION将由glDrawArraysglDrawElements当前程序对象中的任何两个活动采样器具有不同类型,但引用相同的纹理图像单元.
  4. GL_INVALID_OPERATION 如果几何着色器处于活动状态且模式与当前安装的程序对象中几何着色器的输入基元类型不兼容,则会生成.
  5. GL_INVALID_OPERATION如果模式是GL_PATCHES并且没有曲面细分控制着色器处于活动状态,则生成.
  6. GL_INVALID_OPERATION如果将基元的顶点记录到用于变换反馈目的的缓冲区对象,则会生成超出任何缓冲区对象大小的限制,或者超出结束位置偏移+大小-1,如下所示glBindBufferRange.
  7. GL_INVALID_OPERATIONglDrawArrays()如果不存在几何着色器,则生成变换反馈,并且模式不是允许的模式之一.
  8. GL_INVALID_OPERATIONglDrawArrays()如果存在几何着色器,则生成变换反馈,并且几何着色器的输出基元类型与变换反馈primitiveMode不匹配.
  9. GL_INVALID_OPERATION 如果绑定着色器程序无效,则生成.
  10. GL_INVALID_OPERATION如果正在使用变换反馈,则生成编辑10/10/12:绑定到变换反馈绑定点的缓冲区也绑定到数组缓冲区绑定点.这是我遇到的问题,因为我绑定了缓冲区的拼写错误.虽然规范确实声明这是非法的,但在我发现的任何文档中,它都没有列在glDrawArrays下作为它可以抛出错误的原因之一.

不幸的是,我找不到任何一份官方文档,其中包括超过3篇.我不得不从众多来源收集这份清单.第7点和第8点实际上来自文档glBeginTransformFeedback,第9点似乎根本没有记录.我发现它在某个论坛帖子中提到过.但是,我仍然不认为这个列表是完整的,因为这些似乎都没有解释我得到的错误.

  1. 我在任何地方的程序中都没有映射任何缓冲区.
  2. 我使用的是核心配置文件,所以glBeginglEnd没有提供连.
  3. 我有两个采样器,它们有不同的类型,但它们肯定映射到不同的纹理.
  4. 几何着色器处于活动状态,但它的输入布局是layout (points) in,并且glDrawArrays正在调用GL_POINTS.
  5. 我没有使用GL_PATCHES任何类型的镶嵌着色器.
  6. 我已经确定我正在分配我的几何着色器可能输出的最大空间量.然后我尝试了四倍.没有帮助.
  7. 有一个几何着色器.看下一点.
  8. 正在使用变换反馈,并且有一个几何着色器,但输出布局是layout (points) out …

opengl shader glsl marching-cubes geometry-shader

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

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

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

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

opengl 3d shader glsl

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

OpenGL 4.x学习资源

我知道有一些关于学习OpenGL的问题.这就是我所知道的:

  • 3D的数学
  • 三维理论

以下是我想知道的: - OpenGL 4.0 核心配置文件(或后者) - Shader Language 400(或后者) - 上面的每一部分(如果它不能在供应商之间工作那么它仍然不会打扰我)

这是我不想知道的 - 固定功能管道(永远不会使用它!) - 旧的OpenGL - 兼容性配置文件

我更喜欢大部分信息,如教程,系列文章,书籍.

PS如果您了解opengl 3.x核心配置文件的资源,也可以发布它们

opengl shader opengl-3 opengl-4

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

如何在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万
查看次数

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

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


1.每个材质着色器程序

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

潜在的缺点:

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

优点:

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


2.全局着色器程序

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

潜在的缺点:

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

优点:

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


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

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

谢谢!

architecture shader glsl

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

着色器中分支的效率

我知道这个问题可能看起来有点没有根据,但如果有人知道任何理论/有关于这个主题的实践经验,那么如果你分享它会很棒.

我正在尝试优化我的一个旧着色器,它使用了大量的纹理查找.

我有三个可能的映射平面中的每一个的漫反射,普通,高光贴图,对于一些靠近用户的面,我还必须应用贴图技术,这也带来了很多纹理查找(如parallax occlusion mapping).

分析表明纹理查找是着色器的瓶颈,我愿意将其中一些删除.对于输入参数的某些情况,我已经知道纹理查找的一部分是不必要的,显而易见的解决方案是执行类似(伪代码)的操作:

if (part_actually_needed) {
   perform lookups;
   perform other steps specific for THIS PART;
}

// All other parts.
Run Code Online (Sandbox Code Playgroud)

现在 - 问题来了.

我不记得确切(这就是为什么我说这个问题可能会不接地),但在某些纸张最近,我读(不幸的是,不记得名字了)类似下面的内容指出:

所提出的技术的性能取决于基于硬件的条件分支 的实施效率.

在我即将开始重构大量着色器并实现我所讨论的if基于优化的优化之前,我记得这种说法.

所以 - 在我开始这样做之前 - 有人知道着色器中分支的效率吗?为什么分支会在着色器中造成严重的性能损失?

甚至有可能我只能通过if基于分支的方式恶化实际性能?


你可能会说 - 试试看.是的,如果这里没有人帮助我,那就是我要做的事:)

但是,在这种if情况下,新GPU可能会有效,对于一些较老的GPU来说可能是一场噩梦.除非你有很多不同的GPU(这不是我的情况),否则很难预测这类问题

所以,如果有人知道这些或具有这些着色器的基准测试经验,我将非常感谢您的帮助.


实际工作的剩余脑细胞几乎没有告诉我,GPU上的分支可能远不如分支CPU(通常具有非常有效的分支预测方法和消除缓存未命中)那么有效,仅仅因为它是GPU(或者说可能很难/不可能在GPU上实现).

不幸的是,我不确定这个陈述是否与实际情况有任何共同之处......

performance shader branch

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

学习现代OpenGL

我知道在过去的几年中也有类似的问题,但在做了一些研究后,我仍然无法决定从哪里学习,应该学什么.我还希望通过更多的C++ OOP和着色器方法来了解您对现代OpenGL编程的当前实际观点.并确保我对某些事情的实际理解是有效的.

所以...目前我们已经有了OpenGL 4.2,当我读到某个地方需要dx11硬件(它是什么意思?)和一组'侧'库时,例如创建窗口.

有最常见的GLUT,我非常讨厌.其中一个主要原因是函数调用,它不允许我们创建主循环的方式自由.正如一些人所说,它不适合游戏.

还有GLFW,实际上对我来说非常好而直截了当.出于某种原因,人们将其与GLUT一起使用.(它不仅提供窗口初始化,还提供其他实用程序?)

还有SFML和SDL(SDL <SFML imo),而它们两者有时需要使用奇怪的方法来处理OGL,并且在某些情况下并不是很快.

而且我们还有GLEW,这是扩展加载实用程序......等待...... GLUT/GLFW已经不是扩展了吗?是否有任何理由使用它,就像是否有任何真正重要的扩展感兴趣?

直到现在我们都有窗口创建(和一些实用程序),但是...... OGL不会处理纹理,也不管3D模型.我需要多少个其他库?

我们现在提一下教育部分.有着名的NeHe教程.用C语言编写,使用WinApi,代码极其不清晰,过时的解决方案,但仍然是最受欢迎的解决方案.可以找到像Red Book这样的东西,这些东西与2.x或3.x等版本有关,但是只有少数(和未完成的)教程提到4.x.

怎么办?

c++ opengl shader opengl-4

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