Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Light sources (#37) #201

Draft
wants to merge 8 commits into
base: dev
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
WIP Add uniform param to frag shader
jdahlstrom committed Dec 16, 2024

Unverified

No user is associated with the committer email.
commit 4464180c7ce48711e7ebf5a75ee54162ffcb9144
7 changes: 4 additions & 3 deletions core/src/render.rs
Original file line number Diff line number Diff line change
@@ -74,12 +74,13 @@ pub type NdcToScreen = RealToReal<3, Ndc, Screen>;

/// Alias for combined vertex+fragment shader types
pub trait Shader<Vtx, Var, Uni>:
VertexShader<Vtx, Uni, Output = Vertex<ProjVec4, Var>> + FragmentShader<Var>
VertexShader<Vtx, Uni, Output = Vertex<ProjVec4, Var>>
+ FragmentShader<Var, Uni>
{
}
impl<S, Vtx, Var, Uni> Shader<Vtx, Var, Uni> for S where
S: VertexShader<Vtx, Uni, Output = Vertex<ProjVec4, Var>>
+ FragmentShader<Var>
+ FragmentShader<Var, Uni>
{
}

@@ -162,7 +163,7 @@ pub fn render<Vtx: Clone, Var: Lerp + Vary, Uni: Copy, Shd>(
// Fragment shader and rasterization
tri_fill(vs, |scanline| {
// Convert to fragments and shade
stats.frags += target.rasterize(scanline, shader, ctx);
stats.frags += target.rasterize(scanline, uniform, shader, ctx);
});
}
*ctx.stats.borrow_mut() += stats.finish();
6 changes: 3 additions & 3 deletions core/src/render/cam.rs
Original file line number Diff line number Diff line change
@@ -148,9 +148,9 @@ impl<M: Mode> Camera<M> {
Vtx,
(&'a Mat4x4<RealToProj<B>>, Uni),
Output = Vertex<ClipVec, Var>,
> + FragmentShader<Var>,
> + FragmentShader<Var, Uni>,
{
let tf = to_world.then(&self.world_to_project());
/*let tf = to_world.then(&self.world_to_project());
super::render(
tris.as_ref(),
@@ -160,7 +160,7 @@ impl<M: Mode> Camera<M> {
self.viewport,
target,
ctx,
);
);*/
}
}

22 changes: 11 additions & 11 deletions core/src/render/shader.rs
Original file line number Diff line number Diff line change
@@ -43,13 +43,13 @@ pub trait VertexShader<In, Uni> {
///
/// # Type parameters
/// * `Var`: The varying of the input fragment.
pub trait FragmentShader<Var> {
pub trait FragmentShader<Var, Uni> {
/// Computes the color of `frag`. Returns either `Some(color)`, or `None`
/// if the fragment should be discarded.
///
/// # Panics
/// `shade_fragment` should never panic.
fn shade_fragment(&self, frag: Frag<Var>) -> Option<Color4>;
fn shade_fragment(&self, frag: Frag<Var>, uniform: Uni) -> Option<Color4>;
}

impl<F, In, Out, Uni> VertexShader<In, Uni> for F
@@ -63,13 +63,13 @@ where
}
}

impl<F, Var, Out> FragmentShader<Var> for F
impl<F, Var, Out, Uni> FragmentShader<Var, Uni> for F
where
F: Fn(Frag<Var>) -> Out,
F: Fn(Frag<Var>, Uni) -> Out,
Out: Into<Option<Color4>>,
{
fn shade_fragment(&self, frag: Frag<Var>) -> Option<Color4> {
self(frag).into()
fn shade_fragment(&self, frag: Frag<Var>, uniform: Uni) -> Option<Color4> {
self(frag, uniform).into()
}
}

@@ -86,7 +86,7 @@ impl<Vs, Fs> Shader<Vs, Fs> {
pub const fn new<In, Uni, Pos, Attr>(vs: Vs, fs: Fs) -> Self
where
Vs: VertexShader<In, Uni, Output = Vertex<Pos, Attr>>,
Fs: FragmentShader<Attr>,
Fs: FragmentShader<Attr, Uni>,
{
Self {
vertex_shader: vs,
@@ -106,11 +106,11 @@ where
}
}

impl<Vs, Fs, Var> FragmentShader<Var> for Shader<Vs, Fs>
impl<Vs, Fs, Var, Uni> FragmentShader<Var, Uni> for Shader<Vs, Fs>
where
Fs: FragmentShader<Var>,
Fs: FragmentShader<Var, Uni>,
{
fn shade_fragment(&self, frag: Frag<Var>) -> Option<Color4> {
self.fragment_shader.shade_fragment(frag)
fn shade_fragment(&self, frag: Frag<Var>, uni: Uni) -> Option<Color4> {
self.fragment_shader.shade_fragment(frag, uni)
}
}
22 changes: 14 additions & 8 deletions core/src/render/target.rs
Original file line number Diff line number Diff line change
@@ -16,15 +16,17 @@ pub trait Target {
/// Writes a single scanline into `self`.
///
/// Returns count of fragments input and output.
fn rasterize<V, Fs>(
fn rasterize<V, U, Fs>(
&mut self,
scanline: Scanline<V>,
uniform: U,
frag_shader: &Fs,
ctx: &Context,
) -> Throughput
where
V: Vary,
Fs: FragmentShader<V>;
U: Copy,
Fs: FragmentShader<V, U>;
}

/// Framebuffer, combining a color (pixel) buffer and a depth buffer.
@@ -40,15 +42,17 @@ where
Dep: AsMutSlice2<f32>,
{
/// Rasterizes `scanline` into this framebuffer.
fn rasterize<V, Fs>(
fn rasterize<V, U, Fs>(
&mut self,
mut sl: Scanline<V>,
uni: U,
fs: &Fs,
ctx: &Context,
) -> Throughput
where
V: Vary,
Fs: FragmentShader<V>,
U: Copy,
Fs: FragmentShader<V, U>,
{
let x0 = sl.xs.start;
let x1 = sl.xs.end.max(x0);
@@ -64,7 +68,7 @@ where
let new_z = frag.pos.z();

if ctx.depth_test(new_z, *curr_z) {
if let Some(new_col) = fs.shade_fragment(frag) {
if let Some(new_col) = fs.shade_fragment(frag, uni) {
if ctx.color_write {
io.o += 1;
// TODO Blending should happen here
@@ -83,15 +87,17 @@ where
impl<Buf: AsMutSlice2<u32>> Target for Buf {
/// Rasterizes `scanline` into this `u32` color buffer.
/// Does no z-buffering.
fn rasterize<V, Fs>(
fn rasterize<V, U, Fs>(
&mut self,
mut sl: Scanline<V>,
uni: U,
fs: &Fs,
ctx: &Context,
) -> Throughput
where
V: Vary,
Fs: FragmentShader<V>,
U: Copy,
Fs: FragmentShader<V, U>,
{
let x0 = sl.xs.start;
let x1 = sl.xs.end.max(x0);
@@ -101,7 +107,7 @@ impl<Buf: AsMutSlice2<u32>> Target for Buf {
sl.fragments()
.zip(cbuf_span)
.for_each(|(frag, c)| {
if let Some(color) = fs.shade_fragment(frag) {
if let Some(color) = fs.shade_fragment(frag, uni) {
if ctx.color_write {
io.o += 1;
*c = color.to_argb_u32();
4 changes: 2 additions & 2 deletions demos/src/bin/crates.rs
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ fn main() {
let light_col = u.light.eval(pos).add(&gray(0.2));
vertex(u.proj.apply(&pos), light_col.mul(v.attrib.r()))
},
|f: Frag<Color3f>| f.var.to_color4(),
|f: Frag<Color3f>, _: &_| f.var.to_color4(),
);
let crate_shader = Shader::new(
|v: Vertex3<Normal3>, u: &Uniform| {
@@ -49,7 +49,7 @@ fn main() {

vertex(u.proj.apply(&pos), color)
},
|f: Frag<Color3f>| {
|f: Frag<Color3f>, _: &_| {
//let [x, y, z] = ((f.var + splat(1.0)) / 2.0).0;
//rgb(x, y, z).to_color4()
f.var.to_color4()
2 changes: 1 addition & 1 deletion demos/src/bin/solids.rs
Original file line number Diff line number Diff line change
@@ -79,7 +79,7 @@ fn main() {
vertex(mvp.apply(&v.pos), col)
}

fn frag_shader(f: Frag<Color3f>) -> Color4 {
fn frag_shader(f: Frag<Color3f>, _: Uniform) -> Color4 {
f.var.to_color4()
}

2 changes: 1 addition & 1 deletion demos/src/bin/sprites.rs
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ fn main() {
let view_pos = mv.apply_pt(&v.pos) + vertex_pos;
vertex(proj.apply(&view_pos), v.attrib)
},
|frag: Frag<Vec2<_>>| {
|frag: Frag<Vec2<_>>, _: (&_, &_)| {
let d2 = frag.var.len_sqr();
(d2 < 1.0).then(|| {
// TODO ops trait for colors
2 changes: 1 addition & 1 deletion demos/src/bin/square.rs
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ fn main() {
|v: Vertex3<_>, mvp: &Mat4x4<ModelToProj>| {
vertex(mvp.apply(&v.pos), v.attrib)
},
|frag: Frag<_>| SamplerClamp.sample(&checker, frag.var),
|frag: Frag<_>, _: &_| SamplerClamp.sample(&checker, frag.var),
);

let (w, h) = win.dims;
2 changes: 1 addition & 1 deletion demos/wasm/src/triangle.rs
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ pub fn start() {

let sh = Shader::new(
|v: Vertex3<Color4f>, _| vertex(mvp.apply(&v.pos), v.attrib),
|f: Frag<Color4f>| f.var.to_color4(),
|f: Frag<Color4f>, _| f.var.to_color4(),
);

render(
8 changes: 5 additions & 3 deletions front/src/sdl2.rs
Original file line number Diff line number Diff line change
@@ -193,15 +193,17 @@ impl Window {
}

impl<'a> Target for Framebuf<'a> {
fn rasterize<V, Fs>(
fn rasterize<V, U, Fs>(
&mut self,
mut sl: Scanline<V>,
uni: U,
fs: &Fs,
ctx: &Context,
) -> Throughput
where
V: Vary,
Fs: FragmentShader<V>,
U: Copy,
Fs: FragmentShader<V, U>,
{
// TODO Lots of duplicate code

@@ -218,7 +220,7 @@ impl<'a> Target for Framebuf<'a> {
.for_each(|((frag, c), z)| {
let new_z = frag.pos.z();
if ctx.depth_test(new_z, *z) {
if let Some(new_c) = fs.shade_fragment(frag) {
if let Some(new_c) = fs.shade_fragment(frag, uni) {
if ctx.color_write {
// TODO Blending should happen here
io.o += 1;