11import { accessViewportSize } from '@typegpu/common' ;
2- import tgpu , {
3- type TgpuBuffer ,
4- type TgpuRoot ,
5- type UniformFlag ,
6- } from 'typegpu' ;
2+ import tgpu , { type TgpuRoot , type TgpuUniform } from 'typegpu' ;
3+ import { normalize } from 'typegpu/std' ;
74import * as d from 'typegpu/data' ;
85import { mat4 , vec3 } from 'wgpu-matrix' ;
96
@@ -24,60 +21,47 @@ export const CameraStruct = d.struct({
2421 field_of_view : d . f32 ,
2522} ) ;
2623
27- export const getCameraProps = tgpu [ '~unstable' ]
28- . accessor ( CameraStruct )
29- . $name ( 'getCameraProps' ) ;
30-
31- export const constructRayPos = tgpu [ '~unstable' ]
32- . fn (
33- [ ] ,
34- d . vec3f ,
35- ) ( /* wgsl */ `() -> vec3f {
36- let camera = getCameraProps;
37- return (camera.inv_view_matrix * vec4(0., 0., 0., 1.)).xyz;
38- }` )
39- . $uses ( { getCameraProps } ) ;
40-
41- export const constructRayDir = tgpu [ '~unstable' ]
42- . fn (
43- [ d . vec2f ] ,
44- d . vec3f ,
45- ) ( /* wgsl */ `(coord: vec2f) -> vec3f {
46- let camera = getCameraProps;
47- let viewport_size = accessViewportSize;
48- var view_coords = (coord - viewport_size / 2.) / viewport_size.y; // y in [-0.5, 0.5]
49- view_coords = view_coords * camera.field_of_view;
50-
51- var view_ray_dir = vec3f(
52- view_coords,
53- -0.5,
54- );
55- view_ray_dir.y *= -1.;
56- view_ray_dir = normalize(view_ray_dir);
24+ export const cameraPropsAccess = tgpu [ '~unstable' ] . accessor ( CameraStruct ) ;
25+
26+ export const constructRayPos = tgpu . fn (
27+ [ ] ,
28+ d . vec3f ,
29+ ) ( ( ) => cameraPropsAccess . $ . inv_view_matrix . mul ( d . vec4f ( 0 , 0 , 0 , 1 ) ) . xyz ) ;
30+
31+ export const constructRayDir = tgpu . fn (
32+ [ d . vec2f ] ,
33+ d . vec3f ,
34+ ) ( ( coord ) => {
35+ const viewCoords = coord
36+ . sub ( accessViewportSize . $ . div ( 2 ) )
37+ . div ( accessViewportSize . $ . y )
38+ // y in [-0.5, 0.5]
39+ . mul ( cameraPropsAccess . $ . field_of_view ) ;
5740
58- return (camera.inv_view_matrix * vec4(view_ray_dir, 0.)).xyz;
59- }` )
60- . $uses ( { getCameraProps, accessViewportSize } )
61- . $name ( 'construct_ray_dir' ) ;
41+ const viewRayDir = normalize ( d . vec3f ( viewCoords , - 0.5 ) ) ;
42+ viewRayDir . y *= - 1 ;
43+
44+ return cameraPropsAccess . $ . inv_view_matrix . mul ( d . vec4f ( viewRayDir , 0 ) ) . xyz ;
45+ } ) ;
6246
6347export class Camera {
64- public readonly cameraBuffer : TgpuBuffer < typeof CameraStruct > & UniformFlag ;
48+ #lastTime = performance . now ( ) ;
6549
66- private _lastTime = Date . now ( ) ;
50+ readonly cameraUniform : TgpuUniform < typeof CameraStruct > ;
6751
6852 constructor ( root : TgpuRoot ) {
69- this . cameraBuffer = root . createBuffer ( CameraStruct ) . $usage ( 'uniform' ) ;
53+ this . cameraUniform = root . createUniform ( CameraStruct ) ;
7054 }
7155
7256 update ( ) {
73- const now = Date . now ( ) ;
74- const dt = ( now - this . _lastTime ) / 1000 ;
75- this . _lastTime = now ;
57+ const now = performance . now ( ) ;
58+ const dt = ( now - this . #lastTime ) / 1000 ;
59+ this . #lastTime = now ;
7660
7761 const invViewMatrix = mat4 . identity ( d . mat4x4f ( ) ) ;
7862
79- const manualOrientation = ( store . get ( cameraOrientationControlAtom ) / 180 ) *
80- Math . PI ;
63+ const manualOrientation =
64+ ( store . get ( cameraOrientationControlAtom ) / 180 ) * Math . PI ;
8165 const autoOrientation = ( store . get ( autoCameraOrientation ) / 180 ) * Math . PI ;
8266
8367 const rad = store . get ( autoRotateControlAtom )
@@ -108,8 +92,7 @@ export class Camera {
10892
10993 const fovAngle = ( store . get ( cameraFovControlAtom ) / 180 ) * Math . PI ;
11094
111- // Writing to buffer
112- this . cameraBuffer . write ( {
95+ this . cameraUniform . write ( {
11396 view_matrix : viewMatrix ,
11497 inv_view_matrix : invViewMatrix ,
11598 field_of_view : Math . tan ( fovAngle / 2 ) ,
0 commit comments