mirror of
https://github.com/GayPizzaSpecifications/voxelotl-engine.git
synced 2025-08-02 21:00:57 +00:00
instancing
This commit is contained in:
parent
89780d87d4
commit
5f69da369d
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user