From 42244456c93ab11c569fe8b62d3f59a025ccc983 Mon Sep 17 00:00:00 2001 From: a dinosaur Date: Mon, 2 Sep 2024 19:06:16 +1000 Subject: [PATCH] restore halfs in shader --- Sources/Voxelotl/Renderer/Renderer.swift | 29 ++++++++---------------- Sources/Voxelotl/shader.metal | 16 ++++++------- Sources/Voxelotl/shadertypes.h | 8 +++---- 3 files changed, 20 insertions(+), 33 deletions(-) diff --git a/Sources/Voxelotl/Renderer/Renderer.swift b/Sources/Voxelotl/Renderer/Renderer.swift index a00f40d..04869a7 100644 --- a/Sources/Voxelotl/Renderer/Renderer.swift +++ b/Sources/Voxelotl/Renderer/Renderer.swift @@ -167,7 +167,7 @@ public class Renderer { let color = Color.white let vertices = mesh.vertices.map { - ShaderVertex(position: $0.position, normal: $0.normal, color: color.values, texCoord: $0.texCoord) + ShaderVertex(position: $0.position, normal: $0.normal, color: SIMD4(color), texCoord: $0.texCoord) } guard let vtxBuffer = self.device.makeBuffer( bytes: vertices, @@ -348,14 +348,14 @@ public class Renderer { var fragUniforms = FragmentShaderUniforms( cameraPosition: camera.position, directionalLight: normalize(environment.lightDirection), - ambientColor: material.ambient.values, - diffuseColor: material.diffuse.values, - specularColor: material.specular.values, + ambientColor: SIMD4(material.ambient), + diffuseColor: SIMD4(material.diffuse), + specularColor: SIMD4(material.specular), specularIntensity: material.gloss) var instance = VertexShaderInstance( model: model, normalModel: model.inverse.transpose, - color: color.values) + color: SIMD4(color)) self._encoder.setCullMode(.init(environment.cullFace)) @@ -386,9 +386,9 @@ public class Renderer { var fragUniforms = FragmentShaderUniforms( cameraPosition: camera.position, directionalLight: normalize(environment.lightDirection), - ambientColor: material.ambient.values, - diffuseColor: material.diffuse.values, - specularColor: material.specular.values, + ambientColor: SIMD4(material.ambient), + diffuseColor: SIMD4(material.diffuse), + specularColor: SIMD4(material.specular), specularIntensity: material.gloss) let numInstances = instances.count @@ -417,7 +417,7 @@ public class Renderer { .scale(instance.scale) data[i] = VertexShaderInstance( model: model, normalModel: model.inverse.transpose, - color: instance.color.values) + color: SIMD4(instance.color)) } } instanceBuffer.didModifyRange(0.. { - .init(self.r.bitPattern, self.g.bitPattern, self.b.bitPattern, self.a.bitPattern) - } -} -fileprivate extension SIMD4 where Scalar == Float { - var reinterpretUShort: SIMD4 { - .init(self.x.bitPattern, self.y.bitPattern, self.z.bitPattern, self.w.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 63bc5c3..4614d17 100644 --- a/Sources/Voxelotl/shader.metal +++ b/Sources/Voxelotl/shader.metal @@ -7,7 +7,7 @@ struct FragmentInput { float3 world; float3 normal; float2 texCoord; - float4 color; + half4 color; }; vertex FragmentInput vertexMain( @@ -23,13 +23,13 @@ vertex FragmentInput vertexMain( FragmentInput out; out.position = u.projView * world; out.world = world.xyz; - out.color = vtx[vertexID].color * i[instanceID].color; + out.color = half4(vtx[vertexID].color) * half4(i[instanceID].color); out.normal = (i[instanceID].normalModel * float4(vtx[vertexID].normal, 0)).xyz; out.texCoord = vtx[vertexID].texCoord; return out; } -fragment float4 fragmentMain( +fragment half4 fragmentMain( FragmentInput in [[stage_in]], metal::texture2d texture [[texture(0)]], constant FragmentShaderUniforms& u [[buffer(FragmentShaderInputIdxUniforms)]] @@ -45,18 +45,18 @@ fragment float4 fragmentMain( // Compute diffuse component float lambert = metal::dot(normal, lightVec); float diffuseAmount = metal::max(0.0, lambert); - float4 diffuse = u.diffuseColor * diffuseAmount; + half4 diffuse = half4(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); - float4 specular = u.specularColor * specularAmount; + half4 specular = half4(u.specularColor) * specularAmount; // Sample texture & vertex color to get albedo - float4 albedo = float4(texture.sample(sampler, in.texCoord)); - albedo *= in.color; + half4 albedo = texture.sample(sampler, in.texCoord); + albedo *= half4(in.color); - return albedo * (u.ambientColor + diffuse) + specular; + return albedo * (half4(u.ambientColor) + diffuse) + specular; } diff --git a/Sources/Voxelotl/shadertypes.h b/Sources/Voxelotl/shadertypes.h index 63330e6..0a9ef3d 100644 --- a/Sources/Voxelotl/shadertypes.h +++ b/Sources/Voxelotl/shadertypes.h @@ -10,8 +10,6 @@ #include -typedef simd_float4 color_float4; - typedef NS_ENUM(NSInteger, VertexShaderInputIdx) { VertexShaderInputIdxVertices = 0, VertexShaderInputIdxInstance = 1, @@ -21,14 +19,14 @@ typedef NS_ENUM(NSInteger, VertexShaderInputIdx) { typedef struct { vector_float3 position; vector_float3 normal; - color_float4 color; + vector_float4 color; vector_float2 texCoord; } ShaderVertex; typedef struct { matrix_float4x4 model; matrix_float4x4 normalModel; - color_float4 color; + vector_float4 color; } VertexShaderInstance; typedef struct { @@ -41,7 +39,7 @@ typedef NS_ENUM(NSInteger, FragmentShaderInputIdx) { typedef struct { vector_float3 cameraPosition, directionalLight; - color_float4 ambientColor, diffuseColor, specularColor; + vector_float4 ambientColor, diffuseColor, specularColor; float specularIntensity; } FragmentShaderUniforms;