@@ -3,6 +3,7 @@ import { vec3 } from "gl-matrix";
3
3
4
4
5
5
export class Framebuffer {
6
+ public static glContextStencilBits = 0 ; //class static variable
6
7
public framebuffer : WebGLFramebuffer ;
7
8
public renderbuffer : WebGLRenderbuffer ;
8
9
public texture : WebGLTexture ;
@@ -70,10 +71,17 @@ export class Framebuffer {
70
71
gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_MIN_FILTER , gl . NEAREST ) ;
71
72
gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_WRAP_S , gl . CLAMP_TO_EDGE ) ;
72
73
gl . texParameteri ( gl . TEXTURE_2D , gl . TEXTURE_WRAP_T , gl . CLAMP_TO_EDGE ) ;
73
- if ( this . _glVersion === 1 ) {
74
+
75
+ //If the stencil bit is 8 bits or more, set to record the depth texture with DEPTH24_STENCIL8 if available (24+8 expands to a total of 32 bits to record depth => needs confirmation)
76
+ if ( Framebuffer . glContextStencilBits >= 8 ) {
77
+ //32bit(24+8) precision
78
+ gl . texImage2D ( gl . TEXTURE_2D , 0 , gl [ "DEPTH24_STENCIL8" ] , width , height , 0 , gl . DEPTH_STENCIL , gl [ "UNSIGNED_INT_24_8" ] , null ) ;
79
+ } else if ( this . _glVersion === 1 ) {
80
+ //8bit precision
74
81
gl . texImage2D ( gl . TEXTURE_2D , 0 , gl . DEPTH_COMPONENT , width , height , 0 , gl . DEPTH_COMPONENT , gl . UNSIGNED_SHORT , null ) ;
75
82
} else {
76
- gl . texImage2D ( gl . TEXTURE_2D , 0 , gl . DEPTH_COMPONENT16 , width , height , 0 , gl . DEPTH_COMPONENT , gl . UNSIGNED_SHORT , null ) ;
83
+ //16bit precision
84
+ gl . texImage2D ( gl . TEXTURE_2D , 0 , gl . DEPTH_COMPONENT16 , width , height , 0 , gl . DEPTH_COMPONENT , gl . UNSIGNED_INT , null ) ;
77
85
}
78
86
}
79
87
@@ -109,6 +117,23 @@ export class Framebuffer {
109
117
return result ;
110
118
}
111
119
120
+ public getPixelAsFloat ( x : number , y : number ) : number {
121
+ if ( ! this . isReady )
122
+ return null ;
123
+ var result = new Uint8Array ( 4 ) ;
124
+ this . gl . readPixels ( x , y , 1 , 1 , this . gl . RGBA , this . gl . UNSIGNED_BYTE , result ) ;
125
+ return this . decodeFloatFromRGBA ( result ) ;
126
+ }
127
+
128
+ public decodeFloatFromRGBA ( rgba : Uint8Array ) :number {
129
+ const rightVec4 = [ 1.0 , 1 / 255.0 , 1 / 65025.0 , 1 / 16581375.0 ] ;
130
+ const dot = ( rgba [ 0 ] / 255.0 ) * rightVec4 [ 0 ]
131
+ + ( rgba [ 1 ] / 255.0 ) * rightVec4 [ 1 ]
132
+ + ( rgba [ 2 ] / 255.0 ) * rightVec4 [ 2 ]
133
+ + ( rgba [ 3 ] / 255.0 ) * rightVec4 [ 3 ] ;
134
+ return dot ;
135
+ }
136
+
112
137
public getDepth ( x : number , y : number ) : number {
113
138
if ( ! this . isReady )
114
139
return null ;
@@ -135,15 +160,12 @@ export class Framebuffer {
135
160
const depths = this . getDepths ( points ) ;
136
161
137
162
return depths . map ( ( depth , i ) => {
138
- if ( depth === 255 ) { // infinity (= nothing, no value)
139
- return null ;
140
- }
141
163
142
164
// convert values to clip space where x and y are [-1, 1] and z is [0, 1]
143
165
const point = points [ i ] ;
144
166
const xc = point . x / this . width * 2.0 - 1.0 ;
145
167
const yc = point . y / this . height * 2.0 - 1.0 ;
146
- const zc = ( depth / 255.0 - 0.5 ) * 2.0 ;
168
+ const zc = ( depth - 0.5 ) * 2.0 ;
147
169
148
170
return vec3 . fromValues ( xc , yc , zc ) ;
149
171
} ) ;
@@ -177,20 +199,13 @@ export class Framebuffer {
177
199
}
178
200
179
201
const depth = this . getDepth ( x , y ) ;
180
- if ( depth === 255 ) { // infinity
181
- return null ;
182
- }
183
202
184
203
// convert values to clip space where x and y are [-1, 1] and z is [0, 1]
185
204
const xc = x / this . width * 2.0 - 1.0 ;
186
205
const yc = y / this . height * 2.0 - 1.0 ;
187
- const zc = ( depth / 255.0 - 0.5 ) * 2.0 ;
188
-
189
- const depthNear = Math . max ( depth - 1 , 0 ) ;
190
- const zcn = ( depthNear / 255.0 - 0.5 ) * 2.0 ;
191
-
192
- const depthFar = Math . min ( depth + 1 , 255 ) ;
193
- const zcf = ( depthFar / 255.0 - 0.5 ) * 2.0 ;
206
+ const zc = 0.5 ;
207
+ const zcn = 0.0 ;
208
+ const zcf = 1.0 ;
194
209
195
210
return {
196
211
far : vec3 . fromValues ( xc , yc , zcf ) ,
0 commit comments