Harbor

branch main
showing the latest snapshot on main
basic.luma 1.4 KB · Plain text
gpu/shader/examples/basic.luma 0644 Raw
-- Basic vertex + fragment shader pair
-- Demonstrates: structs, uniforms, entry points, @varying, auto-location

struct VertexInput
	position: vec3
	normal: vec3
	uv: vec2
end

-- @varying marks a struct shared between vertex output and fragment input.
-- Fragment inputs automatically skip @builtin fields.
@varying
struct Interpolated
	@builtin(position) position: vec4
	uv: vec2
	normal: vec3
end

struct Uniforms
	model: mat4
	view_proj: mat4
	normal_mat: mat4
end

-- Binding attributes are optional: @group defaults to 0, @binding auto-increments
uniform uniforms: Uniforms

@entry(vertex)
function vs_main(input: VertexInput) -> Interpolated
	let world_pos = uniforms.model * vec4(input.position, 1.0)
	let clip_pos = uniforms.view_proj * world_pos
	let world_normal = normalize((uniforms.normal_mat * vec4(input.normal, 0.0)).xyz)

	return Interpolated {
		position = clip_pos,
		uv = input.uv,
		normal = world_normal,
	}
end

struct FragmentOutput
	@location(0) color: vec4
end

-- sampler2D is automatically split into texture + sampler bindings
@group(1) @binding(0)
uniform albedo_tex: sampler2D

@entry(fragment)
function fs_main(input: Interpolated) -> FragmentOutput
	let albedo = sample(albedo_tex, input.uv)
	let light = max(dot(input.normal, normalize(vec3(1.0, 1.0, 0.0))), 0.0)
	let color = albedo * (light * 0.8 + 0.2)

	return FragmentOutput {
		color = vec4(color.rgb, 1.0),
	}
end