Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/111.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 金属碎片着色器-如何根据制服为每个像素指定颜色,我可以通过绘制功能进行调整?_Ios_Metal_Fragment Shader - Fatal编程技术网

Ios 金属碎片着色器-如何根据制服为每个像素指定颜色,我可以通过绘制功能进行调整?

Ios 金属碎片着色器-如何根据制服为每个像素指定颜色,我可以通过绘制功能进行调整?,ios,metal,fragment-shader,Ios,Metal,Fragment Shader,我有一个MTKView,它正在渲染一个立方体,该立方体的大小使其一个面填充整个屏幕 我正在将一个包含随机浮点的结构变量(称为theuniforms)传递给片段着色器,并希望根据浮点值为屏幕上的每个像素着色 现在,它根据浮点值将整个四边形着色为红色或蓝色,该值在draw函数中随机化 我认为我的设置是错误的,因为在任何帧中,我只能访问一个随机浮点,并且在该帧中,所有像素都将着色(我不会使用随机浮点数组来确定像素颜色)。但是,我认为我可以简单地向struct变量添加更多变量来克服这个问题 主要问题是通

我有一个MTKView,它正在渲染一个立方体,该立方体的大小使其一个面填充整个屏幕

我正在将一个包含随机浮点的结构变量(称为theuniforms)传递给片段着色器,并希望根据浮点值为屏幕上的每个像素着色

现在,它根据浮点值将整个四边形着色为红色或蓝色,该值在draw函数中随机化

我认为我的设置是错误的,因为在任何帧中,我只能访问一个随机浮点,并且在该帧中,所有像素都将着色(我不会使用随机浮点数组来确定像素颜色)。但是,我认为我可以简单地向struct变量添加更多变量来克服这个问题

主要问题是通过片段函数访问单个像素。。。它的性能是否足以决定屏幕上每个像素的颜色

import UIKit
import MetalKit

class ViewController: UIViewController, MTKViewDelegate {
     
     var metaldevice: MTLDevice!
     var metalview: MTKView!
     var metallibrary: MTLLibrary!
     var metalqueue: MTLCommandQueue!
     var metalpipelinestate: MTLRenderPipelineState!
     var metalmesh: MTKMesh!
     
     var theuniforms = Uniforms(color: 1)
     
     struct Uniforms {
          var color = Float(1)
     }
     
     override var prefersStatusBarHidden: Bool { return true }
     override var prefersHomeIndicatorAutoHidden: Bool { return true }
     override func viewDidLoad() {
          super.viewDidLoad()

          self.view.backgroundColor = .black
          
          self.metaldevice = MTLCreateSystemDefaultDevice()
          self.metalview = MTKView()
          self.metalview.frame = UIScreen.main.bounds
          self.metalview.clearColor = MTLClearColor(red: 0, green: 0, blue: 0, alpha: 1)
          self.metalview.delegate = self
          self.metalview.device = self.metaldevice
          self.view.addSubview(self.metalview)
          
          self.metallibrary = self.metaldevice.makeDefaultLibrary()
          self.metalqueue = self.metaldevice.makeCommandQueue()
          self.metalmesh = self.returncube()
          
          let vfunc = self.metallibrary.makeFunction(name: "vertex_main")
          let ffunc = self.metallibrary.makeFunction(name: "fragment_main")
          let descriptor = MTLRenderPipelineDescriptor()
          descriptor.colorAttachments[0].pixelFormat = .bgra8Unorm
          descriptor.vertexFunction = vfunc
          descriptor.fragmentFunction = ffunc
          descriptor.vertexDescriptor = MTKMetalVertexDescriptorFromModelIO(self.metalmesh.vertexDescriptor)
          
          self.metalpipelinestate = try! self.metaldevice.makeRenderPipelineState(descriptor: descriptor)
          

     }


