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

[re_renderer] shader import cleanup & wgsl typedefs #229

Merged
merged 5 commits into from
Oct 26, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
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
19 changes: 10 additions & 9 deletions crates/re_renderer/shader/generic_skybox.wgsl
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
#import <./frame_uniform.wgsl>
#import <./types.wgsl>
#import <./global_bindings.wgsl>

fn camera_dir_from_screenuv(texcoord: vec2<f32>) -> vec3<f32> {
fn camera_dir_from_screenuv(texcoord: Vec2) -> vec3<f32> {
let x = texcoord.x * 2.0 - 1.0;
let y = (1.0 - texcoord.y) * 2.0 - 1.0;
let dir_view = normalize(vec3<f32>(frame.top_right_screen_corner_in_view * vec2<f32>(x, y), 1.0));
let dir_view = normalize(Vec3(frame.top_right_screen_corner_in_view * Vec2(x, y), 1.0));
// the inner 3x3 part of the view_from_world matrix is orthonormal
// A transpose / multiply from right is therefore its inverse!
return (dir_view * frame.view_from_world).xyz;
}

struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) texcoord: vec2<f32>,
@builtin(position) position: Vec4,
@location(0) texcoord: Vec2,
};

fn skybox_dark(dir: vec3<f32>) -> vec3<f32> {
fn skybox_dark(dir: Vec3) -> Vec3 {
let rgb = dir * 0.5 + vec3<f32>(0.5);
return vec3<f32>(0.05) + 0.20 * rgb;
}

fn skybox_light(dir: vec3<f32>) -> vec3<f32> {
fn skybox_light(dir: Vec3) -> Vec3 {
let rgb = dir * 0.5 + vec3<f32>(0.5);
return vec3<f32>(0.85) + 0.15 * rgb;
}

@fragment
fn main(in: VertexOutput) -> @location(0) vec4<f32> {
fn main(in: VertexOutput) -> @location(0) Vec4 {
let camera_dir = camera_dir_from_screenuv(in.texcoord);
let rgb = skybox_dark(camera_dir); // TODO(andreas): Allow switchting to skybox_light
return vec4<f32>(rgb, 1.0);
return Vec4(rgb, 1.0);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ struct FrameUniformBuffer {
};
@group(0) @binding(0)
var<uniform> frame: FrameUniformBuffer;

@group(0) @binding(1)
var nearest_sampler: sampler;
81 changes: 24 additions & 57 deletions crates/re_renderer/shader/lines.wgsl
Original file line number Diff line number Diff line change
@@ -1,65 +1,32 @@
struct FrameUniformBuffer {
view_from_world: mat4x3<f32>,
projection_from_view: mat4x4<f32>,
projection_from_world: mat4x4<f32>,

camera_position: vec3<f32>,
top_right_screen_corner_in_view: vec2<f32>,
};
@group(0) @binding(0)
var<uniform> frame: FrameUniformBuffer;
#import <./types.wgsl>
#import <./global_bindings.wgsl>
#import <./utils/srgb.wgsl>
#import <./utils/encoding.wgsl>

@group(1) @binding(0)
var line_strip_texture: texture_2d<f32>;
@group(1) @binding(1)
var position_data_texture: texture_2d<u32>;


// ---------------------------------------------------------------------------
// TODO(andreas): Utilities that belong to a shared header

// workaround for https://github.com/gfx-rs/naga/issues/2006
fn unpack4x8unorm_workaround(v: u32) -> vec4<f32> {
var shifted = vec4<u32>(v, v >> 8u, v >> 16u, v >> 24u);
var bytes = shifted & vec4<u32>(0xFFu);
return vec4<f32>(bytes) * (1.0 / 255.0);
}

// Converts a color from 0-1 sRGB to 0-1 linear
fn linear_from_srgb(srgb: vec3<f32>) -> vec3<f32> {
let cutoff = ceil(srgb - 0.04045);
let under = srgb / 12.92;
let over = pow((srgb + 0.055) / 1.055, vec3<f32>(2.4));
return mix(under, over, cutoff);
}

// Converts a color from 0-1 sRGB to 0-1 linear, leaves alpha untouched
fn linear_from_srgba(srgb_a: vec4<f32>) -> vec4<f32> {
return vec4<f32>(linear_from_srgb(srgb_a.rgb), srgb_a.a);
}

// ---------------------------------------------------------------------------


// textureLoad needs i32 right now, so we use that with all sizes & indices to avoid casts
// https://github.com/gfx-rs/naga/issues/1997
var<private> line_strip_texture_SIZE: i32 = 512;
var<private> POSITION_DATA_TEXTURE_SIZE: i32 = 256;
let LINESTRIP_TEXTURE_SIZE: i32 = 512;
let POSITION_DATA_TEXTURE_SIZE: i32 = 256;

struct VertexOut {
@location(0) color: vec4<f32>,
@builtin(position) position: vec4<f32>,
@location(0) color: Vec4,
@builtin(position) position: Vec4,
};

struct LineStripData {
color: vec4<f32>,
color: Vec4,
thickness: f32,
stippling: f32,
}

// Read and unpack line strip data at a given location
fn read_strip_data(idx: i32) -> LineStripData {
var raw_data = textureLoad(position_data_texture, vec2<i32>(idx % POSITION_DATA_TEXTURE_SIZE, idx / POSITION_DATA_TEXTURE_SIZE), 0).xy;
var raw_data = textureLoad(position_data_texture, IVec2(idx % POSITION_DATA_TEXTURE_SIZE, idx / POSITION_DATA_TEXTURE_SIZE), 0).xy;

var data: LineStripData;
data.color = linear_from_srgba(unpack4x8unorm_workaround(raw_data.x));
Expand All @@ -79,7 +46,7 @@ struct PositionData {

// Read and unpack position data at a given location
fn read_position_data(idx: i32) -> PositionData {
var raw_data = textureLoad(line_strip_texture, vec2<i32>(idx % line_strip_texture_SIZE, idx / line_strip_texture_SIZE), 0);
var raw_data = textureLoad(line_strip_texture, IVec2(idx % LINESTRIP_TEXTURE_SIZE, idx / LINESTRIP_TEXTURE_SIZE), 0);

var data: PositionData;
data.pos = raw_data.xyz;
Expand All @@ -90,18 +57,18 @@ fn read_position_data(idx: i32) -> PositionData {
@vertex
fn vs_main(@builtin(vertex_index) vertex_idx: u32) -> VertexOut {
// Basic properties of the vertex we're at.
var is_at_quad_end = i32(vertex_idx) % 2;
var quad_idx = i32(vertex_idx) / 6;
var local_idx = vertex_idx % 6u;
var top_bottom = f32(local_idx <= 1u || local_idx == 5u) * 2.0 - 1.0; // 1 for a top vertex, -1 for a bottom vertex.
let is_at_quad_end = i32(vertex_idx) % 2;
let quad_idx = i32(vertex_idx) / 6;
let local_idx = vertex_idx % 6u;
let top_bottom = f32(local_idx <= 1u || local_idx == 5u) * 2.0 - 1.0; // 1 for a top vertex, -1 for a bottom vertex.

// data at and before the vertex
var pos_data_idx = quad_idx + is_at_quad_end;
var pos_data_before = read_position_data(pos_data_idx - 1);
let pos_data_idx = quad_idx + is_at_quad_end;
let pos_data_before = read_position_data(pos_data_idx - 1);
var pos_data_current = read_position_data(pos_data_idx);
var pos_data_next = read_position_data(pos_data_idx + 1);
let pos_data_next = read_position_data(pos_data_idx + 1);

// Is this a degenerated quad? Collapse it!
// Are we at the end of a previous and start of a new line strip? If so, collapse the quad between them.
if is_at_quad_end == 1 && pos_data_before.strip_index != pos_data_current.strip_index {
pos_data_current = pos_data_before;
}
Expand All @@ -117,20 +84,20 @@ fn vs_main(@builtin(vertex_index) vertex_idx: u32) -> VertexOut {
quad_dir = normalize(quad_dir);

// Span up the vertex away from the line's axis, orthogonal to the direction to the camera
var to_camera = normalize(frame.camera_position - pos_data_current.pos);
var dir_up = normalize(cross(to_camera, quad_dir));
var pos = pos_data_current.pos + (strip_data.thickness * top_bottom) * dir_up;
let to_camera = normalize(frame.camera_position - pos_data_current.pos);
let dir_up = normalize(cross(to_camera, quad_dir));
let pos = pos_data_current.pos + (strip_data.thickness * top_bottom) * dir_up;

// Output, transform to projection space and done.
var out: VertexOut;
out.position = frame.projection_from_world * vec4<f32>(pos, 1.0);
out.position = frame.projection_from_world * Vec4(pos, 1.0);
out.color = strip_data.color;

return out;
}

@fragment
fn fs_main(in: VertexOut) -> @location(0) vec4<f32> {
fn fs_main(in: VertexOut) -> @location(0) Vec4 {
// TODO(andreas): Shading, rounded caps, etc.
return in.color;
}
16 changes: 9 additions & 7 deletions crates/re_renderer/shader/screen_triangle.wgsl
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
#import <./types.wgsl>

struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) texcoord: vec2<f32>,
@builtin(position) position: Vec4,
@location(0) texcoord: Vec2,
};

var<private> positions: array<vec2<f32>, 3> = array<vec2<f32>, 3>(
vec2<f32>(-1.0, -3.0),
vec2<f32>(-1.0, 1.0),
vec2<f32>(3.0, 1.0)
var<private> positions: array<Vec2, 3> = array<Vec2, 3>(
Vec2(-1.0, -3.0),
Vec2(-1.0, 1.0),
Vec2(3.0, 1.0)
);

@vertex
fn main(@builtin(vertex_index) vertex_index: u32) -> VertexOutput {
var out: VertexOutput;
out.position = vec4<f32>(positions[vertex_index], 0.0, 1.0);
out.position = Vec4(positions[vertex_index], 0.0, 1.0);
out.texcoord = out.position.xy * 0.5 + 0.5;
out.texcoord.y = 1.0 - out.texcoord.y;
return out;
Expand Down
27 changes: 14 additions & 13 deletions crates/re_renderer/shader/test_triangle.wgsl
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
#import <./frame_uniform.wgsl>
#import <./types.wgsl>
#import <./global_bindings.wgsl>

struct VertexOut {
@location(0) color: vec4<f32>,
@builtin(position) position: vec4<f32>,
@location(0) color: Vec4,
@builtin(position) position: Vec4,
};

var<private> v_positions: array<vec2<f32>, 3> = array<vec2<f32>, 3>(
vec2<f32>(0.0, 1.0),
vec2<f32>(1.0, -1.0),
vec2<f32>(-1.0, -1.0),
var<private> v_positions: array<Vec2, 3> = array<Vec2, 3>(
Vec2(0.0, 1.0),
Vec2(1.0, -1.0),
Vec2(-1.0, -1.0),
);

var<private> v_colors: array<vec4<f32>, 3> = array<vec4<f32>, 3>(
vec4<f32>(1.0, 0.0, 0.0, 1.0),
vec4<f32>(0.0, 1.0, 0.0, 1.0),
vec4<f32>(0.0, 0.0, 1.0, 1.0),
var<private> v_colors: array<Vec4, 3> = array<Vec4, 3>(
Vec4(1.0, 0.0, 0.0, 1.0),
Vec4(0.0, 1.0, 0.0, 1.0),
Vec4(0.0, 0.0, 1.0, 1.0),
);

@vertex
fn vs_main(@builtin(vertex_index) v_idx: u32) -> VertexOut {
var out: VertexOut;

out.position = frame.projection_from_world * vec4<f32>(v_positions[v_idx], 0.0, 1.0);
out.position = frame.projection_from_world * Vec4(v_positions[v_idx], 0.0, 1.0);
out.color = v_colors[v_idx];

return out;
}

@fragment
fn fs_main(in: VertexOut) -> @location(0) vec4<f32> {
fn fs_main(in: VertexOut) -> @location(0) Vec4 {
return in.color;
}
21 changes: 8 additions & 13 deletions crates/re_renderer/shader/tonemap.wgsl
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#import <./types.wgsl>
#import <./utils/srgb.wgsl>

struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) texcoord: vec2<f32>,
@builtin(position) position: Vec4,
@location(0) texcoord: Vec2,
};

// TODO(andreas): Move global bindings to shared include
Expand All @@ -10,19 +13,11 @@ var nearest_sampler: sampler;
@group(1) @binding(0)
var hdr_texture: texture_2d<f32>;

/// 0-1 gamma from 0-1 linear
fn srgb_from_linear(color_linear: vec3<f32>) -> vec3<f32> {
var selector = ceil(color_linear - 0.0031308);
var under = 12.92 * color_linear;
var over = 1.055 * pow(color_linear, vec3<f32>(0.41666)) - 0.055;
return mix(under, over, selector);
}

@fragment
fn main(in: VertexOutput) -> @location(0) vec4<f32> {
fn main(in: VertexOutput) -> @location(0) Vec4 {
// Note that we can't use a simple textureLoad using @builtin(position) here despite the lack of filtering.
// The issue is that positions provided by @builtin(position) are not dependent on the set viewport,
// but are about the location of the texel in the target texture.
var hdr = textureSample(hdr_texture, nearest_sampler, in.texcoord);
return vec4<f32>(srgb_from_linear(hdr.rgb), 1.0);
let hdr = textureSample(hdr_texture, nearest_sampler, in.texcoord);
return Vec4(srgb_from_linear(hdr.rgb), 1.0);
}
30 changes: 30 additions & 0 deletions crates/re_renderer/shader/types.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// As of writing typedefs can't be used for constructing vecN from a single item
// https://github.com/gfx-rs/naga/issues/2105

emilk marked this conversation as resolved.
Show resolved Hide resolved
type Vec2 = vec2<f32>;
type Vec3 = vec3<f32>;
type Vec4 = vec4<f32>;
type UVec2 = vec2<u32>;
type UVec3 = vec3<u32>;
type UVec4 = vec4<u32>;
type IVec2 = vec2<i32>;
type IVec3 = vec3<i32>;
type IVec4 = vec4<i32>;
type Mat4 = mat4x4<f32>;

// Following should be const expressions once available
// https://github.com/gfx-rs/naga/issues/1829

let f32min = -3.4028235e38;
let f32max = 3.4028235e38;
let f32eps = 0.00000011920928955078125;

let u32min = 0u;
let u32max = 0xFFFFFFFFu;

let X = Vec3(1.0, 0.0, 0.0);
let Y = Vec3(0.0, 1.0, 0.0);
let Z = Vec3(0.0, 0.0, 1.0);

let ZERO = Vec3(0.0, 0.0, 0.0);
let ONE = Vec3(1.0, 1.0, 1.0);
6 changes: 6 additions & 0 deletions crates/re_renderer/shader/utils/encoding.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// workaround for https://github.com/gfx-rs/naga/issues/2006
fn unpack4x8unorm_workaround(v: u32) -> vec4<f32> {
let shifted = vec4<u32>(v, v >> 8u, v >> 16u, v >> 24u);
let bytes = shifted & vec4<u32>(0xFFu);
return vec4<f32>(bytes) * (1.0 / 255.0);
}
25 changes: 25 additions & 0 deletions crates/re_renderer/shader/utils/srgb.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Converts a color from 0-1 sRGB to 0-1 linear
fn linear_from_srgb(srgb: Vec3) -> Vec3 {
let cutoff = ceil(srgb - 0.04045);
let under = srgb / 12.92;
let over = pow((srgb + 0.055) / 1.055, vec3<f32>(2.4));
return mix(under, over, cutoff);
}

// Converts a color from 0-1 sRGB to 0-1 linear, leaves alpha untouched
fn linear_from_srgba(srgb_a: Vec4) -> Vec4 {
return Vec4(linear_from_srgb(srgb_a.rgb), srgb_a.a);
}

// Converts a color from 0-1 linear to 0-1 sRGB
fn srgb_from_linear(color_linear: Vec3) -> Vec3 {
let selector = ceil(color_linear - 0.0031308);
let under = 12.92 * color_linear;
let over = 1.055 * pow(color_linear, vec3<f32>(0.41666)) - 0.055;
return mix(under, over, selector);
}

// Converts a color from 0-1 sRGB to 0-1 linear, leaves alpha untouched
fn srgba_from_linear(srgb_a: Vec4) -> Vec4 {
return Vec4(srgb_from_linear(srgb_a.rgb), srgb_a.a);
}
Loading