unsafe composition

This commit is contained in:
ethan merchant 2023-08-15 04:41:17 -04:00
parent f55e9ac7c0
commit 691e785195
11 changed files with 229 additions and 90 deletions

View file

@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
using StereoKit; using StereoKit;
// [StructLayout(LayoutKind.Sequential)] // [StructLayout(LayoutKind.Sequential)]
// struct BufferData { // struct oriel_buffer {
// public Vec3 position; // public Vec3 position;
// public float time; // public float time;
// } // }
@ -20,7 +20,7 @@ public class Oriel {
bool draggingOriel = false; bool draggingOriel = false;
Vec3 orielOffset = Vec3.Zero; Vec3 orielOffset = Vec3.Zero;
// MaterialBuffer<BufferData> buffer; // MaterialBuffer<oriel_buffer> buffer;
public void Start(Monolith mono, int bufferIndex) { public void Start(Monolith mono, int bufferIndex) {
this.mono = mono; this.mono = mono;
@ -28,10 +28,10 @@ public class Oriel {
bounds = new Bounds(Vec3.Zero, new Vec3(1f, 0.5f, 0.5f)); bounds = new Bounds(Vec3.Zero, new Vec3(1f, 0.5f, 0.5f));
bounds.center = new Vec3(0.5f, -0.25f, -1f); bounds.center = new Vec3(0.5f, -0.25f, -1f);
// buffer = new MaterialBuffer<BufferData>(bufferIndex); // buffer = new MaterialBuffer<oriel_buffer>(bufferIndex);
} }
// BufferData data = new BufferData(); // oriel_buffer data = new oriel_buffer();
public void Step() { public void Step() {
Vec3 rGlovePos = mono.rGlove.virtualGlove.position; Vec3 rGlovePos = mono.rGlove.virtualGlove.position;
Vec3 lGlovePos = mono.lGlove.virtualGlove.position; Vec3 lGlovePos = mono.lGlove.virtualGlove.position;

View file

@ -15,7 +15,7 @@ Texture2D tex; // : register(t0);
SamplerState tex_s; // : register(s0); SamplerState tex_s; // : register(s0);
cbuffer BufferData : register(b3) { cbuffer oriel_buffer : register(b3) {
float3 position; float3 position;
float time; float time;
}; };

View file

@ -2,10 +2,14 @@
//--name = dofdev/compositor //--name = dofdev/compositor
//--diffuse = white //--near = white
//--far = white
Texture2D diffuse : register(t0); Texture2D near : register(t0);
SamplerState diffuse_s : register(s0); SamplerState near_s : register(s0);
Texture2D far : register(t1);
SamplerState far_s : register(s1);
struct vsIn { struct vsIn {
float4 pos : SV_Position; float4 pos : SV_Position;
@ -13,6 +17,7 @@ struct vsIn {
float2 uv : TEXCOORD0; float2 uv : TEXCOORD0;
}; };
struct psIn { struct psIn {
float4 screen_pos : SV_Position;
float4 pos : SV_Position; float4 pos : SV_Position;
float3 world : WORLD; float3 world : WORLD;
float2 uv : TEXCOORD0; float2 uv : TEXCOORD0;
@ -26,37 +31,84 @@ psIn vs(vsIn input, uint id : SV_InstanceID) {
o.world = mul(input.pos, sk_inst[id].world).xyz; o.world = mul(input.pos, sk_inst[id].world).xyz;
o.pos = mul(float4(o.world, 1), sk_viewproj[o.view_id]); o.pos = mul(float4(o.world, 1), sk_viewproj[o.view_id]);
o.screen_pos = input.pos;
// float3 normal = normalize(mul(input.norm, (float3x3)sk_inst[id].world)); // float3 normal = normalize(mul(input.norm, (float3x3)sk_inst[id].world));
o.uv = input.uv; o.uv = input.uv;
o.uv.y = 1 - o.uv.y; // gl flip
return o; return o;
} }
float far_clip = 1.0; // 1.0 for anything behind the near of the oriel is clipped
float near_flatten = 1.0; // 1.0 for anything behind the near of the oriel having its depth be set to the near of the oriel
float front_clip = 1.0; // same as far_clip
float front_flatten = 1.0; // same as near_flatten
static const float NEAR = 0.01;
static const float FAR = 100.0;
// clip depth -> view depth
float depth_cv(float d) {
// 32 bit DepthTexture *clip space
return (NEAR * FAR) / (FAR - d * (FAR - NEAR));
}
float4 ps(psIn input) : SV_TARGET { float4 ps(psIn input) : SV_TARGET {
float4 tex = diffuse.Sample(diffuse_s, input.uv);
return tex;
// 16 bit DepthTexture *non-linear* depth
// render depth for debug by undoing the non-linear depth rcp
float reciprocal_value = tex.r;
float max_distance = 100.0;
float depth = 1.0 / (reciprocal_value * (1.0 / max_distance) + 1.0); // uint stencil = tex.a * 255.0;
// float2 screen_uv = input.pos.xy / input.pos.w; // flip y?
// screen_uv.y = 1 - screen_uv.y;
return float4(depth, depth, depth, 1); // screen_uv.x = 744 - screen_uv.x * 744;
// screen_uv.y = 1050 - screen_uv.y * 1050;
// if (depth > 0.0) { float2 screen_uv = float2(input.pos.x * sk_aspect_ratio(input.view_id) / 744.0, input.pos.y / 1050.0);
// depth = 1.0;
// screen_uv.y *= sk_aspect_ratio(input.view_id);
float oriel_n = depth_cv(near.Sample(near_s, screen_uv).r);
// if (oriel_n < 1.0) {
// discard;
// }
// clip(2 - oriel_n);
// float oriel_f = depth_cv(far.Sample(far_s, screen_uv).r);
// clip
// float4 pos_view = mul(float4(input.world, 1), sk_viewproj[input.view_id]);
// pos_view = input.pos;
// float d = (pos_view * rcp(pos_view.w)).z;
// d = depth_cv(d);
// if (d < oriel_n) {
// discard;
// }
// if (d > oriel_f) {
// discard;
// } // }
// depth = rcp(depth); // if (depth_cv(near.Sample(near_s, pos_view.xy / input.pos.w).r) < 1.0) {
// discard;
// float4 og = mul(float4(input.world, 1), sk_viewproj[input.view_id]); // }
// float depth = (og * rcp(og.w)).z;
// return tex; // float4(tex.a, tex.a, tex.a, 1); // screen space checkerboard using fmod
// float v = -rcp(-val.r); float checkerboard = fmod(floor(input.uv.x * 8.0) + floor(input.uv.y * 8.0), 2);
// v = val.r; float checkeruv = fmod(floor(screen_uv.x * 8.0) + floor(screen_uv.y * 8.0), 2);
// return float4(v, v, v, 1); return float4(checkerboard, screen_uv.y, checkeruv, 1);
// // new depth
// if(depth < front_depth) {
// depth = lerp(0, front_depth, front_clip); // clip is t
// } else if(depth > near_depth) {
// depth = lerp(FAR, near_depth, far_clip); // clip is t
// } else {
// out_depth = depth;
// }
return float4(1,0,1,1);
} }

15
add/shaders/dofdev.hlsli Normal file
View file

@ -0,0 +1,15 @@
#ifndef _DOFDEV_HLSLI
#define _DOFDEV_HLSLI
struct oriel {
float4x4 transform;
float3 dimensions;
float x;
}; // sizeof(oriel) = 80bytes
cbuffer oriel_buffer : register(b3) {
oriel oriels[819]; // UINT16_MAX(65535) / sizeof(oriel) = 819
};
#endif

View file

@ -115,10 +115,9 @@ psOut ps(psIn input) {
if (oll < 99) { if (oll < 99) {
o.color = float4(1, 1, 1, 1); o.color = float4(1, 1, 1, 1);
float3 origin2 = origin + oll * direction; float3 pos_world = origin + oll * direction;
float4 og = mul(float4(origin2, 1), sk_viewproj[input.view_id]); float4 pos_view = mul(float4(pos_world, 1), sk_viewproj[input.view_id]);
// o.depth = og.z; o.depth = (pos_view * rcp(pos_view.w)).z;
o.depth = (og * rcp(og.w)).z;
return o; return o;
} }

View file

@ -1,4 +1,5 @@
#include "stereokit.hlsli" #include "stereokit.hlsli"
#include "dofdev.hlsli"
//--name = dofdev/room //--name = dofdev/room
@ -11,12 +12,6 @@ float tex_scale;
Texture2D diffuse : register(t0); Texture2D diffuse : register(t0);
SamplerState diffuse_s : register(s0); SamplerState diffuse_s : register(s0);
cbuffer BufferData : register(b3) {
float4x4 oriel_matrix;
float3 dimensions;
float time;
};
struct vsIn { struct vsIn {
float4 pos : SV_Position; float4 pos : SV_Position;
float3 norm : NORMAL0; float3 norm : NORMAL0;
@ -46,8 +41,8 @@ psIn vs(vsIn input, uint id : SV_InstanceID) {
float3 normal = normalize(mul(input.norm, (float3x3)sk_inst[id].world)); float3 normal = normalize(mul(input.norm, (float3x3)sk_inst[id].world));
o.uv = input.uv * tex_scale; o.uv = input.uv * tex_scale;
o.color = color * input.col * sk_inst[id].color; o.color = color * input.col * sk_inst[id].color;
// o.color.rgb *= Lighting(normal); // o.color.rgb *= Lighting(normal);
return o; return o;
} }
@ -67,8 +62,8 @@ float raymarch(float4x4 m, float3 ro, float3 rd) {
float dist = 0.0; float dist = 0.0;
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
float3 pos = ro + dist * rd; float3 pos = ro + dist * rd;
float step = sdBox(pos, dimensions / 2.0); float step = sdBox(pos, oriels[0].dimensions / 2.0);
// float step = sdSphere(pos, dimensions.y / 2.0); // float step = sdSphere(pos, oriels[0].dimensions.y / 2.0);
if (step < 0.0001 || dist > 100) break; // 100 == distmax if (step < 0.0001 || dist > 100) break; // 100 == distmax
dist += step; dist += step;
} }
@ -101,7 +96,9 @@ float4 ps(psIn input) : SV_TARGET {
float3 ro = input.campos; float3 ro = input.campos;
float3 rd = normalize(input.world - ro); float3 rd = normalize(input.world - ro);
float ol = raymarch(oriel_matrix, ro, rd); float ol = raymarch(oriels[0].transform, ro, rd);
// we don't need to clip here anymore ^-^
// *just keeping this for a working reference, for a refactoring later
clip(-(100 - (ol + 1))); clip(-(100 - (ol + 1)));
// if ((100 - (ol + 1)) > 0) { // if ((100 - (ol + 1)) > 0) {

View file

@ -1,6 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net7</TargetFramework> <TargetFramework>net7</TargetFramework>
<SKAssetFolder>add</SKAssetFolder> <SKAssetFolder>add</SKAssetFolder>
@ -8,7 +10,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="StereoKit" Version="0.3.7-preview.1619" /> <PackageReference Include="StereoKit" Version="0.3.7-preview.1667" />
<!-- <PackageReference Include="System.Speech" Version="5.0.0" /> --> <!-- <PackageReference Include="System.Speech" Version="5.0.0" /> -->
</ItemGroup> </ItemGroup>

View file

@ -8,50 +8,111 @@ public class Compositor {
Greenyard.Mono greenyard = new Greenyard.Mono(); Greenyard.Mono greenyard = new Greenyard.Mono();
// bool other = false; // bool other = false;
Tex tex, depth; Tex tex_near, depth_near;
Tex tex_far, depth_far;
Material mat_near, mat_far;
Material mat = new Material(Shader.FromFile("shaders/compositor.hlsl")); Material mat = new Material(Shader.FromFile("shaders/compositor.hlsl"));
public void Init() { public void Init() {
tex = new Tex(TexType.Rendertarget); tex_near = new Tex(TexType.Rendertarget);
tex.SetSize(512, 512); tex_near.SetSize(512, 512);
depth = tex.AddZBuffer(TexFormat.Depth32); // DepthStencil depth_near = tex_near.AddZBuffer(TexFormat.Depth32); // DepthStencil
mat[MatParamName.DiffuseTex] = depth;
tex_far = new Tex(TexType.Rendertarget);
tex_far.SetSize(512, 512);
depth_far = tex_far.AddZBuffer(TexFormat.Depth32); // DepthStencil
mat_near = Material.Unlit.Copy();
mat_near.FaceCull = Cull.Back;
mat_far = Material.Unlit.Copy();
mat_far.FaceCull = Cull.Front;
mat["near"] = depth_near;
mat["far"] = depth_far;
mat.FaceCull = Cull.None; mat.FaceCull = Cull.None;
// Renderer.Blit(tex, newMat) // Renderer.Blit(tex, newMat)
backrooms.Init(); backrooms.Init();
greenyard.Init(); greenyard.Init();
} }
public void Frame() { public void Frame() {
Mono mono = Mono.inst; Mono mono = Mono.inst;
Rig rig = mono.rig;
if (Input.Key(Key.Space).IsJustActive()) { if (false) {
// add the depth tex color.r's up and see if they are > 0 Pose oriel = new(
float r = 0; V.XYZ(0, 1.6f, -0.4f),
Color32[] cols = depth.GetColors(); Quat.Identity
for (int i = 0; i < cols.Length; i++) { );
r += cols[i].r; Vec3 oriel_scale = new(
} 0.2f, 0.1f, 0.2f
Console.WriteLine($"r: {r}"); );
// oriel_n
Mesh.Cube.Draw(
mat_near,
oriel.ToMatrix(1),
Color.White,
RenderLayer.Layer1
);
Renderer.RenderTo(tex_near,
Renderer.CameraRoot, // will need separate matrices+ for each eye
Matrix.Perspective(90, 1, 1*U.cm, 100),
RenderLayer.Layer1 // RenderLayer.All & ~RenderLayer.Layer1
);
// oriel_f
Mesh.Cube.Draw(
mat_far,
oriel.ToMatrix(1),
Color.White,
RenderLayer.Layer2
);
Renderer.RenderTo(tex_far,
Renderer.CameraRoot, // will need separate matrices+ for each eye
Matrix.Perspective(90, 1, 1*U.cm, 100),
RenderLayer.Layer2 // RenderLayer.All & ~RenderLayer.Layer2
);
// oriel_content debug
Mesh.Quad.Draw(mat,
Matrix.TRS(
V.XYZ(0, 0, 0 * U.cm),
Quat.FromAngles(0, 180, 0),
1
) * oriel.ToMatrix(1)
);
} }
Default.MeshQuad.Draw(mat,
Matrix.TRS(V.XYZ(-0.90f, 1.16f, 1.44f), Quat.LookDir(0.63f, 0.78f, 0.02f), 0.5f)
);
Renderer.RenderTo(tex,
Matrix.TR(V.XYZ(-0.90f, 1.16f, 1.44f), Quat.LookDir(0.63f, 0.78f, 0.02f)),
Matrix.Perspective(60, 1, 0.1f, 100),
RenderLayer.All, // & ~RenderLayer.Layer1
RenderClear.All,
default(Rect)
);
// backrooms.oriel.Frame();
// optimize by making it more of a composition texture rather than depth textures
/*
SK
Plane.Plane(Vec3 pointOnPlane1, Vec3 pointOnPlane2, Vec3 pointOnPlane3)
pointOnPlane3: Third point on the plane.
Creates a plane from 3 points that are directly on that plane.
use this for that hand tracking mouse cursor
and then make the delta of the hand motion relative to the hand rotation
just like a mouse ^-^
painfully easy, so focus on which joint points are being tracked well
to use for the 'sensor position' + offset*
*/
backrooms.oriel.Frame();
// greenyard.oriel.Frame(); // greenyard.oriel.Frame();
// // mono.space.Frame(); // // mono.space.Frame();

View file

@ -1,24 +1,24 @@
namespace Oriels; namespace Oriels;
public class Mono { public class Mono {
private static readonly Lazy<Oriels.Mono> lazy = new Lazy<Oriels.Mono>(() => new Oriels.Mono()); private static readonly Lazy<Mono> lazy = new Lazy<Mono>(() => new Mono());
public static Oriels.Mono inst { get { return lazy.Value; } } public static Mono inst { get { return lazy.Value; } }
public PR.Noise noise = new PR.Noise(939949595); public PR.Noise noise = new(939949595);
public Mat mat = new Mat(); public Mat mat = new();
public Rig rig = new Rig(); public Rig rig = new();
public Space space = new Space(); public Space space = new();
public Compositor compositor = new Compositor(); public Compositor compositor = new();
// ------------------------------------------------- // -------------------------------------------------
public Interaction[] interactions; public Interaction[] interactions;
public ColorCube colorCube = new ColorCube(); public ColorCube colorCube = new();
public Glove rGlove = new Glove(true), lGlove = new Glove(false); public Glove rGlove = new(true), lGlove = new(false);
public Glove Glove(bool chirality) { return chirality ? rGlove : lGlove; } public Glove Glove(bool chirality) { return chirality ? rGlove : lGlove; }
// ------------------------------------------------- // -------------------------------------------------
@ -58,11 +58,11 @@ public class Mono {
Spatial spatial = new Spatial(new Vec3(-1, 0.76f, 0.666f)); Spatial spatial = new (new Vec3(-1, 0.76f, 0.666f));
Cursor cursor = new Cursor(); Cursor cursor = new();
Drawer drawerA = new Drawer(new Pose(new Vec3(-0.8f, 0.6f, 1.4f), Quat.FromAngles(0, 90f, 0))); Drawer drawerA = new (new Pose(new Vec3(-0.8f, 0.6f, 1.4f), Quat.FromAngles(0, 90f, 0)));
Drawer drawerB = new Drawer(new Pose(new Vec3(-0.8f, 0.6f, 0.95f), Quat.FromAngles(0, 90f, 0))); Drawer drawerB = new (new Pose(new Vec3(-0.8f, 0.6f, 0.95f), Quat.FromAngles(0, 90f, 0)));
Drawer drawerC = new Drawer(new Pose(new Vec3(-0.8f, 0.6f, 0.5f), Quat.FromAngles(0, 90f, 0))); Drawer drawerC = new (new Pose(new Vec3(-0.8f, 0.6f, 0.5f), Quat.FromAngles(0, 90f, 0)));
public void Frame() { public void Frame() {

View file

@ -2,15 +2,20 @@ using System.Runtime.InteropServices;
namespace Oriels; namespace Oriels;
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
struct BufferData { unsafe struct oriel {
public Matrix matrix; public Matrix matrix;
public Vec3 dimensions; public Vec3 dimensions;
public float time; public float x;
}
[StructLayout(LayoutKind.Sequential)]
unsafe struct oriel_buffer {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 819)]
public oriel[] oriels;
} }
public class Space { public class Space {
MaterialBuffer<BufferData> buffer; MaterialBuffer<oriel_buffer> buffer;
BufferData data = new BufferData(); oriel_buffer data = new oriel_buffer();
Material matFloor = new Material(Shader.Default); Material matFloor = new Material(Shader.Default);
Model shed = Model.FromFile("shed/shed.glb", Shader.FromFile("shaders/room.hlsl")); Model shed = Model.FromFile("shed/shed.glb", Shader.FromFile("shaders/room.hlsl"));
@ -18,7 +23,8 @@ public class Space {
Solid floor; Solid floor;
public Space() { public Space() {
buffer = new MaterialBuffer<BufferData>(3); // index data.oriels = new oriel[819]; // match dofdev.hlsli
buffer = new MaterialBuffer<oriel_buffer>(3); // index
// recenter the nodes in the leek model // recenter the nodes in the leek model
// so that the leek is centered at the origin // so that the leek is centered at the origin
@ -78,8 +84,12 @@ public class Space {
// data.matrix = (Matrix)System.Numerics.Matrix4x4.Transpose(oriel.matrixInv); // data.matrix = (Matrix)System.Numerics.Matrix4x4.Transpose(oriel.matrixInv);
// data.dimensions = oriel.bounds.dimensions; // data.dimensions = oriel.bounds.dimensions;
data.matrix = (Matrix)System.Numerics.Matrix4x4.Transpose(Matrix.T(Vec3.Up)); data.oriels[0].matrix = (Matrix)System.Numerics.Matrix4x4.Transpose(
data.dimensions = new Vec3(0.1f, 0.1f, 0.1f); Matrix.T(
V.XYZ(0, 1, 1.6f)
).Inverse // invert for sdf rendering ~
);
data.oriels[0].dimensions = new Vec3(0.4f, 0.3f, 0.3f);
buffer.Set(data); buffer.Set(data);

View file

@ -1,5 +1,6 @@
global using System; global using System;
global using StereoKit; global using StereoKit;
using System.Text.RegularExpressions;
// global using Oriels; // global using Oriels;
SKSettings settings = new SKSettings { SKSettings settings = new SKSettings {
@ -19,9 +20,11 @@ Input.HandVisible(Handed.Max, true);
Renderer.Scaling = 2; Renderer.Scaling = 2;
Renderer.Multisample = 0; Renderer.Multisample = 0;
Renderer.SetClip(0.02f, 100f); Renderer.SetClip(0.01f, 100f);
Renderer.EnableSky = false; Renderer.EnableSky = false;
Renderer.ClearColor = new Color(0f / 256f, 162f / 256f, 206f / 256f); Renderer.ClearColor = new Color(0f / 256f, 162f / 256f, 206f / 256f);
Renderer.LayerFilter = RenderLayer.All & ~RenderLayer.Layer1 & ~RenderLayer.Layer2;
Renderer.SetFOV(90f);
Oriels.Mono mono = Oriels.Mono.inst; Oriels.Mono mono = Oriels.Mono.inst;
mono.Init(); mono.Init();