     func returncube() -> MTKMesh {
          let allocator = MTKMeshBufferAllocator(device: self.metaldevice)
          let model = MDLMesh(boxWithExtent: [2, 2, 2], segments: [1, 1, 1], inwardNormals: false, geometryType: .triangles, allocator: allocator)
          let mesh = try! MTKMesh(mesh: model, device: self.metaldevice)
          return mesh
     }
     
     func draw(in view: MTKView) {
          let descriptor = self.metalview.currentRenderPassDescriptor
          let buffer = self.metalqueue.makeCommandBuffer()
          let encoder = buffer?.makeRenderCommandEncoder(descriptor: descriptor!)
          encoder?.setRenderPipelineState(self.metalpipelinestate)
          
          self.theuniforms.color = Float.random(in: 1.0...2.0)
          
          encoder?.setVertexBytes(&theuniforms, length: MemoryLayout<Uniforms>.stride, index: 1)
          encoder?.setVertexBuffer(self.metalmesh.vertexBuffers[0].buffer, offset: 0, index: 0)
          for mesh in self.metalmesh.submeshes {
               encoder?.drawIndexedPrimitives(type: .triangle, indexCount: mesh.indexCount, indexType: mesh.indexType, indexBuffer: mesh.indexBuffer.buffer, indexBufferOffset: mesh.indexBuffer.offset)
          }
          
          encoder?.endEncoding()
          let drawable = self.metalview.currentDrawable
          buffer?.present(drawable!)
          buffer?.commit()
          
     }
     
     func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
          
     }
}


导入UIKit
进口金属套件
类ViewController:UIViewController、MTKViewDelegate{
var metaldevice:MTLDevice!
var metalview:MTKView!
var metallibrary:MTLLibrary!
var metalqueue:MTLCommandQueue!
var metalpipelinestate:MTLRenderPipelineState!
var metalmesh:MTKMesh!
制服=制服(颜色:1)
结构制服{
变量颜色=浮动(1)
}
重写变量prefersStatusBarHidden:Bool{return true}
重写变量prefersHomeIndicatorAutoHidden:Bool{return true}
重写func viewDidLoad(){
super.viewDidLoad()
self.view.backgroundColor=.black
self.metaldevice=MTLCreateSystemDefaultDevice()
self.metalview=MTKView()
self.metalview.frame=UIScreen.main.bounds
self.metalview.clearColor=MTLClearColor(红色:0,绿色:0,蓝色:0,alpha:1)
self.metalview.delegate=self
self.metalview.device=self.metalview.device
self.view.addSubview(self.metalview)
self.metallibrary=self.metaldevice.makeDefaultLibrary()
self.metalqueue=self.metaldevice.makeCommandQueue()
self.metalmesh=self.returncube()
让vfunc=self.metalibrary.makeFunction(名称:“vertex_main”)
让ffunc=self.metalibrary.makeFunction(名称:“fragment\u main”)
let descriptor=MTLRenderPipelineDescriptor()
descriptor.colorAttachments[0]。像素格式=.bgra8Unorm
descriptor.vertexFunction=vfunc
descriptor.fragmentFunction=ffunc
descriptor.vertexDescriptor=MTKMetalVertexDescriptorFromModelIO(self.metalmesh.vertexDescriptor)
self.metalpipelinestate=try!self.metaldevice.makeRenderPipelineState(描述符:描述符)
}
func returncube()->MTKMesh{
let allocator=MTKMeshBufferAllocator(设备:self.metaldevice)
让model=MDLMesh(boxWithExtent:[2,2,2],segments:[1,1,1],向内法线:false,geometryType:。三角形,分配器:分配器)
让mesh=try!MTKMesh(mesh:model,device:self.metaldevice)
回流网
}
func绘图(视图中:MTKView){
让描述符=self.metalview.currentRenderPassDescriptor
让buffer=self.metalqueue.makeCommandBuffer()
让编码器=缓冲区?.makeRenderCommandEncoder(描述符:描述符!)
编码器?.setRenderPipelineState(self.metalpipelinestate)
self.theuniforms.color=Float.random(in:1.0…2.0)
编码器?.setVertexBytes(&theuniforms,长度:MemoryLayout.stride,索引:1)
编码器?.setVertexBuffer(self.metalmesh.vertexBuffers[0]。缓冲区,偏移量:0,索引:0)
对于self.metalmesh.subshees中的网格{
编码器?.drawIndexedPrimitives(类型:。三角形,indexCount:mesh.indexCount,indexType:mesh.indexType,indexBuffer:mesh.indexBuffer.buffer,indexBufferOffset:mesh.indexBuffer.offset)
}
编码器?.endEncoding()
设drawable=self.metalview.currentDrawable
缓冲区?存在(可抽出!)
缓冲区?.commit()
}
func mtkView(view:mtkView,drawableSizeWillChange size:CGSize){
}
}
以下是着色器代码

