mirror of
				https://github.com/GayPizzaSpecifications/voxelotl-engine.git
				synced 2025-11-04 10:59:39 +00:00 
			
		
		
		
	RIP to Float16, it's sad that Intel doesn't support you.
This commit is contained in:
		@ -123,7 +123,7 @@ public struct Chunk: Hashable {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public enum BlockType: Hashable {
 | 
					public enum BlockType: Hashable {
 | 
				
			||||||
  case air
 | 
					  case air
 | 
				
			||||||
  case solid(_ color: Color<Float16>)
 | 
					  case solid(_ color: Color<Float>)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public struct Block: Hashable {
 | 
					public struct Block: Hashable {
 | 
				
			||||||
 | 
				
			|||||||
@ -4,13 +4,13 @@ struct Instance {
 | 
				
			|||||||
  let position: SIMD3<Float>
 | 
					  let position: SIMD3<Float>
 | 
				
			||||||
  let scale: SIMD3<Float>
 | 
					  let scale: SIMD3<Float>
 | 
				
			||||||
  let rotation: simd_quatf
 | 
					  let rotation: simd_quatf
 | 
				
			||||||
  let color: Color<Float16>
 | 
					  let color: Color<Float>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init(
 | 
					  init(
 | 
				
			||||||
    position: SIMD3<Float> = .zero,
 | 
					    position: SIMD3<Float> = .zero,
 | 
				
			||||||
    scale: SIMD3<Float> = .one,
 | 
					    scale: SIMD3<Float> = .one,
 | 
				
			||||||
    rotation: simd_quatf = .identity,
 | 
					    rotation: simd_quatf = .identity,
 | 
				
			||||||
    color: Color<Float16> = .white
 | 
					    color: Color<Float> = .white
 | 
				
			||||||
  ) {
 | 
					  ) {
 | 
				
			||||||
    self.position = position
 | 
					    self.position = position
 | 
				
			||||||
    self.scale = scale
 | 
					    self.scale = scale
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
public struct Material {
 | 
					public struct Material {
 | 
				
			||||||
  public var ambient: Color<Float16>
 | 
					  public var ambient: Color<Float>
 | 
				
			||||||
  public var diffuse: Color<Float16>
 | 
					  public var diffuse: Color<Float>
 | 
				
			||||||
  public var specular: Color<Float16>
 | 
					  public var specular: Color<Float>
 | 
				
			||||||
  public var gloss: Float
 | 
					  public var gloss: Float
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,6 +18,6 @@ public struct VertexPositionNormalTexcoord: Vertex {
 | 
				
			|||||||
public struct VertexPositionNormalColorTexcoord: Vertex {
 | 
					public struct VertexPositionNormalColorTexcoord: Vertex {
 | 
				
			||||||
  var position: SIMD3<Float>
 | 
					  var position: SIMD3<Float>
 | 
				
			||||||
  var normal:   SIMD3<Float>
 | 
					  var normal:   SIMD3<Float>
 | 
				
			||||||
  var color:    SIMD4<Float16>
 | 
					  var color:    SIMD4<Float>
 | 
				
			||||||
  var texCoord: SIMD2<Float>
 | 
					  var texCoord: SIMD2<Float>
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -141,7 +141,7 @@ public class Renderer {
 | 
				
			|||||||
    if mesh.vertices.isEmpty || mesh.indices.isEmpty { return nil }
 | 
					    if mesh.vertices.isEmpty || mesh.indices.isEmpty { return nil }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let vertices = mesh.vertices.map {
 | 
					    let vertices = mesh.vertices.map {
 | 
				
			||||||
      ShaderVertex(position: $0.position, normal: $0.normal, color: $0.color.reinterpretUShort, texCoord: $0.texCoord)
 | 
					      ShaderVertex(position: $0.position, normal: $0.normal, color: $0.color, texCoord: $0.texCoord)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    guard let vtxBuffer = self.device.makeBuffer(
 | 
					    guard let vtxBuffer = self.device.makeBuffer(
 | 
				
			||||||
      bytes: vertices,
 | 
					      bytes: vertices,
 | 
				
			||||||
@ -165,9 +165,9 @@ public class Renderer {
 | 
				
			|||||||
  func createMesh(_ mesh: Mesh<VertexPositionNormalTexcoord, UInt16>) -> RendererMesh? {
 | 
					  func createMesh(_ mesh: Mesh<VertexPositionNormalTexcoord, UInt16>) -> RendererMesh? {
 | 
				
			||||||
    if mesh.vertices.isEmpty || mesh.indices.isEmpty { return nil }
 | 
					    if mesh.vertices.isEmpty || mesh.indices.isEmpty { return nil }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let color = Color<Float16>.white.reinterpretUShort
 | 
					    let color = Color<Float>.white
 | 
				
			||||||
    let vertices = mesh.vertices.map {
 | 
					    let vertices = mesh.vertices.map {
 | 
				
			||||||
      ShaderVertex(position: $0.position, normal: $0.normal, color: color, texCoord: $0.texCoord)
 | 
					      ShaderVertex(position: $0.position, normal: $0.normal, color: color.values, texCoord: $0.texCoord)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    guard let vtxBuffer = self.device.makeBuffer(
 | 
					    guard let vtxBuffer = self.device.makeBuffer(
 | 
				
			||||||
      bytes: vertices,
 | 
					      bytes: vertices,
 | 
				
			||||||
@ -341,21 +341,21 @@ public class Renderer {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  func draw(model: matrix_float4x4, color: Color<Float16>, mesh: RendererMesh, material: Material, environment: Environment, camera: Camera) {
 | 
					  func draw(model: matrix_float4x4, color: Color<Float>, mesh: RendererMesh, material: Material, environment: Environment, camera: Camera) {
 | 
				
			||||||
    assert(self._encoder != nil, "draw can't be called outside of a frame being rendered")
 | 
					    assert(self._encoder != nil, "draw can't be called outside of a frame being rendered")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var vertUniforms = VertexShaderUniforms(projView: camera.viewProjection)
 | 
					    var vertUniforms = VertexShaderUniforms(projView: camera.viewProjection)
 | 
				
			||||||
    var fragUniforms = FragmentShaderUniforms(
 | 
					    var fragUniforms = FragmentShaderUniforms(
 | 
				
			||||||
      cameraPosition: camera.position,
 | 
					      cameraPosition: camera.position,
 | 
				
			||||||
      directionalLight: normalize(environment.lightDirection),
 | 
					      directionalLight: normalize(environment.lightDirection),
 | 
				
			||||||
      ambientColor:  material.ambient.reinterpretUShort,
 | 
					      ambientColor:  material.ambient.values,
 | 
				
			||||||
      diffuseColor:  material.diffuse.reinterpretUShort,
 | 
					      diffuseColor:  material.diffuse.values,
 | 
				
			||||||
      specularColor: material.specular.reinterpretUShort,
 | 
					      specularColor: material.specular.values,
 | 
				
			||||||
      specularIntensity: material.gloss)
 | 
					      specularIntensity: material.gloss)
 | 
				
			||||||
    var instance = VertexShaderInstance(
 | 
					    var instance = VertexShaderInstance(
 | 
				
			||||||
      model:       model,
 | 
					      model:       model,
 | 
				
			||||||
      normalModel: model.inverse.transpose,
 | 
					      normalModel: model.inverse.transpose,
 | 
				
			||||||
      color:       color.reinterpretUShort)
 | 
					      color:       color.values)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    self._encoder.setCullMode(.init(environment.cullFace))
 | 
					    self._encoder.setCullMode(.init(environment.cullFace))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -386,9 +386,9 @@ public class Renderer {
 | 
				
			|||||||
    var fragUniforms = FragmentShaderUniforms(
 | 
					    var fragUniforms = FragmentShaderUniforms(
 | 
				
			||||||
      cameraPosition: camera.position,
 | 
					      cameraPosition: camera.position,
 | 
				
			||||||
      directionalLight: normalize(environment.lightDirection),
 | 
					      directionalLight: normalize(environment.lightDirection),
 | 
				
			||||||
      ambientColor:  material.ambient.reinterpretUShort,
 | 
					      ambientColor:  material.ambient.values,
 | 
				
			||||||
      diffuseColor:  material.diffuse.reinterpretUShort,
 | 
					      diffuseColor:  material.diffuse.values,
 | 
				
			||||||
      specularColor: material.specular.reinterpretUShort,
 | 
					      specularColor: material.specular.values,
 | 
				
			||||||
      specularIntensity: material.gloss)
 | 
					      specularIntensity: material.gloss)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let numInstances = instances.count
 | 
					    let numInstances = instances.count
 | 
				
			||||||
@ -417,7 +417,7 @@ public class Renderer {
 | 
				
			|||||||
          .scale(instance.scale)
 | 
					          .scale(instance.scale)
 | 
				
			||||||
        data[i] = VertexShaderInstance(
 | 
					        data[i] = VertexShaderInstance(
 | 
				
			||||||
          model: model, normalModel: model.inverse.transpose,
 | 
					          model: model, normalModel: model.inverse.transpose,
 | 
				
			||||||
          color: instance.color.reinterpretUShort)
 | 
					          color: instance.color.values)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    instanceBuffer.didModifyRange(0..<instancesBytes)
 | 
					    instanceBuffer.didModifyRange(0..<instancesBytes)
 | 
				
			||||||
@ -468,13 +468,13 @@ fileprivate extension MTLCullMode {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fileprivate extension Color where T == Float16 {
 | 
					fileprivate extension Color where T == Float {
 | 
				
			||||||
  var reinterpretUShort: SIMD4<UInt16> {
 | 
					  var reinterpretUInt: SIMD4<UInt32> {
 | 
				
			||||||
    .init(self.r.bitPattern, self.g.bitPattern, self.b.bitPattern, self.a.bitPattern)
 | 
					    .init(self.r.bitPattern, self.g.bitPattern, self.b.bitPattern, self.a.bitPattern)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
fileprivate extension SIMD4 where Scalar == Float16 {
 | 
					fileprivate extension SIMD4 where Scalar == Float {
 | 
				
			||||||
  var reinterpretUShort: SIMD4<UInt16> {
 | 
					  var reinterpretUShort: SIMD4<UInt32> {
 | 
				
			||||||
    .init(self.x.bitPattern, self.y.bitPattern, self.z.bitPattern, self.w.bitPattern)
 | 
					    .init(self.x.bitPattern, self.y.bitPattern, self.z.bitPattern, self.w.bitPattern)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,9 +26,9 @@ struct WorldGenerator {
 | 
				
			|||||||
          + self.noise.get(fpos * 0.30) * 0.23
 | 
					          + self.noise.get(fpos * 0.30) * 0.23
 | 
				
			||||||
      return if value < threshold {
 | 
					      return if value < threshold {
 | 
				
			||||||
        .solid(.init(
 | 
					        .solid(.init(
 | 
				
			||||||
          hue:        Float16(180 + self.noise2.get(fpos * 0.05) * 180),
 | 
					          hue:        Float(180 + self.noise2.get(fpos * 0.05) * 180),
 | 
				
			||||||
          saturation: Float16(0.5 + self.noise2.get(SIMD4(fpos * 0.05, 4)) * 0.5),
 | 
					          saturation: Float(0.5 + self.noise2.get(SIMD4(fpos * 0.05, 4)) * 0.5),
 | 
				
			||||||
          value:      Float16(0.5 + self.noise2.get(SIMD4(fpos * 0.05, 9)) * 0.5).lerp(0.5, 1)).linear)
 | 
					          value:      Float(0.5 + self.noise2.get(SIMD4(fpos * 0.05, 9)) * 0.5).lerp(0.5, 1)).linear)
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        .air
 | 
					        .air
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ struct FragmentInput {
 | 
				
			|||||||
  float3 world;
 | 
					  float3 world;
 | 
				
			||||||
  float3 normal;
 | 
					  float3 normal;
 | 
				
			||||||
  float2 texCoord;
 | 
					  float2 texCoord;
 | 
				
			||||||
  half4 color;
 | 
					  float4 color;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vertex FragmentInput vertexMain(
 | 
					vertex FragmentInput vertexMain(
 | 
				
			||||||
@ -29,7 +29,7 @@ vertex FragmentInput vertexMain(
 | 
				
			|||||||
  return out;
 | 
					  return out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fragment half4 fragmentMain(
 | 
					fragment float4 fragmentMain(
 | 
				
			||||||
  FragmentInput in [[stage_in]],
 | 
					  FragmentInput in [[stage_in]],
 | 
				
			||||||
  metal::texture2d<half, metal::access::sample> texture [[texture(0)]],
 | 
					  metal::texture2d<half, metal::access::sample> texture [[texture(0)]],
 | 
				
			||||||
  constant FragmentShaderUniforms& u [[buffer(FragmentShaderInputIdxUniforms)]]
 | 
					  constant FragmentShaderUniforms& u [[buffer(FragmentShaderInputIdxUniforms)]]
 | 
				
			||||||
@ -45,17 +45,17 @@ fragment half4 fragmentMain(
 | 
				
			|||||||
  // Compute diffuse component
 | 
					  // Compute diffuse component
 | 
				
			||||||
  float lambert = metal::dot(normal, lightVec);
 | 
					  float lambert = metal::dot(normal, lightVec);
 | 
				
			||||||
  float diffuseAmount = metal::max(0.0, lambert);
 | 
					  float diffuseAmount = metal::max(0.0, lambert);
 | 
				
			||||||
  half4 diffuse = u.diffuseColor * diffuseAmount;
 | 
					  float4 diffuse = u.diffuseColor * diffuseAmount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Compute specular component (blinn-phong)
 | 
					  // Compute specular component (blinn-phong)
 | 
				
			||||||
  float specularAngle = metal::max(0.0, metal::dot(halfDir, normal));
 | 
					  float specularAngle = metal::max(0.0, metal::dot(halfDir, normal));
 | 
				
			||||||
  float specularTerm = metal::pow(specularAngle, u.specularIntensity);
 | 
					  float specularTerm = metal::pow(specularAngle, u.specularIntensity);
 | 
				
			||||||
  // smoothstep hack to ensure highlight tapers gracefully at grazing angles
 | 
					  // smoothstep hack to ensure highlight tapers gracefully at grazing angles
 | 
				
			||||||
  float specularAmount = specularTerm * metal::smoothstep(0, 2, lambert * u.specularIntensity);
 | 
					  float specularAmount = specularTerm * metal::smoothstep(0, 2, lambert * u.specularIntensity);
 | 
				
			||||||
  half4 specular = u.specularColor * specularAmount;
 | 
					  float4 specular = u.specularColor * specularAmount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Sample texture & vertex color to get albedo
 | 
					  // Sample texture & vertex color to get albedo
 | 
				
			||||||
  half4 albedo = texture.sample(sampler, in.texCoord);
 | 
					  float4 albedo = float4(texture.sample(sampler, in.texCoord));
 | 
				
			||||||
  albedo *= in.color;
 | 
					  albedo *= in.color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return albedo * (u.ambientColor + diffuse) + specular;
 | 
					  return albedo * (u.ambientColor + diffuse) + specular;
 | 
				
			||||||
 | 
				
			|||||||
@ -10,12 +10,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <simd/simd.h>
 | 
					#include <simd/simd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// HACK: allow passing SIMD4<Float16> to shader while `simd_half4` is beta
 | 
					typedef simd_float4 color_float4;
 | 
				
			||||||
#ifdef __METAL_VERSION__
 | 
					 | 
				
			||||||
typedef half4 color_half4;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
typedef simd_ushort4 color_half4;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef NS_ENUM(NSInteger, VertexShaderInputIdx) {
 | 
					typedef NS_ENUM(NSInteger, VertexShaderInputIdx) {
 | 
				
			||||||
  VertexShaderInputIdxVertices = 0,
 | 
					  VertexShaderInputIdxVertices = 0,
 | 
				
			||||||
@ -26,14 +21,14 @@ typedef NS_ENUM(NSInteger, VertexShaderInputIdx) {
 | 
				
			|||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
  vector_float3 position;
 | 
					  vector_float3 position;
 | 
				
			||||||
  vector_float3 normal;
 | 
					  vector_float3 normal;
 | 
				
			||||||
  color_half4   color;
 | 
					  color_float4   color;
 | 
				
			||||||
  vector_float2 texCoord;
 | 
					  vector_float2 texCoord;
 | 
				
			||||||
} ShaderVertex;
 | 
					} ShaderVertex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
  matrix_float4x4 model;
 | 
					  matrix_float4x4 model;
 | 
				
			||||||
  matrix_float4x4 normalModel;
 | 
					  matrix_float4x4 normalModel;
 | 
				
			||||||
  color_half4     color;
 | 
					  color_float4     color;
 | 
				
			||||||
} VertexShaderInstance;
 | 
					} VertexShaderInstance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
@ -46,7 +41,7 @@ typedef NS_ENUM(NSInteger, FragmentShaderInputIdx) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
  vector_float3 cameraPosition, directionalLight;
 | 
					  vector_float3 cameraPosition, directionalLight;
 | 
				
			||||||
  color_half4 ambientColor, diffuseColor, specularColor;
 | 
					  color_float4 ambientColor, diffuseColor, specularColor;
 | 
				
			||||||
  float specularIntensity;
 | 
					  float specularIntensity;
 | 
				
			||||||
} FragmentShaderUniforms;
 | 
					} FragmentShaderUniforms;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user