initial lighting

This commit is contained in:
a dinosaur 2024-08-18 01:10:25 +10:00
parent 55d47a2d2f
commit f7255c473c
3 changed files with 26 additions and 10 deletions

View File

@ -344,13 +344,16 @@ public class Renderer {
assert(self._encoder != nil, "batch can't be called outside of a frame being rendered") assert(self._encoder != nil, "batch can't be called outside of a frame being rendered")
assert(instances.count < 52) assert(instances.count < 52)
var uniforms = ShaderUniforms(projView: camera.viewProjection) var uniforms = ShaderUniforms(
projView: camera.viewProjection,
directionalLight: normalize(.init(0.75, -1, 0.5)))
let instances = instances.map { (instance: Instance) -> ShaderInstance in let instances = instances.map { (instance: Instance) -> ShaderInstance in
ShaderInstance( let model =
model: .translate(instance.position) *
.translate(instance.position) * matrix_float4x4(instance.rotation) *
matrix_float4x4(instance.rotation) * .scale(instance.scale)
.scale(instance.scale), return ShaderInstance(
model: model, normalModel: model.inverse.transpose,
color: SIMD4(Color<UInt8>(instance.color))) color: SIMD4(Color<UInt8>(instance.color)))
} }
@ -361,6 +364,9 @@ public class Renderer {
self._encoder.setVertexBytes(&uniforms, self._encoder.setVertexBytes(&uniforms,
length: MemoryLayout<ShaderUniforms>.stride, length: MemoryLayout<ShaderUniforms>.stride,
index: ShaderInputIdx.uniforms.rawValue) index: ShaderInputIdx.uniforms.rawValue)
self._encoder.setFragmentBytes(&uniforms,
length: MemoryLayout<ShaderUniforms>.stride,
index: ShaderInputIdx.uniforms.rawValue)
self._encoder.drawIndexedPrimitives( self._encoder.drawIndexedPrimitives(
type: .triangle, type: .triangle,

View File

@ -4,7 +4,7 @@
struct FragmentInput { struct FragmentInput {
float4 position [[position]]; float4 position [[position]];
float4 normal; float3 normal;
float2 texCoord; float2 texCoord;
half4 color; half4 color;
}; };
@ -23,16 +23,24 @@ vertex FragmentInput vertexMain(
FragmentInput out; FragmentInput out;
out.position = ndc; out.position = ndc;
out.color = half4(i[instanceID].color) / 255.0; out.color = half4(i[instanceID].color) / 255.0;
out.normal = vtx[vertexID].normal; out.normal = (i[instanceID].normalModel * vtx[vertexID].normal).xyz;
out.texCoord = vtx[vertexID].texCoord; out.texCoord = vtx[vertexID].texCoord;
return out; return out;
} }
fragment half4 fragmentMain( fragment half4 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 ShaderUniforms& u [[buffer(ShaderInputIdxUniforms)]]
) { ) {
constexpr metal::sampler sampler(metal::address::repeat, metal::filter::nearest); constexpr metal::sampler sampler(metal::address::repeat, metal::filter::nearest);
auto normal = metal::normalize(in.normal);
float lambert = metal::dot(normal, -u.directionalLight);
float diffuse = metal::max(0.0, lambert);
half4 albedo = texture.sample(sampler, in.texCoord); half4 albedo = texture.sample(sampler, in.texCoord);
return albedo * in.color; albedo *= in.color;
return albedo * diffuse;
} }

View File

@ -24,11 +24,13 @@ typedef struct {
typedef struct { typedef struct {
matrix_float4x4 model; matrix_float4x4 model;
matrix_float4x4 normalModel;
vector_uchar4 color; vector_uchar4 color;
} ShaderInstance; } ShaderInstance;
typedef struct { typedef struct {
matrix_float4x4 projView; matrix_float4x4 projView;
vector_float3 directionalLight;
} ShaderUniforms; } ShaderUniforms;
#endif//SHADERTYPES_H #endif//SHADERTYPES_H