diff --git a/Sources/Voxelotl/Renderer/Renderer.swift b/Sources/Voxelotl/Renderer/Renderer.swift index 7d2a93a..25c2a9d 100644 --- a/Sources/Voxelotl/Renderer/Renderer.swift +++ b/Sources/Voxelotl/Renderer/Renderer.swift @@ -353,9 +353,9 @@ public class Renderer { var fragUniforms = FragmentShaderUniforms( cameraPosition: camera.position, directionalLight: normalize(environment.lightDirection), - ambientColor: SIMD4(Color(material.ambient)), - diffuseColor: SIMD4(Color(material.diffuse)), - specularColor: SIMD4(Color(material.specular)), + ambientColor: material.ambient.reinterpretUShort, + diffuseColor: material.diffuse.reinterpretUShort, + specularColor: material.specular.reinterpretUShort, specularIntensity: material.gloss) let numInstances = instances.count @@ -384,7 +384,7 @@ public class Renderer { .scale(instance.scale) data[i] = VertexShaderInstance( model: model, normalModel: model.inverse.transpose, - color: SIMD4(Color(instance.color))) + color: instance.color.reinterpretUShort) } } instanceBuffer.didModifyRange(0.. { + .init(self.r.bitPattern, self.g.bitPattern, self.b.bitPattern, self.a.bitPattern) + } +} + enum RendererError: Error { case initFailure(_ message: String) case loadFailure(_ message: String) diff --git a/Sources/Voxelotl/shader.metal b/Sources/Voxelotl/shader.metal index ab4c6f6..db6f8be 100644 --- a/Sources/Voxelotl/shader.metal +++ b/Sources/Voxelotl/shader.metal @@ -45,18 +45,18 @@ fragment half4 fragmentMain( // Compute diffuse component float lambert = metal::dot(normal, lightVec); float diffuseAmount = metal::max(0.0, lambert); - half4 diffuse = half4(u.diffuseColor) * diffuseAmount; + half4 diffuse = u.diffuseColor * diffuseAmount; // Compute specular component (blinn-phong) float specularAngle = metal::max(0.0, metal::dot(halfDir, normal)); float specularTerm = metal::pow(specularAngle, u.specularIntensity); // smoothstep hack to ensure highlight tapers gracefully at grazing angles float specularAmount = specularTerm * metal::smoothstep(0, 2, lambert * u.specularIntensity); - half4 specular = half4(u.specularColor) * specularAmount; + half4 specular = u.specularColor * specularAmount; // Sample texture & vertex color to get albedo half4 albedo = texture.sample(sampler, in.texCoord); albedo *= in.color; - return albedo * (half4(u.ambientColor) + diffuse) + specular; + return albedo * (u.ambientColor + diffuse) + specular; } diff --git a/Sources/Voxelotl/shadertypes.h b/Sources/Voxelotl/shadertypes.h index f316a62..fb8c84d 100644 --- a/Sources/Voxelotl/shadertypes.h +++ b/Sources/Voxelotl/shadertypes.h @@ -10,6 +10,13 @@ #include +// HACK: allow passing SIMD4 to shader while `simd_half4` is beta +#ifdef __METAL_VERSION__ +typedef half4 color_half4; +#else +typedef simd_ushort4 color_half4; +#endif + typedef NS_ENUM(NSInteger, VertexShaderInputIdx) { VertexShaderInputIdxVertices = 0, VertexShaderInputIdxInstance = 1, @@ -25,7 +32,7 @@ typedef struct { typedef struct { matrix_float4x4 model; matrix_float4x4 normalModel; - vector_float4 color; + color_half4 color; } VertexShaderInstance; typedef struct { @@ -38,7 +45,7 @@ typedef NS_ENUM(NSInteger, FragmentShaderInputIdx) { typedef struct { vector_float3 cameraPosition, directionalLight; - vector_float4 ambientColor, diffuseColor, specularColor; + color_half4 ambientColor, diffuseColor, specularColor; float specularIntensity; } FragmentShaderUniforms;