考虑典型的“天真”顶点着色器:
in vec3 aPos;
uniform mat4 uMatCam;
uniform mat4 uMatModelView;
uniform mat4 uMatProj;
void main () {
gl_Position = uMatProj * uMatCam * uMatModelView * vec4(aPos, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
当然,传统观点会建议“每个顶点乘以三个 mat4,其中两个即使在当前着色器程序中的多个后续 glDrawX() 调用中也是一致的,至少这两个应该在 CPU 端预乘,可能甚至所有三个。”
我想知道现代 GPU 是否已将此用例优化到 CPU 端预乘不再具有性能优势的程度。当然,纯粹主义者可能会说“这取决于最终用户的 OpenGL 实现”,但对于这个用例,我们可以安全地假设它将是提供该实现的当前一代支持 OpenGL 4.2 的 nVidia 或 ATI 驱动程序。
根据您的经验,考虑到我们可能会在每次 UseProgram() 传递中“绘制”一百万个左右的顶点——每个 UseProgram() 将至少预乘前两个(透视投影和相机变换矩阵)将性能提升到任何显着程度?每个 Draw() 调用的所有三个怎么样?
当然,这完全是关于基准测试......但我希望有人拥有基本的、基于当前硬件实现的见解我错过了这可能表明“甚至不值得一试,不要浪费你的时间”或“一定要这样做,因为您当前没有预乘法的着色器将是纯粹的疯狂” ......想法?
我正在尝试将片段着色器转换为顶点着色器(用于移动优化)
如下图所示,中心和右边缘的顶点有问题。(这是一个有 11 x 11 个顶点的平面)
UV 当前从右侧映射,并环绕中心(径向旋转)。我猜中间一半的多个顶点是创建一个洞的相同值?然后右侧将第一个 UV 值交叉淡化到最终值,从而产生拉伸效果。
问题是如何覆盖或修复这些。(它们可能是 2 个不同的问题?)

uniform vec2 _Offset;
uniform float _Multiply;
varying vec4 position;
varying vec4 vert;
varying vec2 tex;
varying vec2 uv;
varying float ar;
#ifdef VERTEX
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
vec2 p = -1.0 + 2.0 * tex.xy;
float a = atan(p.y,p.x) ;
float r = sqrt(dot(p,p));
uv.x = _Multiply*a/3.1416 * 2.0 + 0.1;
float sx = sin(_Multiply*r+_Offset.x);
float sy = _Multiply*.1*cos(_Offset.y+_Multiply*a);
uv.y = -_Offset.x + …Run Code Online (Sandbox Code Playgroud) opengl-es glsl unity-game-engine vertex-shader opengl-es-2.0
我正在尝试为 3D 场景实现导航技术(在 OpenSceneGraph 中使用 OpenGL)。除其他事项外,用户应该能够点击屏幕上的场景对象以朝它移动。
导航技术应集成到另一个项目中,该项目使用顶点着色器将全局变形应用于场景几何体。这就是问题所在:由于使用顶点着色器使几何体变形,因此将鼠标光标位置取消投影到用户实际选择的地点的世界坐标并不是直接的。但是我需要这些坐标来在我的导航技术中执行正确的相机移动。
执行这种非投影的一种方法是修改顶点着色器(用于变形),让它也将顶点的原始位置和法线存储在单独的纹理中。之后可以在鼠标位置读取这些纹理以获得所需的值。
现在,正如我所说,顶点着色器属于另一个我实际上不想触及的项目。我的导航技术的一个目标是尽可能通用,以便轻松集成到其他项目中。
那么问题来了:到目前为止,OpenSceneGraph 或 OpenGL 中是否有任何我没有考虑的功能?有什么可以让我独立于顶点着色器编码器获得片段的世界坐标的吗?
我目前正在尝试使用Android的OpenGL ES 2.0进行游戏.我的地图是一个二维网格地图,每个位置都有一个高度值.现在我想在纹理中存储每个坐标的高度,以在顶点着色器中进行高度查找.
这个想法的好处是我可以生成一个通用三角网并将其(带偏移)放在用户当前正在查看的地图位置上.由于偏移,我可以省略每次用户移动其视图位置和我将从纹理读取的高度轮廓时创建新三角网的需要.
现在存在的问题是许多当前的Android设备(甚至是Galaxy S3)不支持顶点着色器中的纹理查找.可悲的是,这完全破坏了我目前的做法.
我的问题:还有其他可能从顶点着色器中的图形卡内存中获取数据吗?如果不直接指定每个顶点的数据,每次用户更改视图位置时,会强制我(据我所知)重新创建高度贴图.(每次用户更改视图位置时创建高度图都会变慢...)
感谢您的帮助+最好的问候,
安德烈亚斯
人们。
我在通过constant buffer将浮点数组传递给顶点着色器(HLSL)时遇到问题。我知道由于 HLSL 打包规则,下面数组中的每个“浮点数”都单独获得一个 16 字节的插槽(空间相当于 float4):
// C++ struct
struct ForegroundConstants
{
DirectX::XMMATRIX transform;
float bounceCpp[64];
};
// Vertex shader constant buffer
cbuffer ForegroundConstantBuffer : register(b0)
{
matrix transform;
float bounceHlsl[64];
};
Run Code Online (Sandbox Code Playgroud)
(不幸的是,这里的简单解决方案不起作用,在我进行更改后没有绘制任何内容)
而C ++数据被传递时,由于包装规则他们得到间隔开,使得每个“浮动”中bounceCpp C ++阵列中进入一个16字节的空间中的所有本身bounceHlsl阵列。这导致了类似于以下内容的警告:
ID3D11DeviceContext::DrawIndexed:Vertex Shader 单元的 slot 0 处的 Constant Buffer 的大小太小(提供 320 字节,至少 1088 字节,预期)。这是可以的,因为越界读取被定义为返回 0。开发人员也可能知道无论如何都不会使用丢失的数据。如果开发人员实际上打算为着色器期望绑定足够大的常量缓冲区,这只是一个问题。
正如此处和此处所指出的,建议以这种方式重写 HLSL 常量缓冲区:
cbuffer ForegroundConstantBuffer : register(b0)
{
matrix transform;
float4 bounceHlsl[16]; // equivalent …Run Code Online (Sandbox Code Playgroud) 从着色器的three.js教程中,我们了解到我们可以更新ShaderMaterial的统一值:
var attributes = {
displacement: {
type: 'f', // a float
value: [] // an empty array
}
};
var uniforms = {
amplitude: {
type: 'f', // a float
value: 1
}
};
var vShader = $('#vertexshader');
var fShader = $('#fragmentshader');
// create the final material
var shaderMaterial =
new THREE.MeshShaderMaterial({
uniforms: uniforms,
attributes: attributes,
vertexShader: vShader.text(),
fragmentShader: fShader.text()
});
...
var frame = 0;
function update() {
// update the amplitude based on …Run Code Online (Sandbox Code Playgroud) 我很想知道gl_PointSize和 中的 size 属性之间有什么关系PointCloudMaterial。
当我创建PointCloudwithPointCloudMaterial并将属性设置size为时1,粒子的大小远大于创建PointCloudwith aShaderMaterial并将顶点着色器的大小参数设置为 时的大小1。我还像在着色器中一样考虑了尺寸衰减PointCloudMaterial:
<script type="x-shader/x-vertex" id="particle_vs">
uniform float size;
uniform float scale;
void main() {
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_PointSize = size * ( scale / length( mvPosition.xyz ) );
gl_Position = projectionMatrix * mvPosition;
}
</script>
Run Code Online (Sandbox Code Playgroud)
我在这里提取了我的问题的一个简单示例: http: //dev.cartelle.nl/article-example/
PointCloudMaterial为 size 的集合1。ShaderMaterial …我正在 OpenGL 中渲染一条由三角形组成的线。
现在我可以在以下地方工作:
顶点缓冲区:{v0, v1, v2, v3}
索引缓冲区(三角带):{0, 1, 2, 3}
顶部图像是传递到顶点着色器的原始数据,底部是对 v1 和 v3 应用偏移量(使用顶点属性)后顶点着色器的输出。
我的目标是在线上的每个点使用一个顶点,并以其他方式生成偏移。我正在查看 gl_VertexID,但我想要更像元素 ID 的东西。这是我想要的设置:
顶点缓冲区:{v0, v2}
索引缓冲区(三角带):{0, 0, 1, 1}
并使用虚数gl_ElementID % 2来偏移所有其他顶点。
我试图避免使用几何着色器或其他顶点属性。有什么办法可以做到这一点吗?我对完全不同的想法持开放态度。
顶点着色器中的设置gl_PointSize = 1.0意味着什么或实现什么?这是否意味着顶点本身就是一个像素?
我试图让我的着色器在 Shaderfrog 中工作,我通过 URL 导入我的 glsl 沙箱版本。
我收到错误:“C:\fakepath(111,2-27):警告 X3550:数组引用不能用作左值;本身不可寻址,强制循环展开。
真的不确定为什么会发生这个错误,我尝试取消循环内的任何循环,但无济于事。
这是我的片段代码:
#extension GL_OES_standard_derivatives : enable
precision highp float;
varying vec2 vUv;
uniform float time;
uniform vec2 resolution;
void main()
{
vec2 p = vUv.xy / resolution.x * .05;
vec3 col;
for (float j = 0.; j < 3.; j++) {
p.x += ((0.05 / 2.0) * sin(2.0 * 10. * p.y + (time*0.2) + cos((time / (150. * 2.0)) * 2.0)));
p.y += ((0.02 / 2.0)* cos(2.0 * 10. * …Run Code Online (Sandbox Code Playgroud)