这是我在OpenGL中使用的两种混合模式,即IOS中对金属的转换
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA,GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_SRC_ALPHA, GL_ONE);
Run Code Online (Sandbox Code Playgroud) func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
print("current drawable size:\(view.drawableSize)")
}
func draw(in view: MTKView) {
guard let drawable = view.currentDrawable else { return }
let textureDescriptor = MTLTextureDescriptor()
textureDescriptor.textureType = MTLTextureType.type2D
textureDescriptor.width = drawable.texture.width
textureDescriptor.height = drawable.texture.height
textureDescriptor.pixelFormat = .bgra8Unorm
textureDescriptor.storageMode = .shared
textureDescriptor.usage = .renderTarget
let sampleTexture = device.makeTexture(descriptor: textureDescriptor)
let renderPass = MTLRenderPassDescriptor()
renderPass.colorAttachments[0].texture = sampleTexture
renderPass.colorAttachments[0].loadAction = .clear
renderPass.colorAttachments[0].clearColor =
MTLClearColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)
renderPass.colorAttachments[0].storeAction = .store
let commandBuffer = commandQueue.makeCommandBuffer() …
Run Code Online (Sandbox Code Playgroud) 我正在从 obj 文件绘制一个 3D 模型,如下所示。我需要找到该 obj 文件的每个子网格物体的边界框。
let assetURL = Bundle.main.url(forResource: "train", withExtension: "obj")!
let allocator = MTKMeshBufferAllocator(device: device)
let asset = MDLAsset(url: assetURL, vertexDescriptor: vertexDescriptor, bufferAllocator: meshAllocator)
let mdlMesh = asset.object(at: 0) as! MDLMesh
mesh = try! MTKMesh(mesh: mdlMesh, device: device)
for submesh in mesh.submeshes {
//I need to find the bounding box for each Submesh
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能在 iOS 中实现这一点。
使用 Metal 我使用四个点使用贝塞尔曲线绘制线。我为线条使用了近 1500 个三角形。该线是像素化的。我怎样才能减少像素化。
vertex VertexOutBezier bezier_vertex(constant BezierParameters *allParams[[buffer(0)]],
constant GlobalParameters& globalParams[[buffer(1)]],
uint vertexId [[vertex_id]],
uint instanceId [[instance_id]])
{
float t = (float) vertexId / globalParams.elementsPerInstance;
rint(t);
BezierParameters params = allParams[instanceId];
float lineWidth = (1 - (((float) (vertexId % 2)) * 2.0)) * params.lineThickness;
float2 a = params.a;
float2 b = params.b;
float cx = distance(a , b);
float2 p1 = params.p1 * 3.0; // float2 p1 = params.p1 * 3.0;
float2 p2 = params.p2 * 3.0; // float2 …
Run Code Online (Sandbox Code Playgroud) 在Obj CI中创建了一个属性
@property(nonatomic) UILabel *subscriptionText;
Run Code Online (Sandbox Code Playgroud)
然后我为该属性UILabel创建了一个setter方法.如下
-(UILabel *)subscriptionText{
if (!_subscriptionText) {
_subscriptionText = [UILabel new];
_subscriptionText.translatesAutoresizingMaskIntoConstraints = NO;
_subscriptionText.textAlignment = NSTextAlignmentJustified;
}
return _subscriptionText;
}
Run Code Online (Sandbox Code Playgroud)
然后在viewdidload中我添加此视图
[self.view addSubview:self.subscriptionText];
Run Code Online (Sandbox Code Playgroud)
如何在Swift 4.2中执行相同的操作.
我是金属新手。我们可以在单个应用程序中创建多少个 MTLRenderpassdescriptor(任意限制)?
我想要三个 MTLRenderpassdescriptor 是否可能。一我需要根据手指位置绘制四边形。这就像离屏渲染。将会有纹理输出。
我想将输出纹理传递给另一个渲染通道描述符来处理它的颜色,这也类似于离屏渲染。这里将提供新的输出纹理
我想向屏幕呈现新的输出纹理。是否可以 ?当我创建三个渲染通道描述符时,只有两个可用。
第一次离屏渲染效果很好
let renderPass = MTLRenderPassDescriptor()
renderPass.colorAttachments[0].texture = ssTexture
renderPass.colorAttachments[0].loadAction = .clear
renderPass.colorAttachments[0].clearColor = MTLClearColorMake( 0.0, 0.0, 0.0, 0.0)
renderPass.colorAttachments[0].storeAction = .store
let commandBuffer = commandQueue.makeCommandBuffer()
var commandEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: renderPass)
for scene in scenesTool{
scene.render(commandEncoder: commandEncoder!)
}
commandEncoder?.endEncoding()
Run Code Online (Sandbox Code Playgroud)
此渲染通道描述符在调试中也不可用。
let renderPassWC = MTLRenderPassDescriptor()
renderPassWC.colorAttachments[0].texture = ssCurrentTexture
renderPassWC.colorAttachments[0].loadAction = .clear
renderPassWC.colorAttachments[0].clearColor = MTLClearColorMake( 0.0, 0.0, 0.0, 0.0)
renderPassWC.colorAttachments[0].storeAction = .store
let commandBufferWC = commandQueue.makeCommandBuffer()
let commandEncoderWC = commandBufferWC?.makeRenderCommandEncoder(descriptor: renderPassWC)
for scene in scenesWCTool{ …
Run Code Online (Sandbox Code Playgroud) fragment half4 fragmen_shader_test(WaterColorCloudOut params[[stage_in]],
texture2d<float , access::sample>cloud1 [[texture(0)]],
texture2d<half, access::sample> cloud2 [[texture(1)]],
texture2d<half, access::sample> cloud3 [[texture(2)]]
)
{
constexpr sampler defaultSampler;
float4 color1;
if(params.index == 0){
color1= float4(cloud1.sample(defaultSampler, float2(params.textureCoordinates))) * params.color ;
}
else if(params.index == 1){
color1= float4(cloud2.sample(defaultSampler, float2(params.textureCoordinates))) * params.color ;
} else{
color1= float4(cloud3.sample(defaultSampler, float2(params.textureCoordinates))) * params.color ;
}
return half4(color1);
}
Run Code Online (Sandbox Code Playgroud)
这里我使用了三个纹理,因为 If-else 条件的性能随着时间的推移而下降。我觉得如果我将纹理数组发送到着色器,则无需执行 if else 语句。在CPU中我有三个MTLTexture。如何将三个纹理绑定到一个数组并将其传递给着色器。
在CPU端我创建了三个纹理并创建了一个MTLTexture数组
var textureArray:[MTLTexture] = []
Run Code Online (Sandbox Code Playgroud)
然后我将纹理附加到该数组。在 MTLRenderCommandEncoder 中
let myRange: CountableRange = 0..<2
commandEncoder.setFragmentTextures(textureArray, range: myRange)
Run Code Online (Sandbox Code Playgroud)
在着色器中
texture2d_array<float , …
Run Code Online (Sandbox Code Playgroud)