- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
是否可以将 metal
文件导入或包含到另一个 metal 文件中?假设我有一个包含所有数学函数的 Metal 文件,我只会在我的 Metal 项目中需要时包含或导入它。可能吗?
我试过:
#include "sdf.metal"
我得到了错误:
metallib: Multiply defined symbols _Z4vmaxDv2_f Command/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/usr/bin/metallib failed with exit code 1
更新:
这是我的两个着色器文件:
SDF.metal:
#ifndef MYAPP_METAL_CONSTANTS
#define MYAPP_METAL_CONSTANTS
#include <metal_stdlib>
namespace metal {
float kk(float2 v) {
return max(v.x, v.y);
}
float kkk(float3 v) {
return max(max(v.x, v.y), v.z);
}
}
#endif
和Shaders.metal:
#include <metal_stdlib>
#include "SDF.metal"
using namespace metal;
float fBoxCheap(float3 p, float3 b) { //cheap box
return kkk(abs(p) - b);
}
float map( float3 p )
{
float box2 = fBoxCheap(p-float3(0.0,3.0,0.0),float3(4.0,3.0,1.0));
return box2;
}
float3 getNormal( float3 p )
{
float3 e = float3( 0.001, 0.00, 0.00 );
float deltaX = map( p + e.xyy ) - map( p - e.xyy );
float deltaY = map( p + e.yxy ) - map( p - e.yxy );
float deltaZ = map( p + e.yyx ) - map( p - e.yyx );
return normalize( float3( deltaX, deltaY, deltaZ ) );
}
float trace( float3 origin, float3 direction, thread float3 &p )
{
float totalDistanceTraveled = 0.0;
for( int i=0; i <64; ++i)
{
p = origin + direction * totalDistanceTraveled;
float distanceFromPointOnRayToClosestObjectInScene = map( p );
totalDistanceTraveled += distanceFromPointOnRayToClosestObjectInScene;
if( distanceFromPointOnRayToClosestObjectInScene < 0.0001 )
{
break;
}
if( totalDistanceTraveled > 10000.0 )
{
totalDistanceTraveled = 0.0000;
break;
}
}
return totalDistanceTraveled;
}
float3 calculateLighting(float3 pointOnSurface, float3 surfaceNormal, float3 lightPosition, float3 cameraPosition)
{
float3 fromPointToLight = normalize(lightPosition - pointOnSurface);
float diffuseStrength = clamp( dot( surfaceNormal, fromPointToLight ), 0.0, 1.0 );
float3 diffuseColor = diffuseStrength * float3( 1.0, 0.0, 0.0 );
float3 reflectedLightVector = normalize( reflect( -fromPointToLight, surfaceNormal ) );
float3 fromPointToCamera = normalize( cameraPosition - pointOnSurface );
float specularStrength = pow( clamp( dot(reflectedLightVector, fromPointToCamera), 0.0, 1.0 ), 10.0 );
// Ensure that there is no specular lighting when there is no diffuse lighting.
specularStrength = min( diffuseStrength, specularStrength );
float3 specularColor = specularStrength * float3( 1.0 );
float3 finalColor = diffuseColor + specularColor;
return finalColor;
}
kernel void compute(texture2d<float, access::write> output [[texture(0)]],
constant float &timer [[buffer(1)]],
constant float &mousex [[buffer(2)]],
constant float &mousey [[buffer(3)]],
uint2 gid [[thread_position_in_grid]])
{
int width = output.get_width();
int height = output.get_height();
float2 uv = float2(gid) / float2(width, height);
uv = uv * 2.0 - 1.0;
// scale proportionately.
if(width > height) uv.x *= float(width)/float(height);
if(width < height) uv.y *= float(height)/float(width);
float posx = mousex * 2.0 - 1.0;
float posy = mousey * 2.0 - 1.0;
float3 cameraPosition = float3( posx * 0.01,posy * 0.01, -10.0 );
float3 cameraDirection = normalize( float3( uv.x, uv.y, 1.0) );
float3 pointOnSurface;
float distanceToClosestPointInScene = trace( cameraPosition, cameraDirection, pointOnSurface );
float3 finalColor = float3(1.0);
if( distanceToClosestPointInScene > 0.0 )
{
float3 lightPosition = float3( 5.0, 2.0, -10.0 );
float3 surfaceNormal = getNormal( pointOnSurface );
finalColor = calculateLighting( pointOnSurface, surfaceNormal, lightPosition, cameraPosition );
}
output.write(float4(float3(finalColor), 1), gid);
}
更新2:
和我的MetalView.swift
:
import MetalKit
public class MetalView: MTKView, NSWindowDelegate {
var queue: MTLCommandQueue! = nil
var cps: MTLComputePipelineState! = nil
var timer: Float = 0
var timerBuffer: MTLBuffer!
var mousexBuffer: MTLBuffer!
var mouseyBuffer: MTLBuffer!
var pos: NSPoint!
var floatx: Float!
var floaty: Float!
required public init(coder: NSCoder) {
super.init(coder: coder)
self.framebufferOnly = false
device = MTLCreateSystemDefaultDevice()
registerShaders()
}
override public func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
if let drawable = currentDrawable {
let command_buffer = queue.commandBuffer()
let command_encoder = command_buffer.computeCommandEncoder()
command_encoder.setComputePipelineState(cps)
command_encoder.setTexture(drawable.texture, atIndex: 0)
command_encoder.setBuffer(timerBuffer, offset: 0, atIndex: 1)
command_encoder.setBuffer(mousexBuffer, offset: 0, atIndex: 2)
command_encoder.setBuffer(mouseyBuffer, offset: 0, atIndex: 3)
update()
let threadGroupCount = MTLSizeMake(8, 8, 1)
let threadGroups = MTLSizeMake(drawable.texture.width / threadGroupCount.width, drawable.texture.height / threadGroupCount.height, 1)
command_encoder.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupCount)
command_encoder.endEncoding()
command_buffer.presentDrawable(drawable)
command_buffer.commit()
}
}
func registerShaders() {
queue = device!.newCommandQueue()
do {
let library = device!.newDefaultLibrary()!
let kernel = library.newFunctionWithName("compute")!
timerBuffer = device!.newBufferWithLength(sizeof(Float), options: [])
mousexBuffer = device!.newBufferWithLength(sizeof(Float), options: [])
mouseyBuffer = device!.newBufferWithLength(sizeof(Float), options: [])
cps = try device!.newComputePipelineStateWithFunction(kernel)
} catch let e {
Swift.print("\(e)")
}
}
func update() {
timer += 0.01
var bufferPointer = timerBuffer.contents()
memcpy(bufferPointer, &timer, sizeof(Float))
bufferPointer = mousexBuffer.contents()
memcpy(bufferPointer, &floatx, sizeof(NSPoint))
bufferPointer = mouseyBuffer.contents()
memcpy(bufferPointer, &floaty, sizeof(NSPoint))
}
override public func mouseDragged(event: NSEvent) {
pos = convertPointToLayer(convertPoint(event.locationInWindow, fromView: nil))
let scale = layer!.contentsScale
pos.x *= scale
pos.y *= scale
floatx = Float(pos.x)
floaty = Float(pos.y)
debugPrint("Hello",pos.x,pos.y)
}
}
更新 3
最佳答案
您的设置不正确(编辑:我在其他答案和此答案的先前版本中的设置也是如此。)
您可以像在 C++ 中一样使用 header (Metal is based on C++11, after all...)。您只需要一个文件,我将其命名为 SDF.h
。该文件包含没有命名空间声明的函数原型(prototype)声明。您需要在 using namespace metal;
其他文件中的声明之后 #include
它。确保头文件不是 .metal
文件并且它不是在 Compile Sources
列表中你的构建阶段。如果 header 被视为已编译的源代码,这很可能是导致 CompilerError
的原因。
SDF.h
:// SDFHeaders.metal
#ifndef SDF_HEADERS
#define SDF_HEADERS
float kk(float2 v);
float kkk(float3 v);
#endif
SDF.metal
:#include <metal_stdlib>
using namespace metal;
#include "SDF.h"
float kk(float2 v) {
return max(v.x, v.y);
}
float kkk(float3 v) {
return max(max(v.x, v.y), v.z);
}
Shaders.metal
:这里是你在包含SDF.h
之后使用函数的地方。
// Shaders.metal
#include <metal_stdlib>
using namespace metal;
#include "SDF.h"
float fBoxCheap(float3 p, float3 b) { //cheap box
return kkk(abs(p) - b);
}
// ...
当然,清理后构建。祝你好运!
关于ios - Metal - `include` 或 `import` 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39283565/
在 Metal 中,在着色器内部(进出)使用什么坐标系?当我们渲染到纹理时是一样的吗?也有z缓冲区?有没有不一致的地方?最后 Metal ,opengl和directX有什么区别? 最佳答案 Meta
我正在尝试在 Mac 上的 Apple metal 中开发我自己的迷你游戏引擎,但我被困在我想在 GPU 上渲染文本的地方。我没有太多的图形编程经验,因此我不知道该怎么做。我偶然发现了 Warren
我找不到答案的简单问题,在 openGL 上有一个 glDeleteTextures(1, &t) 显然模型有很大的不同,但我想知道 Metal 是否有相同的需要或要求。 MTLTexture 是通过
我是 Metal 新手。我想使用 Metal 计算来做一些数学运算,所以我创建了一个内核函数(着色器?),比方说 kernel void foo(device float *data1,
我假设除了 Metal 之外的其他 API 中存在颜色附件(我肯定知道 OpenGL),但我是图形编程的新手,我想知道颜色附件在概念上到底是什么。我所做的所有绘图都涉及在颜色附件数组中的第一个设置属性
在计算着色器中,我可以看到双三次是一个选项,但前提是定义了 __HAVE_BICUBIC_FILTERING__。当我将 bicubic 设置为过滤选项时,出现语法错误。 Linear 或Neares
这是一个绝对的初学者问题。 背景:我并不是真正的游戏开发者,但我正在努力学习底层 3D 编程的基础知识,因为这是一个有趣且有趣的话题。我选择了 Apple 的 Metal 作为图形框架。我知道 Sce
在 GLSL 中,我只需使用 out vec3 array[10]; 将数组从顶点着色器传递到片段着色器。然而,在 Metal 中,我想这样做: struct FragmentIn { flo
我看到 Apple GPU 硬件和 iOS/MacOS 版本的组合决定了一个功能集。我可以使用下面的快速代码片段查询我的 MTLDevice 支持哪些功能集。 device.supportsFeatu
我想将深度缓冲区保存到 Metal 纹理中,但我尝试过的任何方法似乎都不起作用。 _renderPassDesc.colorAttachments[1].clearColor = MTLClearCo
我想在我的 Metal 应用程序中实现一个 A-Buffer 算法来实现与订单无关的透明度。该技术的描述提到使用原子计数器。我从未使用过其中之一,甚至没有听说过。我刚刚阅读了 Metal Shadin
假设我有一个 N channel MPSImage 或基于 MTLTexture 的纹理数组。 我如何从中裁剪一个区域,复制所有 N 个 channel ,但改变“像素大小”? 最佳答案 我将只讨论裁
TL;DR:Metal 似乎没有检测到我的顶点着色器返回的内容 我有这两个用 MSL 编写的函数: vertex float4 base_image_rect(constant float4 *pos
如何在目标设置为 iOS 模拟器的情况下在 Xcode 6 中编译 iOS «Metal» 游戏? error: can't exec 'metal' (No such file or directo
将一些基本的 OpenGL ES 2.0 着色器移植到 Metal 着色器时,我不知道如何将 glsl 中的 in/inout/out 限定符转换为 Metal 着色器语言 (MSL)。例如, //O
我不想使用texture1d_array。我可以简单地传递一个 float 组吗?我将把它写入我的内核函数中。 最佳答案 为了写入内核函数内的 float 组,您需要向内核提供一个缓冲区参数。该参数应
我不想使用texture1d_array。我可以简单地传递一个 float 组吗?我将把它写入我的内核函数中。 最佳答案 为了写入内核函数内的 float 组,您需要向内核提供一个缓冲区参数。该参数应
我有一组 Metal 纹理作为纹理集存储在 Xcode Assets 目录中。我正在使用 MTKTextureLoader.newTexture(name:scaleFactor:bundle:opt
Apple 系统中似乎至少有六个矩阵库。其中之一是 simd 库,其类型在 CPU 和 GPU 代码中的工作方式相同。 import simd let mat = float3x3(...) let
有谁知道 Apple 的旧版本 Metal Feature Set Table 的可用性?文件? 当前的 Metal 3.0 文档仅引用 beta MTLGPUFamily 和 MTLSoftware
我是一名优秀的程序员,十分优秀!