diff --git a/Terrain2/Renderer.swift b/Terrain2/Renderer.swift index 03e5733..6838a3b 100644 --- a/Terrain2/Renderer.swift +++ b/Terrain2/Renderer.swift @@ -61,7 +61,7 @@ class Renderer: NSObject, MTKViewDelegate { metalKitView.colorPixelFormat = MTLPixelFormat.bgra8Unorm_srgb metalKitView.sampleCount = 1 - terrain = Terrain(dimensions: float2(8, 8), segments: uint2(20, 20), device: device)! + terrain = Terrain(dimensions: float2(10, 10), segments: uint2(100, 100), device: device)! do { pipelineState = try Renderer.buildRenderPipelineWithDevice(device: device, @@ -145,11 +145,11 @@ class Renderer: NSObject, MTKViewDelegate { uniforms[0].projectionMatrix = projectionMatrix - let rotationAxis = float3(1, 1, 0) + let rotationAxis = float3(0, 1, 0) let modelMatrix = matrix4x4_rotation(radians: rotation, axis: rotationAxis) - let viewMatrix = matrix4x4_translation(0.0, 0.0, -8.0) + let viewMatrix = matrix4x4_translation(0.0, -2.0, -8.0) uniforms[0].modelViewMatrix = simd_mul(viewMatrix, modelMatrix) - rotation += 0.01 + rotation += 0.0025 } func draw(in view: MTKView) { @@ -203,7 +203,7 @@ class Renderer: NSObject, MTKViewDelegate { } } - renderEncoder.setVertexTexture(terrain.heights, index: 0) + renderEncoder.setVertexTexture(terrain.heightMap, index: 0) renderEncoder.setFragmentTexture(colorMap, index: TextureIndex.color.rawValue) for submesh in terrain.mesh.submeshes { diff --git a/Terrain2/Shaders.metal b/Terrain2/Shaders.metal index e59000d..e50422f 100644 --- a/Terrain2/Shaders.metal +++ b/Terrain2/Shaders.metal @@ -33,14 +33,13 @@ vertex ColorInOut vertexShader(Vertex in [[stage_in]], texture2d heights [[texture(0)]], constant Uniforms & uniforms [[buffer(BufferIndexUniforms)]]) { - constexpr sampler s(coord::pixel, address::clamp_to_zero, filter::linear); + constexpr sampler s(coord::normalized, address::clamp_to_zero, filter::linear); ColorInOut out; - // TODO: Concerned about this. - uint2 gridCoord(in.texCoord.x * heights.get_width(), in.texCoord.y * heights.get_height()); - float4 height = heights.read(gridCoord).rrrr; + float4 height = heights.sample(s, in.texCoord); + // Replace the y coordinate with the height we read from the texture. float4 position(in.position.x, height.r, in.position.z, 1.0); out.position = uniforms.projectionMatrix * uniforms.modelViewMatrix * position; out.texCoord = in.texCoord; @@ -58,5 +57,5 @@ fragment float4 fragmentShader(ColorInOut in [[stage_in]], half4 colorSample = colorMap.sample(colorSampler, in.texCoord.xy); - return float4(colorSample); + return float4(1.0); } diff --git a/Terrain2/Terrain.swift b/Terrain2/Terrain.swift index 58be84c..12ee6eb 100644 --- a/Terrain2/Terrain.swift +++ b/Terrain2/Terrain.swift @@ -70,9 +70,12 @@ class Terrain: NSObject { return try MTKMesh(mesh:plane, device:device) } - class func buildHeightsTexture(dimensions: uint2, device: MTLDevice) -> MTLTexture? { - let heightsDesc = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .r32Float, width: Int(dimensions.x), height: Int(dimensions.y), mipmapped: false) + private static let heightMapSize = MTLSize(width: 512, height: 512, depth: 1) + + class func buildHeightsTexture(device: MTLDevice) -> MTLTexture? { + let heightsDesc = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .r32Float, width: heightMapSize.width, height: heightMapSize.height, mipmapped: false) heightsDesc.usage = [.shaderRead, .shaderWrite] + let tex = device.makeTexture(descriptor: heightsDesc) if let tex = tex { @@ -96,7 +99,7 @@ class Terrain: NSObject { let segments: uint2 let vertexDescriptor: MTLVertexDescriptor let mesh: MTKMesh - let heights: MTLTexture + let heightMap: MTLTexture init?(dimensions dim: float2, segments seg: uint2, device: MTLDevice) { dimensions = dim @@ -110,12 +113,11 @@ class Terrain: NSObject { return nil } - let heightsDimensions = segments - guard let tex = Terrain.buildHeightsTexture(dimensions: heightsDimensions, device: device) else { + guard let tex = Terrain.buildHeightsTexture(device: device) else { print("Couldn't create heights texture") return nil } - heights = tex + heightMap = tex super.init() }