diff --git a/Sources/Voxelotl/Renderer.swift b/Sources/Voxelotl/Renderer.swift index 6f5a254..01b886f 100644 --- a/Sources/Voxelotl/Renderer.swift +++ b/Sources/Voxelotl/Renderer.swift @@ -321,9 +321,7 @@ public class Renderer { encoder.setRenderPipelineState(pso) encoder.setDepthStencilState(depthStencilState) encoder.setFragmentTexture(cubeTexture ?? defaultTexture, index: 0) - encoder.setVertexBuffer(vtxBuffer, - offset: 0, - index: ShaderInputIdx.vertices.rawValue) + encoder.setVertexBuffer(vtxBuffer, offset: 0, index: VertexShaderInputIdx.vertices.rawValue) self._encoder = encoder frameFunc(self) @@ -342,31 +340,30 @@ public class Renderer { func batch(instances: [Instance], camera: Camera) { assert(self._encoder != nil, "batch can't be called outside of a frame being rendered") - assert(instances.count < 52) + assert(instances.count < 28) - var uniforms = ShaderUniforms( - projView: camera.viewProjection, - directionalLight: normalize(.init(0.75, -1, 0.5))) - let instances = instances.map { (instance: Instance) -> ShaderInstance in + var vertUniforms = VertexShaderUniforms(projView: camera.viewProjection) + var fragUniforms = FragmentShaderUniforms(directionalLight: normalize(.init(0.75, -1, 0.5))) + let instances = instances.map { (instance: Instance) -> VertexShaderInstance in let model = .translate(instance.position) * matrix_float4x4(instance.rotation) * .scale(instance.scale) - return ShaderInstance( + return VertexShaderInstance( model: model, normalModel: model.inverse.transpose, color: SIMD4(Color(instance.color))) } // Ideal as long as our uniforms total 4 KB or less self._encoder.setVertexBytes(instances, - length: instances.count * MemoryLayout.stride, - index: ShaderInputIdx.instance.rawValue) - self._encoder.setVertexBytes(&uniforms, - length: MemoryLayout.stride, - index: ShaderInputIdx.uniforms.rawValue) - self._encoder.setFragmentBytes(&uniforms, - length: MemoryLayout.stride, - index: ShaderInputIdx.uniforms.rawValue) + length: instances.count * MemoryLayout.stride, + index: VertexShaderInputIdx.instance.rawValue) + self._encoder.setVertexBytes(&vertUniforms, + length: MemoryLayout.stride, + index: VertexShaderInputIdx.uniforms.rawValue) + self._encoder.setFragmentBytes(&fragUniforms, + length: MemoryLayout.stride, + index: FragmentShaderInputIdx.uniforms.rawValue) self._encoder.drawIndexedPrimitives( type: .triangle, diff --git a/Sources/Voxelotl/shader.metal b/Sources/Voxelotl/shader.metal index 4a036fa..de9d58e 100644 --- a/Sources/Voxelotl/shader.metal +++ b/Sources/Voxelotl/shader.metal @@ -12,9 +12,9 @@ struct FragmentInput { vertex FragmentInput vertexMain( uint vertexID [[vertex_id]], uint instanceID [[instance_id]], - device const ShaderVertex* vtx [[buffer(ShaderInputIdxVertices)]], - device const ShaderInstance* i [[buffer(ShaderInputIdxInstance)]], - constant ShaderUniforms& u [[buffer(ShaderInputIdxUniforms)]] + device const ShaderVertex* vtx [[buffer(VertexShaderInputIdxVertices)]], + device const VertexShaderInstance* i [[buffer(VertexShaderInputIdxInstance)]], + constant VertexShaderUniforms& u [[buffer(VertexShaderInputIdxUniforms)]] ) { auto position = vtx[vertexID].position; auto world = i[instanceID].model * position; @@ -31,7 +31,7 @@ vertex FragmentInput vertexMain( fragment half4 fragmentMain( FragmentInput in [[stage_in]], metal::texture2d texture [[texture(0)]], - constant ShaderUniforms& u [[buffer(ShaderInputIdxUniforms)]] + constant FragmentShaderUniforms& u [[buffer(FragmentShaderInputIdxUniforms)]] ) { constexpr metal::sampler sampler(metal::address::repeat, metal::filter::nearest); auto normal = metal::normalize(in.normal); diff --git a/Sources/Voxelotl/shadertypes.h b/Sources/Voxelotl/shadertypes.h index 45e5d76..1448c47 100644 --- a/Sources/Voxelotl/shadertypes.h +++ b/Sources/Voxelotl/shadertypes.h @@ -10,10 +10,10 @@ #include -typedef NS_ENUM(NSInteger, ShaderInputIdx) { - ShaderInputIdxVertices = 0, - ShaderInputIdxInstance = 1, - ShaderInputIdxUniforms = 2 +typedef NS_ENUM(NSInteger, VertexShaderInputIdx) { + VertexShaderInputIdxVertices = 0, + VertexShaderInputIdxInstance = 1, + VertexShaderInputIdxUniforms = 2 }; typedef struct { @@ -26,11 +26,18 @@ typedef struct { matrix_float4x4 model; matrix_float4x4 normalModel; vector_uchar4 color; -} ShaderInstance; +} VertexShaderInstance; typedef struct { matrix_float4x4 projView; +} VertexShaderUniforms; + +typedef NS_ENUM(NSInteger, FragmentShaderInputIdx) { + FragmentShaderInputIdxUniforms = 0 +}; + +typedef struct { vector_float3 directionalLight; -} ShaderUniforms; +} FragmentShaderUniforms; #endif//SHADERTYPES_H