gpt4 book ai didi

ios - 在 iOS Metal 中重用具有不同统一参数的像素着色器

转载 作者:行者123 更新时间:2023-11-29 10:30:08 25 4
gpt4 key购买 nike

我在跨具有不同统一参数的不同对象重用我的 Metal 像素和顶点着色器时遇到问题。我猜这与我错误地使用命令缓冲区有关。

当我运行我的 Metal 应用程序时,几何图形绘制正确,但只有最终调用的制服

renderCommand setFragmentBuffer:uniform_info offset:0 atIndex:UNIFORM_INFO_BUFFER_INDEX];

似乎在向像素着色器写入数据。

我在这里剪切粘贴(并编辑)了我的渲染循环。我正在寻找一个示例,说明如何在传入不同制服的单个渲染过程中多次重复使用我的像素着色器。

  CAMetalLayer *metalLayer = [metal_info.g_iosMetalView getMetalLayer];

id <CAMetalDrawable> frameDrawable;
while (!frameDrawable){
frameDrawable = [metalLayer nextDrawable];
}
MTLRenderPassDescriptor *mtlRenderPassDescriptor;
mtlRenderPassDescriptor = [MTLRenderPassDescriptor new];
mtlRenderPassDescriptor.colorAttachments[0].texture = frameDrawable.texture;
mtlRenderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionLoad;
mtlRenderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0, 0.0, 1.0, 1.0);

mtlRenderPassDescriptor.depthAttachment.texture = metal_info.g_depthTexture;
mtlRenderPassDescriptor.depthAttachment.loadAction = MTLLoadActionClear;
mtlRenderPassDescriptor.depthAttachment.storeAction = MTLStoreActionStore;
mtlRenderPassDescriptor.depthAttachment.clearDepth = 1.0;

// Create My one and only command buffer
id <MTLCommandBuffer> mtlCommandBuffer = [metal_info.g_commandQueue commandBuffer];

int n = RendererInfo.fact.GetActiveCount();

// loop through all the objects I have (I'm having trouble with 2)
Object* curObj = NULL;
for (int obj_i = 0 ; obj_i < n ; ++obj_i)
{
// create one render encoder for each object
id <MTLRenderCommandEncoder> renderCommand = [mtlCommandBuffer renderCommandEncoderWithDescriptor: mtlRenderPassDescriptor];

memcpy([metal_info.g_projectionMatrix contents], &metal_info.g_Projection, sizeof(Matrix4f));
Matrix4f *view = RendererInfo.cam->GetViewMatrix();
memcpy([metal_info.g_viewMatrix contents], view, sizeof(Matrix4f));

[renderCommand setFrontFacingWinding:MTLWindingCounterClockwise];
[renderCommand setCullMode:MTLCullModeBack];

[renderCommand setViewport: (MTLViewport){ 0.0, 0.0,
(double)metal_info.g_metal_width,
(double)metal_info.g_metal_height,
0.0, 1.0 }];

[renderCommand setRenderPipelineState:metal_info.g_pipelineState];
[renderCommand setDepthStencilState:metal_info.g_depthState];


curObj = RendererInfo.fact.GetObjectAtIndex(obj_i);

id<MTLBuffer> vertices = curObj->GetVertexBuffer();
id<MTLBuffer> indicies = curObj->GetIndexBuffer();
int indexCount = curObj->GetIndexCount();

id <MTLTexture> texture = objTexture->GetAsset();
[renderCommand setFragmentTexture:texture atIndex:0];

memcpy([metal_info.g_shaderUniformInfo contents], curObj->GetUniformInfo(), curObj->curObj->GetUniformInfoSize());

[renderCommand setVertexBuffer:vertices offset:0 atIndex:VERTICES__INDEX];
[renderCommand setVertexBuffer:metal_info.g_viewMatrix offset:0 atIndex:VIEW_MATRIX_BUFFER_INDEX];
[renderCommand setVertexBuffer:metal_info.g_projectionMatrix offset:0 atIndex:PROJECTION_MATRIX_BUFFER_INDEX];

[renderCommand setFragmentBuffer:metal_info.g_shaderUniformInfo offset:0 atIndex:UNIFORM_INFO_BUFFER_INDEX];

[renderCommand drawIndexedPrimitives:MTLPrimitiveTypeTriangle
indexCount:indexCount
indexType:MTLIndexTypeUInt32
indexBuffer:indicies
indexBufferOffset:0];

[renderCommand endEncoding];
}
[mtlCommandBuffer presentDrawable:frameDrawable];
[mtlCommandBuffer commit];

如果您愿意,我也可以发布像素着色器,但是当我编码为一次只渲染一个对象时,着色器可以正常工作。

最佳答案

MTLRenderCommandEncoder 不对“memcpy”指令进行编码。您目前认为每个 memcpy([metal_info.g_shaderUniformInfo contents], curObj->GetUniformInfo(), curObj->curObj->GetUniformInfoSize()); 都与编码器相关联,但实际上,您只是将相同的 metal_info.g_shaderUniformInfo 与每个编码器相关联,并且着色器都在使用来自该缓冲区的数据,在提交命令缓冲区之后 – 编码器不会捕获缓冲区的副本。您注意到的关键是,此提交发生在您最后一次运行循环之后,此时 g_shaderUniformInfo 具有唯一可以有意义地使用的值。

您需要为每个对象使用不同的统一缓冲区,或者写入同一缓冲区的不同部分,然后适本地从中读取。

关于ios - 在 iOS Metal 中重用具有不同统一参数的像素着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30064625/

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