For Chapter 11 can I do something like this?
This is my Scene:
class TesselationScene: Scene {
let model = Model(vertices: [
[-1, 0, 1],
[ 1, 0, -1],
[-1, 0, -1],
[-1, 0, 1],
[ 1, 0, -1],
[ 1, 0, 1]
], vertexFunction: "vertex_basic", fragmentFunction: "fragment_basic")
let arcBallCamera: Camera = {
let camera = ArcballCamera()
camera.distance = 8
camera.target = [0, 0, 0]
camera.rotation.x = Float(-15).degreesToRadians
camera.rotation.y = Float(-105).degreesToRadians
return camera
}()
override func setupScene() {
[model].forEach { add(node: $0) }
inputController.keyboardDelegate = self
cameras = [arcBallCamera]
}
}
Now I made an extra init on Model:
init(vertices: [float3], vertexFunction: String = "vertex_main", fragmentFunction: String = "fragment_mainPBR", position: float3 = [0, 0, 0], rotation: float3 = [0, 0, 0], scale: float3 = [1, 1 ,1], tiling: UInt32 = 1, transparencyEnabled: Bool = true, blendingEnabled: Bool = false) {
self.tiling = tiling
self.blendingEnabled = blendingEnabled
self.transparencyEnabled = transparencyEnabled
let allocator = MTKMeshBufferAllocator(device: Renderer.device)
let vertexBuffer = allocator.newBuffer(MemoryLayout<float3>.stride * vertices.count, type: .vertex)
let vertexMap = vertexBuffer.map()
vertexMap.bytes.assumingMemoryBound(to: float3.self).assign(from: vertices, count: vertices.count)
let indices: [UInt16] = (UInt16(0)..<UInt16(vertices.count)).map { $0 }
let indexBuffer = allocator.newBuffer(MemoryLayout<UInt16>.stride * indices.count, type: .index)
let indexMap = indexBuffer.map()
indexMap.bytes.assumingMemoryBound(to: UInt16.self).assign(from: indices, count: indices.count)
let submesh = MDLSubmesh(indexBuffer: indexBuffer,
indexCount: indices.count,
indexType: .uInt16,
geometryType: .triangles,
material: nil)
let vertexDescriptor = MDLVertexDescriptor()
vertexDescriptor.attributes[0] = MDLVertexAttribute(name: MDLVertexAttributePosition,
format: .float2,
offset: 0,
bufferIndex: 0)
let mdlMesh = MDLMesh(vertexBuffer: vertexBuffer,
vertexCount: vertices.count,
descriptor: vertexDescriptor,
submeshes: [submesh])
var mtkMeshes: [MTKMesh] = []
let mdlMeshes = [mdlMesh]
mdlMeshes.forEach { mdlMesh in
mdlMesh.addTangentBasis(forTextureCoordinateAttributeNamed: MDLVertexAttributeTextureCoordinate,
tangentAttributeNamed: MDLVertexAttributeTangent,
bitangentAttributeNamed: MDLVertexAttributeBitangent)
Model.vertexDescriptor = mdlMesh.vertexDescriptor
guard let mtkMesh = try? MTKMesh(mesh: mdlMesh, device: Renderer.device) else { return }
mtkMeshes.append(mtkMesh)
}
meshes = zip(mdlMeshes, mtkMeshes).map {
Mesh(mdlMesh: $0.0,
mtkMesh: $0.1,
startTime: .zero,
endTime: .zero,
vertexFunctionName: vertexFunction,
fragmentFunctionName: fragmentFunction,
blendingEnabled: blendingEnabled)
}
self.samplerState = Model.buildSamplerState()
debugBoundingBox = DebugBoundingBox(boundingBox: mdlMesh.boundingBox)
self.animations = [:]
super.init(name: "VerticesModel", position: position, rotation: rotation, scale: scale, boundingBox: mdlMesh.boundingBox)
}
Shading:
struct VertexIn {
float4 position [[attribute(Position)]];
float3 normal [[attribute(Normal)]];
float2 uv [[attribute(UV)]];
float3 tangent [[attribute(Tangent)]];
float3 bitangent [[attribute(Bitangent)]];
ushort4 joints [[attribute(Joints)]];
float4 weights [[attribute(Weights)]];
};
struct VertexOut {
float4 position [[position]];
float3 worldPosition;
float3 worldNormal;
float3 worldTangent;
float3 worldBitangent;
float2 uv;
};
vertex VertexOut vertex_basic(const VertexIn vertexIn [[stage_in]],
constant float4x4 *jointMatrices [[buffer(22), function_constant(hasSkeleton)]],
constant Uniforms &uniforms [[buffer(BufferIndexUniforms)]])
{
float4 position = vertexIn.position;
float4 normal = float4(vertexIn.normal, 0);
VertexOut out {
.position = uniforms.projectionMatrix * uniforms.viewMatrix * uniforms.modelMatrix * position,
.worldPosition = (uniforms.modelMatrix * position).xyz,
.worldNormal = uniforms.normalMatrix * normal.xyz,
.worldTangent = uniforms.normalMatrix * vertexIn.tangent,
.worldBitangent = uniforms.normalMatrix * vertexIn.bitangent,
.uv = vertexIn.uv
};
return out;
}
fragment float4 fragment_basic(VertexOut in [[stage_in]],
constant Light *lights [[buffer(BufferIndexLights)]],
constant Material &material [[buffer(BufferIndexMaterials)]],
sampler textureSampler [[sampler(0)]],
constant FragmentUniforms &fragmentUniforms [[buffer(BufferIndexFragmentUniforms)]],
texture2d<float> baseColorTexture [[texture(0), function_constant(hasColorTexture)]],
texture2d<float> normalTexture [[texture(1), function_constant(hasNormalTexture)]],
texture2d<float> roughnessTexture [[texture(2), function_constant(hasRoughnessTexture)]],
texture2d<float> metallicTexture [[texture(3), function_constant(hasMetallicTexture)]],
texture2d<float> aoTexture [[texture(4), function_constant(hasAOTexture)]],
constant bool &transparencyEnabled [[buffer(BufferIndexTransparency)]],
constant bool &blendingEnabled [[buffer(BufferIndexBlending)]],
constant bool &fogEnabled [[buffer(BufferIndexFog)]]){
return float4(0, 0, 1, 1);
}
Unfortunately this is telling me Failed to set (contentViewController) user defined inspected property on (NSWindow): Must provide texture coordinates
But I am confused about what this actually means.
It shows a blank screen without the possibility to use the GPU debugger