separate shader uniforms structures

This commit is contained in:
a dinosaur 2024-08-18 01:20:19 +10:00
parent f7255c473c
commit 94ed59055a
3 changed files with 31 additions and 27 deletions

View File

@ -321,9 +321,7 @@ public class Renderer {
encoder.setRenderPipelineState(pso)
encoder.setDepthStencilState(depthStencilState)
encoder.setFragmentTexture(cubeTexture ?? defaultTexture, index: 0)
encoder.setVertexBuffer(vtxBuffer,
offset: 0,
index: ShaderInputIdx.vertices.rawValue)
encoder.setVertexBuffer(vtxBuffer, offset: 0, index: VertexShaderInputIdx.vertices.rawValue)
self._encoder = encoder
frameFunc(self)
@ -342,31 +340,30 @@ public class Renderer {
func batch(instances: [Instance], camera: Camera) {
assert(self._encoder != nil, "batch can't be called outside of a frame being rendered")
assert(instances.count < 52)
assert(instances.count < 28)
var uniforms = ShaderUniforms(
projView: camera.viewProjection,
directionalLight: normalize(.init(0.75, -1, 0.5)))
let instances = instances.map { (instance: Instance) -> ShaderInstance in
var vertUniforms = VertexShaderUniforms(projView: camera.viewProjection)
var fragUniforms = FragmentShaderUniforms(directionalLight: normalize(.init(0.75, -1, 0.5)))
let instances = instances.map { (instance: Instance) -> VertexShaderInstance in
let model =
.translate(instance.position) *
matrix_float4x4(instance.rotation) *
.scale(instance.scale)
return ShaderInstance(
return VertexShaderInstance(
model: model, normalModel: model.inverse.transpose,
color: SIMD4(Color<UInt8>(instance.color)))
}
// Ideal as long as our uniforms total 4 KB or less
self._encoder.setVertexBytes(instances,
length: instances.count * MemoryLayout<ShaderInstance>.stride,
index: ShaderInputIdx.instance.rawValue)
self._encoder.setVertexBytes(&uniforms,
length: MemoryLayout<ShaderUniforms>.stride,
index: ShaderInputIdx.uniforms.rawValue)
self._encoder.setFragmentBytes(&uniforms,
length: MemoryLayout<ShaderUniforms>.stride,
index: ShaderInputIdx.uniforms.rawValue)
length: instances.count * MemoryLayout<VertexShaderInstance>.stride,
index: VertexShaderInputIdx.instance.rawValue)
self._encoder.setVertexBytes(&vertUniforms,
length: MemoryLayout<VertexShaderUniforms>.stride,
index: VertexShaderInputIdx.uniforms.rawValue)
self._encoder.setFragmentBytes(&fragUniforms,
length: MemoryLayout<FragmentShaderUniforms>.stride,
index: FragmentShaderInputIdx.uniforms.rawValue)
self._encoder.drawIndexedPrimitives(
type: .triangle,

View File

@ -12,9 +12,9 @@ struct FragmentInput {
vertex FragmentInput vertexMain(
uint vertexID [[vertex_id]],
uint instanceID [[instance_id]],
device const ShaderVertex* vtx [[buffer(ShaderInputIdxVertices)]],
device const ShaderInstance* i [[buffer(ShaderInputIdxInstance)]],
constant ShaderUniforms& u [[buffer(ShaderInputIdxUniforms)]]
device const ShaderVertex* vtx [[buffer(VertexShaderInputIdxVertices)]],
device const VertexShaderInstance* i [[buffer(VertexShaderInputIdxInstance)]],
constant VertexShaderUniforms& u [[buffer(VertexShaderInputIdxUniforms)]]
) {
auto position = vtx[vertexID].position;
auto world = i[instanceID].model * position;
@ -31,7 +31,7 @@ vertex FragmentInput vertexMain(
fragment half4 fragmentMain(
FragmentInput in [[stage_in]],
metal::texture2d<half, metal::access::sample> texture [[texture(0)]],
constant ShaderUniforms& u [[buffer(ShaderInputIdxUniforms)]]
constant FragmentShaderUniforms& u [[buffer(FragmentShaderInputIdxUniforms)]]
) {
constexpr metal::sampler sampler(metal::address::repeat, metal::filter::nearest);
auto normal = metal::normalize(in.normal);

View File

@ -10,10 +10,10 @@
#include <simd/simd.h>
typedef NS_ENUM(NSInteger, ShaderInputIdx) {
ShaderInputIdxVertices = 0,
ShaderInputIdxInstance = 1,
ShaderInputIdxUniforms = 2
typedef NS_ENUM(NSInteger, VertexShaderInputIdx) {
VertexShaderInputIdxVertices = 0,
VertexShaderInputIdxInstance = 1,
VertexShaderInputIdxUniforms = 2
};
typedef struct {
@ -26,11 +26,18 @@ typedef struct {
matrix_float4x4 model;
matrix_float4x4 normalModel;
vector_uchar4 color;
} ShaderInstance;
} VertexShaderInstance;
typedef struct {
matrix_float4x4 projView;
} VertexShaderUniforms;
typedef NS_ENUM(NSInteger, FragmentShaderInputIdx) {
FragmentShaderInputIdxUniforms = 0
};
typedef struct {
vector_float3 directionalLight;
} ShaderUniforms;
} FragmentShaderUniforms;
#endif//SHADERTYPES_H