#include <metal_stdlib>
using namespace metal;
#include <simd/simd.h>

struct VertexIn {
     float4 position [[attribute(0)]];
};

struct Uniforms {
     float color;
};

struct VertexOut {
     float4 position [[position]];
     Uniforms uniforms;
};

vertex VertexOut vertex_main(const VertexIn in [[stage_in]],
                          constant Uniforms &uniforms [[buffer(1)]]
                          )
{
     VertexOut out;
     out.position = in.position;
     out.uniforms = uniforms;
     return out;
}

fragment float4 fragment_main( VertexOut in [[stage_in]])
{
     
     float4 color;
     
     if (in.uniforms.color > 1.5){ color = float4(1, 0, 0, 1); }
     else { color = float4(0, 0, 1, 1); }
     return color;
}
#包括
使用金属;
#包括
结构蛋白{
浮动4位置[[属性(0)];
};
结构制服{
浮色;
};
结构顶点输出{
浮动4位[[位]];
制服;
};
顶点顶点顶点输出顶点主(常量顶点位于[[stage_in]],
固定制服和制服[[缓冲区(1)]]
)
{
垂直输出;
out.position=in.position;
制服=制服;
返回;
}
片段浮动4片段\u主(顶点输出在[[阶段\u在]]中)
{
4色;
如果(in.uniforms.color>1.5){color=float4(1,0,0,1);}
else{color=float4(0,0,1,1);}
返回颜色;
}

首先,您不应该使用制服来更改CPU过载时每个像素的颜色,但这是一项GPU任务,因此您应该在着色器中使用一些功能。如果您想相应地更改片段的颜色,则必须将其传递到片段函数
setFragmentBytes(&theuniforms,length:MemoryLayout.stride,index:1)
,并在片段函数中调用它。如果我没弄错,你希望立方体上有白噪声,这是着色器:

#include <metal_stdlib>
using namespace metal;
#include <simd/simd.h>

struct VertexIn {
     float4 position [[attribute(0)]];
};

struct Uniforms {
     float color;
};

struct VertexOut {
     float4 position [[position]];
};

vertex VertexOut vertex_main(const VertexIn in [[stage_in]])
{
     VertexOut out;
     out.position = in.position;
   
     return out;
}



float rand(float2 co)
{
    return fract(sin(dot(co.xy ,float2(12.9898,78.236))) * 43758.5453);
}


fragment float4 fragment_main( VertexOut in [[stage_in]],constant Uniforms &uniforms [[buffer(1)]])
{
              
                                                                                      
     float2 pos = in.position.xy;
     
     float4 color = float4(rand(pos));
     
     //if (in.uniforms.color > 1.5){ color = float4(1, 0, 0, 1); }
     //else { color = float4(0, 0, 1, 1); }
     return color;
}

#包括
使用金属;
#包括
结构蛋白{
浮动4位置[[属性(0)];
};
结构制服{
浮色;
};
结构顶点输出{
浮动4位[[位]];
};
顶点顶点顶点输出顶点主(常量顶点位于[[stage_in]]
{
垂直输出;
外置