mirror of
				https://github.com/GayPizzaSpecifications/voxelotl-engine.git
				synced 2025-11-04 10:59:39 +00:00 
			
		
		
		
	instancing
This commit is contained in:
		@ -286,24 +286,26 @@ class Renderer {
 | 
				
			|||||||
    let projection = matrix_float4x4.perspective(
 | 
					    let projection = matrix_float4x4.perspective(
 | 
				
			||||||
      verticalFov: Float(60.0).radians,
 | 
					      verticalFov: Float(60.0).radians,
 | 
				
			||||||
      aspect: aspectRatio,
 | 
					      aspect: aspectRatio,
 | 
				
			||||||
      near: 0.003,
 | 
					      near: 0.03,
 | 
				
			||||||
      far: 100)
 | 
					      far: 25)
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    let projection = matrix_float4x4.orthographic(
 | 
					    let projection = matrix_float4x4.orthographic(
 | 
				
			||||||
      left: -aspectRatio, right: aspectRatio,
 | 
					      left: -aspectRatio, right: aspectRatio,
 | 
				
			||||||
      bottom: -1, top: 1,
 | 
					      bottom: -1, top: 1,
 | 
				
			||||||
      near: 0, far: -4)
 | 
					      near: -0.03, far: -25)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    let view = camera.view
 | 
					    let view = camera.view
 | 
				
			||||||
    let model: matrix_float4x4 =
 | 
					
 | 
				
			||||||
      .translate(.init(0, -1, 0)) * .scale(.init(10, 0.1, 10))
 | 
					    let instances: [ShaderInstance] = [
 | 
				
			||||||
      //.translate(.init(0, sin(time * 0.5) * 0.75, -2)) *
 | 
					      ShaderInstance(model: .translate(.init(0, sin(time * 0.5) * 0.5, -2)) * .rotate(y: time) * .scale(0.25), color: .init(0.5, 0.5, 1, 1)),
 | 
				
			||||||
      //.scale(0.5) *
 | 
					      ShaderInstance(model: .translate(.init(0, -1, 0)) * .scale(.init(10, 0.1, 10)), color: .init(1, 1, 1, 1)),
 | 
				
			||||||
      //.rotate(y: time)
 | 
					      ShaderInstance(model: .translate(.init(-2.5, 0, -3)), color: .init(1, 0.5, 0.75, 1)),
 | 
				
			||||||
 | 
					      ShaderInstance(model: .translate(.init(-2.5, -0.5, -5)), color: .init(0.75, 1, 1, 1))
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    time += 0.025
 | 
					    time += 0.025
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var uniforms = ShaderUniforms(model: model, projView: projection * view)
 | 
					    var uniforms = ShaderUniforms(projView: projection * view)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    guard let rt = layer.nextDrawable() else {
 | 
					    guard let rt = layer.nextDrawable() else {
 | 
				
			||||||
      throw RendererError.drawFailure("Failed to get next drawable render target")
 | 
					      throw RendererError.drawFailure("Failed to get next drawable render target")
 | 
				
			||||||
@ -318,7 +320,7 @@ class Renderer {
 | 
				
			|||||||
      throw RendererError.drawFailure("Failed to make render encoder from command buffer")
 | 
					      throw RendererError.drawFailure("Failed to make render encoder from command buffer")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    encoder.setCullMode(.none)
 | 
					    encoder.setCullMode(.back)
 | 
				
			||||||
    encoder.setFrontFacing(.counterClockwise)  // OpenGL default
 | 
					    encoder.setFrontFacing(.counterClockwise)  // OpenGL default
 | 
				
			||||||
    encoder.setViewport(viewport)
 | 
					    encoder.setViewport(viewport)
 | 
				
			||||||
    encoder.setRenderPipelineState(pso)
 | 
					    encoder.setRenderPipelineState(pso)
 | 
				
			||||||
@ -328,16 +330,22 @@ class Renderer {
 | 
				
			|||||||
    encoder.setVertexBuffer(vtxBuffer,
 | 
					    encoder.setVertexBuffer(vtxBuffer,
 | 
				
			||||||
      offset: 0,
 | 
					      offset: 0,
 | 
				
			||||||
      index: ShaderInputIdx.vertices.rawValue)
 | 
					      index: ShaderInputIdx.vertices.rawValue)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Ideal as long as our uniforms total 4 KB or less
 | 
					    // Ideal as long as our uniforms total 4 KB or less
 | 
				
			||||||
 | 
					    encoder.setVertexBytes(instances,
 | 
				
			||||||
 | 
					      length: instances.count * MemoryLayout<ShaderInstance>.stride,
 | 
				
			||||||
 | 
					      index: ShaderInputIdx.instance.rawValue)
 | 
				
			||||||
    encoder.setVertexBytes(&uniforms,
 | 
					    encoder.setVertexBytes(&uniforms,
 | 
				
			||||||
      length: MemoryLayout<ShaderUniforms>.stride,
 | 
					      length: MemoryLayout<ShaderUniforms>.stride,
 | 
				
			||||||
      index: ShaderInputIdx.uniforms.rawValue)
 | 
					      index: ShaderInputIdx.uniforms.rawValue)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    encoder.drawIndexedPrimitives(
 | 
					    encoder.drawIndexedPrimitives(
 | 
				
			||||||
      type: .triangle,
 | 
					      type: .triangle,
 | 
				
			||||||
      indexCount: cubeIndices.count,
 | 
					      indexCount: cubeIndices.count,
 | 
				
			||||||
      indexType: .uint16,
 | 
					      indexType: .uint16,
 | 
				
			||||||
      indexBuffer: idxBuffer,
 | 
					      indexBuffer: idxBuffer,
 | 
				
			||||||
      indexBufferOffset: 0)
 | 
					      indexBufferOffset: 0,
 | 
				
			||||||
 | 
					      instanceCount: instances.count)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    encoder.endEncoding()
 | 
					    encoder.endEncoding()
 | 
				
			||||||
    commandBuf.present(rt)
 | 
					    commandBuf.present(rt)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,25 +1,28 @@
 | 
				
			|||||||
#include "shadertypes.h"
 | 
					#include "shadertypes.h"
 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <metal_stdlib>
 | 
					#include <metal_stdlib>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace metal;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct FragmentInput {
 | 
					struct FragmentInput {
 | 
				
			||||||
  float4 position [[position]];
 | 
					  float4 position [[position]];
 | 
				
			||||||
  float4 normal;
 | 
					  float4 normal;
 | 
				
			||||||
  float2 texCoord;
 | 
					  float2 texCoord;
 | 
				
			||||||
 | 
					  half4 color;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vertex FragmentInput vertexMain(
 | 
					vertex FragmentInput vertexMain(
 | 
				
			||||||
  uint vertexID [[vertex_id]],
 | 
					  uint vertexID [[vertex_id]],
 | 
				
			||||||
 | 
					  uint instanceID [[instance_id]],
 | 
				
			||||||
  device const ShaderVertex* vtx [[buffer(ShaderInputIdxVertices)]],
 | 
					  device const ShaderVertex* vtx [[buffer(ShaderInputIdxVertices)]],
 | 
				
			||||||
 | 
					  device const ShaderInstance* i [[buffer(ShaderInputIdxInstance)]],
 | 
				
			||||||
  constant ShaderUniforms& u [[buffer(ShaderInputIdxUniforms)]]
 | 
					  constant ShaderUniforms& u [[buffer(ShaderInputIdxUniforms)]]
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
  auto position = vtx[vertexID].position;
 | 
					  auto position = vtx[vertexID].position;
 | 
				
			||||||
  position = u.projView * u.model * position;
 | 
					  auto world = i[instanceID].model * position;
 | 
				
			||||||
 | 
					  auto ndc = u.projView * world;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FragmentInput out;
 | 
					  FragmentInput out;
 | 
				
			||||||
  out.position = position;
 | 
					  out.position = ndc;
 | 
				
			||||||
 | 
					  out.color    = half4(i[instanceID].color);
 | 
				
			||||||
  out.normal   = vtx[vertexID].normal;
 | 
					  out.normal   = vtx[vertexID].normal;
 | 
				
			||||||
  out.texCoord = vtx[vertexID].texCoord;
 | 
					  out.texCoord = vtx[vertexID].texCoord;
 | 
				
			||||||
  return out;
 | 
					  return out;
 | 
				
			||||||
@ -27,10 +30,9 @@ vertex FragmentInput vertexMain(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
fragment half4 fragmentMain(
 | 
					fragment half4 fragmentMain(
 | 
				
			||||||
  FragmentInput in [[stage_in]],
 | 
					  FragmentInput in [[stage_in]],
 | 
				
			||||||
  texture2d<half, access::sample> tex [[texture(0)]]
 | 
					  metal::texture2d<half, metal::access::sample> texture [[texture(0)]]
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
  constexpr sampler s(address::repeat, filter::nearest);
 | 
					  constexpr metal::sampler sampler(metal::address::repeat, metal::filter::nearest);
 | 
				
			||||||
  half4 albedo = tex.sample(s, in.texCoord);
 | 
					  half4 albedo = texture.sample(sampler, in.texCoord);
 | 
				
			||||||
 | 
					  return albedo * in.color;
 | 
				
			||||||
  return half4(albedo.rgb, 1.0);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef NS_ENUM(NSInteger, ShaderInputIdx) {
 | 
					typedef NS_ENUM(NSInteger, ShaderInputIdx) {
 | 
				
			||||||
  ShaderInputIdxVertices = 0,
 | 
					  ShaderInputIdxVertices = 0,
 | 
				
			||||||
  ShaderInputIdxUniforms = 1
 | 
					  ShaderInputIdxInstance = 1,
 | 
				
			||||||
 | 
					  ShaderInputIdxUniforms = 2
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
@ -23,6 +24,10 @@ typedef struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
  matrix_float4x4 model;
 | 
					  matrix_float4x4 model;
 | 
				
			||||||
 | 
					  vector_float4 color;
 | 
				
			||||||
 | 
					} ShaderInstance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
  matrix_float4x4 projView;
 | 
					  matrix_float4x4 projView;
 | 
				
			||||||
} ShaderUniforms;
 | 
					} ShaderUniforms;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user