gpt4 book ai didi

metal - 以编程方式编写纹理并在片段着色器中读取它

转载 作者:行者123 更新时间:2023-12-05 06:40:25 34 4
gpt4 key购买 nike

我编写了一个输出到纹理的计算着色器。输出纹理的坐标系以像素为单位。然后我有一个基本的顶点和片段着色器,它应该简单地对值进行采样并响应我认为在归一化坐标中的内容。但是,我认为我以编程方式绘制的纹理和渲染表面的顶点之间的这种映射会匹配。

计算函数

可以概括为

texture.write(color, uint2(x, y));

其中 x 和 y 是整数像素位置。

顶点数据

// position.x, position.y, texCoords.x, texCoords.y
let vertexData = [Float](arrayLiteral:
-1, 1, 0, 0,
-1, -1, 0, 1,
1, -1, 1, 1,
1, -1, 1, 1,
1, 1, 1, 0,
-1, 1, 0, 0)

Metal 着色器

typedef struct {
packed_float2 position;
packed_float2 texCoords;
} VertexIn;

typedef struct {
float4 position [[ position ]];
float2 texCoords;
} FragmentVertex;

vertex FragmentVertex simple_vertex(device VertexIn *vertexArray [[ buffer(0) ]],
uint vertexIndex [[ vertex_id ]])
{
VertexIn in = vertexArray[vertexIndex];

FragmentVertex out;
out.position = float4(in.position, 0.f, 1.f);
out.texCoords = in.texCoords;

return out;
}

fragment float4 simple_fragment(FragmentVertex in [[ stage_in ]],
texture2d<uint, access::sample> inputTexture [[ texture(0) ]],
sampler linearSampler [[ sampler(0) ]])
{
const uint2 imageSizeInPixels = uint2(360, 230);
float imageSizeInPixelsWidth = imageSizeInPixels.x;
float imageSizeInPixelsHeight = imageSizeInPixels.y;
float2 coords = float2(in.position.x / 360.f, in.position.y / 230.f);
float color = inputTexture.sample(linearSampler, in.texCoords).x / 255.f;

return float4(float3(color), 1.f);
}

采样器

let samplerDescriptor = MTLSamplerDescriptor()
samplerDescriptor.normalizedCoordinates = true
samplerDescriptor.minFilter = .linear
samplerDescriptor.magFilter = .linear
samplerDescriptor.sAddressMode = .clampToZero
samplerDescriptor.rAddressMode = .clampToZero
self.samplerState = self.metalDevice?.makeSamplerState(descriptor: samplerDescriptor)

在这个实验中,唯一似乎有效的值是 coords,它基于标准化的 in.position 值。 in.texCoords 似乎总是零。顶点和片段着色器接收到的纹理坐标和位置值不应该在顶点数据中定义的值范围内吗?

最佳答案

我的顶点缓冲区是对的,但错了

在将 Obj-C 代码转换为 Swift 的过程中,我未能完全复制顶点。

正确的副本

let byteCount = vertexData.count * MemoryLayout<Float>.size
let vertexBuffer = self.metalDevice?.makeBuffer(bytes: vertexData, length: byteCount, options: options)

我痛苦的根源

let vertexBuffer = self.metalDevice?.makeBuffer(bytes: vertexData, length: vertexData.count, options: options)

完整的顶点缓冲区创建

// Vertex data for a full-screen quad. The first two numbers in each row represent
// the x, y position of the point in normalized coordinates. The second two numbers
// represent the texture coordinates for the corresponding position.
let vertexData = [Float](arrayLiteral:
-1, 1, 0, 0,
-1, -1, 0, 1,
1, -1, 1, 1,
1, -1, 1, 1,
1, 1, 1, 0,
-1, 1, 0, 0)

// Create a buffer to hold the static vertex data

let options = MTLResourceOptions().union(.storageModeShared)
let byteCount = vertexData.count * MemoryLayout<Float>.size
let vertexBuffer = self.metalDevice?.makeBuffer(bytes: vertexData, length: byteCount, options: options)
vertexBuffer?.label = "Image Quad Vertices"
self.vertexBuffer = vertexBuffer

关于metal - 以编程方式编写纹理并在片段着色器中读取它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42697557/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com