- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试使用着色器加载地形上的四个纹理细节图 block ,方法是根据第五张图像合并它们,其中 r、g、b 和 a 组件用于确定每个纹理应该混合多少。混合工作正常,但是当我尝试添加我的“mixmap”图像时,它失败了,我猜是因为纹理坐标有问题。
首先,这里是着色器:
顶点着色器
void main() {
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
片段着色器
uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform sampler2D Texture2;
uniform sampler2D Texture3;
uniform sampler2D Mixmap;
varying vec3 pos;
void main()
{
vec4 texel0 = texture2D(Texture0, gl_TexCoord[0].st).rgba;
vec4 texel1 = texture2D(Texture1, gl_TexCoord[0].st).rgba;
vec4 texel2 = texture2D(Texture2, gl_TexCoord[0].st).rgba;
vec4 texel3 = texture2D(Texture3, gl_TexCoord[0].st).rgba;
vec4 mixmapTexel = texture2D(Mixmap, gl_TexCoord[0].st).rgba;
texel0 *= mixmapTexel.r;
texel1 = mix(texel0, texel1, mixmapTexel.g);
texel2 = mix(texel1, texel2, mixmapTexel.b);
gl_FragColor = mix(texel2, texel3, mixmapTexel.a);
}
正如我所说,混合效果很好。问题在于从我的混合图中读取的值不正确。
这里有一些关于我在做什么的更多解释。我正在构建一个从高度图加载地形的分页地形系统。然后我想使用我的 mixmap 图像来表示 rgba 组件应该根据高度混合多少纹理。
r是水
g是沙子
b是草
一个是摇滚
所以我需要能够从我的着色器中获取正确的像素值以正确地混合我的纹理。
这里是一个箱子和文本之间混合的例子,这样你就可以清楚地看到纹理是如何应用的。
现在,如果我使用一个简单的混合图图像(一半是红色,一半是绿色),它应该给我地形左侧的 crate 和右侧的文本,我得到
这是地形生成过程的一部分:它遍历顶点数组并创建地形三角形
void TerrainPage::generateDisplayList()
{
// create one display list
mDisplayListIndex = glGenLists(1);
// compile the display list, store a triangle in it
glNewList(mDisplayListIndex, GL_COMPILE);
glFrontFace( GL_CW ); // Vertex are added clockwise. Used to calculate normals
std::vector<Vertex>::iterator it;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
texShader.enable();
texShader.bindTexture(mTexture0, "Texture0", 0);
texShader.bindTexture(mTexture1, "Texture1", 1);
texShader.bindTexture(mTexture2, "Texture2", 2);
texShader.bindTexture(mTexture3, "Texture3", 3);
texShader.bindTexture(mMixmapTexture, "Mixmap", 4);
Vertex v;
int j=0;
glEnable(GL_TEXTURE_2D);
//mTexture.bind();
glBegin(GL_TRIANGLE_STRIP);
for(int i = 0; i<mVertices.size(); i++) {
if(i%(2*mWidth) == 0) glEnd(); glBegin(GL_TRIANGLE_STRIP);
v = mVertices[i];
glTexCoord2f(v.texcoords[0], v.texcoords[1]);
glVertex3f(v.position[0], v.position[1], v.position[2]);
}
glEnd();
glDisable(GL_TEXTURE_2D);
texShader.disable();
glEndList();
}
如果需要,我可以提供更多屏幕截图,还有我的一些代码。
作为所提供答案的后续,我尝试通过在着色器中计算 UV 来做到这一点。
首先,这是新的着色器
顶点着色器
varying vec4 VertexPosition;
void main() {
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
VertexPosition = gl_ModelViewMatrix * gl_Vertex;;
}
片段着色器
uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform sampler2D Texture2;
uniform sampler2D Texture3;
uniform sampler2D Mixmap;
varying vec4 VertexPosition;
float side = 500.;
void main()
{
vec4 texel0 = texture2D(Texture0, gl_TexCoord[0].st).rgba;
vec4 texel1 = texture2D(Texture1, gl_TexCoord[0].st).rgba;
vec4 texel2 = texture2D(Texture2, gl_TexCoord[0].st).rgba;
vec4 texel3 = texture2D(Texture3, gl_TexCoord[0].st).rgba;
vec4 mixmapTexel = texture2D(Mixmap, VertexPosition.xz/(2.*side)).rgba;
texel0 *= mixmapTexel.r;
texel1 = mix(texel0, texel1, mixmapTexel.g);
//texel2 = mix(texel1, texel2, mixmapTexel.b);
//vec4 tx = mix(texel2, texel3, mixmapTexel.a);
//vec4 tx = mixmapTexel; //vec4(1, 1, 1, 1.);
gl_FragColor = texel1;
//if(test > 250. )
// gl_FragColor = vec4(1.,1.,1.,1.);
}
这是结果
但是如果我移动相机:
如您所见,这次箱子和文本并排放置。但看起来我是在屏幕坐标而不是世界坐标中计算。我一定又对坐标系感到困惑了。我会尽力找到合适的!我只是想确保我的方向是正确的。我也会寻找多纹理坐标,一旦我弄清楚它是如何工作的,它可能会更方便;)
最佳答案
如果我没理解错的话,您的混合贴图需要不同的纹理坐标。现在它使用每个单元格的整个混合映射,这就是为什么你得到一半的文本,每个单元格的一半 crate 。
尝试使用多个纹理坐标。您还可以在着色器中计算正确的 UV,方法是用顶点的当前 x 位置除以地形在 x 方向上的长度,对于 y 也是如此。但是,如果您缩放地形,请务必将地形的长度也乘以比例。
如果您不明白我在说什么,地形的每个单元格都在获取以下任一的 UV:(0,0)、(1,0)、(0,1) 或 (1,1)。这对于 crate 和文本纹理来说很好,但 mixmap 应该更加碎片化和多样化。
这是一个link到另一个地形教程。它使用 DirectX,但顶点/UV 生成具有可比性。最大的不同是他为整个地形使用了一个大纹理,这是你需要为你的 mixmap 而不是为你的其他纹理做的。
我想我知道出了什么问题。显式存储顶点位置。不要将它乘以 modelviewmatrix 即:
varying vec4 VertexPosition;
void main() {
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
//VertexPosition = gl_ModelViewMatrix * gl_Vertex;;
VertexPosition = gl_Vertex;
}
这会修复它,抱歉,我将你的固定着色器放入 rendermonkey,它不再随相机移动。希望这可以帮助。我正在平移,但现在看起来像:
关于c++ - GLSL 着色器纹理 alpha splatting,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13433902/
如何覆盖解包语法*obj和**obj的结果? 例如,您能否以某种方式创建一个行为如下的对象 thing: >>> [*thing] ['a', 'b', 'c'] >>> [x for x in th
在 Python 中,可以使用 * 运算符来解包可迭代对象。 In [1]: head, *tail = [1, 2, 3, 4, 5] In [2]: head Out[2]: 1 In [3]:
我被要求调整我前一段时间正在处理的脚本。我得到了帮助here .在脚本中,我使用了 splatting 和格式运算符。它在脚本上进一步工作,但失败了。我打开了一个小得多的样本来显示失败。如果您需要查看
我大部分时间都在用这个。我试图在 splatting 之前向我的哈希表添加一个参数。但是,我尝试添加的参数是两个字符串的集合。 $myHT = @{ From = 'me@x.
F# 内置运算符/函数是否允许解包参数列表/元组并将其传递给函数调用? 用法示例: // simple add function let add (a1 : int) (a2 : int) (a3 :
我正在尝试使用 Start-Job 来启动一个新的 Powershell 脚本。新脚本有几个参数(有些是可选的,有些不是),所以我想制作一个哈希表并将它们拼凑起来。然而,这些参数之一本身就是一个哈希表
下面的 Split-Path 参数不正确,它应该是 $delZipExe。 这使得 $delZipCmd 哈希值被设置为空。 我希望 WorkingDirectory 值在 $delZipCmd 哈希
我试图解压一个列表: ls = [1, 2, 3] a, *b = ls 然后,我尝试解压字典: dc = {'x': 1, 'y': 2, 'z': 3} a, **b = dc # Out: Sy
我在一篇文章中看到了这方面的插图,但是当我在我的 IRB shell 中尝试它时,我得到了一个错误。以下代码合法吗?否则有没有一种简写的方法来获取中间数组(比如假定排序数组的 1 或 2 个元素的中值
对于下面的方法 def mixed_args(a,b,*c,d) puts a,b,c,d end p mixed_args(1,2,3,4,5) 我收到此错误消息: syntax error,
为什么这段代码 Hash[*[[:first_name, 'Shane'], [:last_name, 'Harvie']].flatten] 返回这个 {:first_name=>"Shane",
使用yield_self,一元方法的参数可以预先放置在方法链中。因此,给定: Foo = Struct.new(:one_arg) 这一行: Foo.new("x") 相当于那一行: "x".yiel
我是 Ruby 的新手,将构建国际象棋作为一种学习练习。我正在尝试重构一些代码,但遇到了困难。 为什么这样做: @available_moves = [] #part of castling logi
match, text, number = *"foobar 123".match(/([A-z]*) ([0-9]*)/) 我知道这是在做某种正则表达式匹配,但是 splat 在这里扮演什么角色,有
def initialize(apps, catch=404) @apps = []; @has_app = {} apps.each { |app| add app } @catch =
昨天有人问splat运算符,我想看源代码……是用C写的还是Ruby写的?在哪里可以找到? 最佳答案 一些快速的谷歌搜索显示它是在 eval.c 中实现的。 .您可以在文件中的几个地方找到对“splat
散列上的 splat 将其转换为数组。 [*{foo: :bar}] # => [[:foo, :bar]] 这里是否存在某种隐藏机制(例如隐式类转换),或者它是一种内置的原始特征? 除了数组,nil
我在浏览 Camping 代码库时看到一个带有 splat 的构造函数,如下所示: class Fruit def initialize(*) end end 我试着在这个网站和谷歌上查找“s
这是我的程序: def calculate(*numbers, options = {}) add(numbers) if options[:add] subtract(number
我定义了一个带有循环的模块: module "stamp" { for_each = toset(var.stamps) source = "./modules/stamp" ...
我是一名优秀的程序员,十分优秀!