@@ -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,19 @@ 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 ) ;
74
+
73
75
if ( this . _glVersion === 1 ) {
76
+ //8bit precision
74
77
gl . texImage2D ( gl . TEXTURE_2D , 0 , gl . DEPTH_COMPONENT , width , height , 0 , gl . DEPTH_COMPONENT , gl . UNSIGNED_SHORT , null ) ;
75
- } else {
76
- gl . texImage2D ( gl . TEXTURE_2D , 0 , gl . DEPTH_COMPONENT16 , width , height , 0 , gl . DEPTH_COMPONENT , gl . UNSIGNED_SHORT , null ) ;
78
+ }
79
+ else if ( Framebuffer . glContextStencilBits >= 8 ) {
80
+ //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)
81
+ //DEPTH24_STENCIL8 only available at glVersion 2
82
+ gl . texImage2D ( gl . TEXTURE_2D , 0 , gl [ "DEPTH24_STENCIL8" ] , width , height , 0 , gl . DEPTH_STENCIL , gl [ "UNSIGNED_INT_24_8" ] , null ) ;
83
+ }
84
+ else {
85
+ //16bit precision
86
+ gl . texImage2D ( gl . TEXTURE_2D , 0 , gl . DEPTH_COMPONENT16 , width , height , 0 , gl . DEPTH_COMPONENT , gl . UNSIGNED_INT , null ) ;
77
87
}
78
88
}
79
89
@@ -109,6 +119,23 @@ export class Framebuffer {
109
119
return result ;
110
120
}
111
121
122
+ public getPixelAsFloat ( x : number , y : number ) : number {
123
+ if ( ! this . isReady )
124
+ return null ;
125
+ var result = new Uint8Array ( 4 ) ;
126
+ this . gl . readPixels ( x , y , 1 , 1 , this . gl . RGBA , this . gl . UNSIGNED_BYTE , result ) ;
127
+ return this . decodeFloatFromRGBA ( result ) ;
128
+ }
129
+
130
+ public decodeFloatFromRGBA ( rgba : Uint8Array ) :number {
131
+ const rightVec4 = [ 1.0 , 1 / 255.0 , 1 / 65025.0 , 1 / 16581375.0 ] ;
132
+ const dot = ( rgba [ 0 ] / 255.0 ) * rightVec4 [ 0 ]
133
+ + ( rgba [ 1 ] / 255.0 ) * rightVec4 [ 1 ]
134
+ + ( rgba [ 2 ] / 255.0 ) * rightVec4 [ 2 ]
135
+ + ( rgba [ 3 ] / 255.0 ) * rightVec4 [ 3 ] ;
136
+ return dot ;
137
+ }
138
+
112
139
public getDepth ( x : number , y : number ) : number {
113
140
if ( ! this . isReady )
114
141
return null ;
@@ -135,15 +162,12 @@ export class Framebuffer {
135
162
const depths = this . getDepths ( points ) ;
136
163
137
164
return depths . map ( ( depth , i ) => {
138
- if ( depth === 255 ) { // infinity (= nothing, no value)
139
- return null ;
140
- }
141
165
142
166
// convert values to clip space where x and y are [-1, 1] and z is [0, 1]
143
167
const point = points [ i ] ;
144
168
const xc = point . x / this . width * 2.0 - 1.0 ;
145
169
const yc = point . y / this . height * 2.0 - 1.0 ;
146
- const zc = ( depth / 255.0 - 0.5 ) * 2.0 ;
170
+ const zc = ( depth - 0.5 ) * 2.0 ;
147
171
148
172
return vec3 . fromValues ( xc , yc , zc ) ;
149
173
} ) ;
@@ -177,20 +201,13 @@ export class Framebuffer {
177
201
}
178
202
179
203
const depth = this . getDepth ( x , y ) ;
180
- if ( depth === 255 ) { // infinity
181
- return null ;
182
- }
183
204
184
205
// convert values to clip space where x and y are [-1, 1] and z is [0, 1]
185
206
const xc = x / this . width * 2.0 - 1.0 ;
186
207
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 ;
208
+ const zc = 0.5 ;
209
+ const zcn = 0.0 ;
210
+ const zcf = 1.0 ;
194
211
195
212
return {
196
213
far : vec3 . fromValues ( xc , yc , zcf ) ,
0 commit comments