@@ -2,99 +2,155 @@ import Regl from "regl";
2
2
import { mat4 } from "gl-matrix" ;
3
3
import Tweakpane from "tweakpane" ;
4
4
5
+ import { loadMesh } from "./geometry" ;
6
+ import { generatePencilTextures } from "./texture" ;
7
+ import { saveImage , loadImage } from "./utils" ;
5
8
import fragmentShader from "./frag.glsl?raw" ;
6
9
import vertexShader from "./vert.glsl?raw" ;
7
- import rawTexture from "../textures/texture_256_64_64.json" ;
8
- import bunny from "../models/bunny_1k_2_sub.json" ;
9
- import { loadMesh } from "./geometry" ;
10
- import {
11
- TextureData ,
12
- displayImageData ,
13
- generatePencilTextures ,
14
- } from "./texture" ;
15
-
16
- const pane = new Tweakpane ( { title : "Parameters" } ) ;
17
- const params = {
18
- scale : 15 ,
19
- zoom : 0.5 ,
20
- height : 0.2 ,
21
- rotate : true ,
22
- speed : 0.5 ,
23
- angle : 0 ,
24
- } ;
25
- pane . addInput ( params , "scale" , { min : 0 , max : 50 } ) ;
26
- pane . addInput ( params , "zoom" , { min : - 5 , max : 5 } ) ;
27
- pane . addInput ( params , "height" , { min : - 1 , max : 1 } ) ;
28
- pane . addSeparator ( ) ;
29
- pane . addInput ( params , "rotate" ) ;
30
- pane . addInput ( params , "speed" , { min : - 1.0 , max : 1.0 } ) ;
31
- pane . addInput ( params , "angle" , { min : 0 , max : 2 * Math . PI } ) ;
10
+ import pencilTexturesUrl from "../textures/texture_256_64_64.png" ;
11
+ import bunnyUrl from "../models/bunny_1k_2_sub.json?url" ;
32
12
33
13
const regl = Regl ( { extensions : [ "OES_standard_derivatives" ] } ) ;
34
14
35
- const width = rawTexture . width ;
36
- const height = rawTexture . height ;
37
- const numTextures = rawTexture . numTextures ;
38
- //const texture = generatePencilTextures(numTextures, width, height);
39
- //console.log(JSON.stringify(texture));
40
- const texture = new TextureData ( rawTexture . data , width , height , numTextures ) ;
41
- //displayImageData(texture);
42
-
43
- const pencilTextures = regl . texture ( {
44
- data : texture . data ,
45
- width : width ,
46
- height : height * numTextures ,
47
- mag : "linear" ,
48
- min : "mipmap" ,
49
- mipmap : true ,
50
- } ) ;
15
+ class Renderer {
16
+ async start ( ) {
17
+ this . initPane ( ) ;
18
+ await Promise . all ( [ this . initTextures ( ) , this . loadMesh ( bunnyUrl ) ] ) ;
19
+
20
+ regl . frame ( ( ) => {
21
+ if ( this . params . rotate ) {
22
+ this . params . angle =
23
+ ( this . params . angle + this . params . speed / 100.0 ) % ( 2 * Math . PI ) ;
24
+ this . pane . refresh ( ) ;
25
+ }
26
+ const t = this . params . angle ;
27
+ const radius = Math . pow ( 2 , - this . params . zoom ) ;
28
+ const height = this . params . height ;
29
+
30
+ regl . clear ( { color : [ 1 , 1 , 1 , 1 ] } ) ;
31
+ this . draw ( {
32
+ eye : [ radius * Math . cos ( t ) , height , radius * Math . sin ( t ) ] ,
33
+ center : [ 0 , height , 0 ] ,
34
+ } ) ;
35
+ } ) ;
36
+ }
37
+
38
+ initPane ( ) {
39
+ const pane = new Tweakpane ( { title : "Parameters" } ) ;
40
+ const params = {
41
+ scale : 15 ,
42
+ zoom : 0.8 ,
43
+ height : 0.2 ,
44
+ rotate : true ,
45
+ speed : 0.5 ,
46
+ angle : 0 ,
47
+ } ;
48
+
49
+ pane . addInput ( params , "scale" , { min : 0 , max : 50 } ) ;
50
+
51
+ const camera = pane . addFolder ( { title : "Camera" } ) ;
52
+ camera . addInput ( params , "zoom" , { min : - 5 , max : 5 } ) ;
53
+ camera . addInput ( params , "height" , { min : - 1 , max : 1 } ) ;
54
+ camera . addSeparator ( ) ;
55
+ camera . addInput ( params , "rotate" ) ;
56
+ camera . addInput ( params , "speed" , { min : - 1.0 , max : 1.0 } ) ;
57
+ camera . addInput ( params , "angle" , { min : 0 , max : 2 * Math . PI } ) ;
58
+
59
+ const textures = pane . addFolder ( { title : "Textures" } ) ;
60
+ const texParams = {
61
+ number : 64 ,
62
+ width : 64 ,
63
+ height : 64 ,
64
+ save : false ,
65
+ } ;
66
+ textures . addInput ( texParams , "number" , { min : 8 , max : 256 , step : 8 } ) ;
67
+ textures . addInput ( texParams , "width" , { min : 16 , max : 128 , step : 8 } ) ;
68
+ textures . addInput ( texParams , "height" , { min : 16 , max : 128 , step : 8 } ) ;
69
+ textures . addInput ( texParams , "save" ) ;
70
+ textures . addButton ( { title : "Generate" } ) . on ( "click" , ( ) => {
71
+ this . generateTextures ( texParams ) ;
72
+ } ) ;
73
+
74
+ this . pane = pane ;
75
+ this . params = params ;
76
+ }
51
77
52
- const { elements, attributes } = loadMesh ( bunny ) ;
78
+ async initTextures ( ) {
79
+ const textures = regl . texture ( {
80
+ data : await loadImage ( pencilTexturesUrl ) ,
81
+ mag : "linear" ,
82
+ min : "mipmap" ,
83
+ mipmap : true ,
84
+ } ) ;
85
+ this . setTextures ( 256 , textures ) ;
86
+ }
87
+
88
+ setTextures ( numTextures , pencilTextures ) {
89
+ this . numTextures = numTextures ;
90
+ this . pencilTextures = pencilTextures ;
91
+ }
92
+
93
+ generateTextures ( texParams ) {
94
+ const img = generatePencilTextures (
95
+ texParams . number ,
96
+ texParams . width ,
97
+ texParams . height
98
+ ) ;
99
+ const textures = regl . texture ( {
100
+ data : img . data ,
101
+ width : texParams . width ,
102
+ height : texParams . height * texParams . number ,
103
+ mag : "linear" ,
104
+ min : "mipmap" ,
105
+ mipmap : true ,
106
+ } ) ;
107
+ if ( texParams . save ) {
108
+ saveImage ( "textures.png" , img ) ;
109
+ }
110
+ this . setTextures ( texParams . number , textures ) ;
111
+ }
112
+
113
+ async loadMesh ( url ) {
114
+ const resp = await fetch ( url ) ;
115
+ const mesh = await resp . json ( ) ;
116
+ const { attributes, elements } = loadMesh ( mesh ) ;
117
+ this . attributes = attributes ;
118
+ this . elements = elements ;
119
+ }
120
+ }
53
121
54
- const draw = regl ( {
122
+ Renderer . prototype . draw = regl ( {
55
123
frag : fragmentShader ,
56
124
vert : vertexShader ,
57
- attributes,
58
- elements,
125
+ attributes : {
126
+ position : regl . this ( "attributes.position" ) ,
127
+ normal : regl . this ( "attributes.normal" ) ,
128
+ indexInTriangle : regl . this ( "attributes.indexInTriangle" ) ,
129
+ curvature : regl . this ( "attributes.curvature" ) ,
130
+ } ,
131
+ elements : regl . this ( "elements" ) ,
59
132
uniforms : {
60
133
eye : regl . prop ( "eye" ) ,
61
- view : ( context , props ) => {
134
+ view : ( _ , props ) => {
62
135
return mat4 . lookAt ( [ ] , props . eye , props . center , [ 0 , 1 , 0 ] ) ;
63
136
} ,
64
- projection : ( { viewportWidth, viewportHeight } ) =>
65
- mat4 . perspective (
66
- [ ] ,
67
- Math . PI / 4 ,
68
- viewportWidth / viewportHeight ,
69
- 0.01 ,
70
- 1000
71
- ) ,
72
- resolution : ( c ) => [
73
- c . drawingBufferWidth ,
74
- c . drawingBufferHeight ,
75
- Math . min ( c . drawingBufferWidth , c . drawingBufferHeight ) ,
137
+ projection : ( { viewportWidth, viewportHeight } ) => {
138
+ const ratio = viewportWidth / viewportHeight ;
139
+ return mat4 . perspective ( [ ] , Math . PI / 4 , ratio , 0.01 , 1000 ) ;
140
+ } ,
141
+ resolution : ( { drawingBufferWidth, drawingBufferHeight } ) => [
142
+ drawingBufferWidth ,
143
+ drawingBufferHeight ,
144
+ Math . min ( drawingBufferWidth , drawingBufferHeight ) ,
76
145
] ,
77
146
pixelRatio : regl . context ( "pixelRatio" ) ,
78
- scale : ( ) => params . scale , // How large the textures are scaled in world space
79
- numTextures : ( ) => 1.0 * numTextures ,
80
- pencilTextures : ( ) => pencilTextures ,
147
+ scale : regl . this ( "params.scale" ) , // How large the textures are scaled in world space
148
+ numTextures : regl . this ( "numTextures" ) ,
149
+ pencilTextures : regl . this ( "pencilTextures" ) ,
150
+ } ,
151
+ cull : {
152
+ enable : true ,
81
153
} ,
82
154
} ) ;
83
155
84
- regl . frame ( ( ) => {
85
- if ( params . rotate ) {
86
- params . angle = ( params . angle + params . speed / 100.0 ) % ( 2 * Math . PI ) ;
87
- pane . refresh ( ) ;
88
- }
89
- const t = params . angle ;
90
- const radius = Math . pow ( 2 , - params . zoom ) ;
91
- const height = params . height ;
92
-
93
- regl . clear ( {
94
- color : [ 1 , 1 , 1 , 1 ] ,
95
- } ) ;
96
- draw ( {
97
- eye : [ radius * Math . cos ( t ) , height , radius * Math . sin ( t ) ] ,
98
- center : [ 0 , height , 0 ] ,
99
- } ) ;
100
- } ) ;
156
+ new Renderer ( ) . start ( ) ;
0 commit comments