Skip to content

Broken fragment shader in camera / cinematic example #13729

@moraxy

Description

@moraxy
Description of the problem

The camera / cinematic example is currently broken due to an error in its fragment shaders:

THREE.WebGLProgram: shader error:  0 gl.VALIDATE_STATUS false gl.getProgramInfoLog invalid shaders
ERROR: 0:248: 'DEPTH_PACKING' : unexpected token after conditional expression

The line in question is in BokehShader2.js

"float getDepth( const in vec2 screenPosition ) {",
" #if DEPTH_PACKING == 1",
" return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );",
" #else",
" return texture2D( tDepth, screenPosition ).x;",
" #endif",
"}",

and apparently the final shader's just missing the appropriate #define for DEPTH_PACKING, I guess? (see console log below)

For reference: BokehShader2.js is also used in postprocessing / dof, no errors there.

Broken shader dump from console:

1: precision highp float;
2: precision highp int;
3: #define SHADER_NAME ShaderMaterial
4: #define RINGS 3
5: #define SAMPLES 4
6: #define GAMMA_FACTOR 2
7: uniform mat4 viewMatrix;
8: uniform vec3 cameraPosition;
9: #define TONE_MAPPING
10: #ifndef saturate
11: 	#define saturate(a) clamp( a, 0.0, 1.0 )
12: #endif
13: uniform float toneMappingExposure;
14: uniform float toneMappingWhitePoint;
15: vec3 LinearToneMapping( vec3 color ) {
16: 	return toneMappingExposure * color;
17: }
18: vec3 ReinhardToneMapping( vec3 color ) {
19: 	color *= toneMappingExposure;
20: 	return saturate( color / ( vec3( 1.0 ) + color ) );
21: }
22: #define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )
23: vec3 Uncharted2ToneMapping( vec3 color ) {
24: 	color *= toneMappingExposure;
25: 	return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );
26: }
27: vec3 OptimizedCineonToneMapping( vec3 color ) {
28: 	color *= toneMappingExposure;
29: 	color = max( vec3( 0.0 ), color - 0.004 );
30: 	return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );
31: }
32: 
33: vec3 toneMapping( vec3 color ) { return LinearToneMapping( color ); }
34: 
35: vec4 LinearToLinear( in vec4 value ) {
36: 	return value;
37: }
38: vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {
39: 	return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );
40: }
41: vec4 LinearToGamma( in vec4 value, in float gammaFactor ) {
42: 	return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );
43: }
44: vec4 sRGBToLinear( in vec4 value ) {
45: 	return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );
46: }
47: vec4 LinearTosRGB( in vec4 value ) {
48: 	return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );
49: }
50: vec4 RGBEToLinear( in vec4 value ) {
51: 	return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );
52: }
53: vec4 LinearToRGBE( in vec4 value ) {
54: 	float maxComponent = max( max( value.r, value.g ), value.b );
55: 	float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );
56: 	return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );
57: }
58: vec4 RGBMToLinear( in vec4 value, in float maxRange ) {
59: 	return vec4( value.xyz * value.w * maxRange, 1.0 );
60: }
61: vec4 LinearToRGBM( in vec4 value, in float maxRange ) {
62: 	float maxRGB = max( value.x, max( value.g, value.b ) );
63: 	float M      = clamp( maxRGB / maxRange, 0.0, 1.0 );
64: 	M            = ceil( M * 255.0 ) / 255.0;
65: 	return vec4( value.rgb / ( M * maxRange ), M );
66: }
67: vec4 RGBDToLinear( in vec4 value, in float maxRange ) {
68: 	return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );
69: }
70: vec4 LinearToRGBD( in vec4 value, in float maxRange ) {
71: 	float maxRGB = max( value.x, max( value.g, value.b ) );
72: 	float D      = max( maxRange / maxRGB, 1.0 );
73: 	D            = min( floor( D ) / 255.0, 1.0 );
74: 	return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );
75: }
76: const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );
77: vec4 LinearToLogLuv( in vec4 value )  {
78: 	vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;
79: 	Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));
80: 	vec4 vResult;
81: 	vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;
82: 	float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
83: 	vResult.w = fract(Le);
84: 	vResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;
85: 	return vResult;
86: }
87: const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );
88: vec4 LogLuvToLinear( in vec4 value ) {
89: 	float Le = value.z * 255.0 + value.w;
90: 	vec3 Xp_Y_XYZp;
91: 	Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);
92: 	Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;
93: 	Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;
94: 	vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;
95: 	return vec4( max(vRGB, 0.0), 1.0 );
96: }
97: 
98: vec4 mapTexelToLinear( vec4 value ) { return LinearToLinear( value ); }
99: vec4 envMapTexelToLinear( vec4 value ) { return LinearToLinear( value ); }
100: vec4 emissiveMapTexelToLinear( vec4 value ) { return LinearToLinear( value ); }
101: vec4 linearToOutputTexel( vec4 value ) { return LinearToLinear( value ); }
102: 
103: #define PI 3.14159265359
104: #define PI2 6.28318530718
105: #define PI_HALF 1.5707963267949
106: #define RECIPROCAL_PI 0.31830988618
107: #define RECIPROCAL_PI2 0.15915494
108: #define LOG2 1.442695
109: #define EPSILON 1e-6
110: #define saturate(a) clamp( a, 0.0, 1.0 )
111: #define whiteCompliment(a) ( 1.0 - saturate( a ) )
112: float pow2( const in float x ) { return x*x; }
113: float pow3( const in float x ) { return x*x*x; }
114: float pow4( const in float x ) { float x2 = x*x; return x2*x2; }
115: float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }
116: highp float rand( const in vec2 uv ) {
117: 	const highp float a = 12.9898, b = 78.233, c = 43758.5453;
118: 	highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );
119: 	return fract(sin(sn) * c);
120: }
121: struct IncidentLight {
122: 	vec3 color;
123: 	vec3 direction;
124: 	bool visible;
125: };
126: struct ReflectedLight {
127: 	vec3 directDiffuse;
128: 	vec3 directSpecular;
129: 	vec3 indirectDiffuse;
130: 	vec3 indirectSpecular;
131: };
132: struct GeometricContext {
133: 	vec3 position;
134: 	vec3 normal;
135: 	vec3 viewDir;
136: };
137: vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
138: 	return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
139: }
140: vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {
141: 	return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );
142: }
143: vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
144: 	float distance = dot( planeNormal, point - pointOnPlane );
145: 	return - distance * planeNormal + point;
146: }
147: float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
148: 	return sign( dot( point - pointOnPlane, planeNormal ) );
149: }
150: vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {
151: 	return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;
152: }
153: mat3 transposeMat3( const in mat3 m ) {
154: 	mat3 tmp;
155: 	tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );
156: 	tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );
157: 	tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );
158: 	return tmp;
159: }
160: float linearToRelativeLuminance( const in vec3 color ) {
161: 	vec3 weights = vec3( 0.2126, 0.7152, 0.0722 );
162: 	return dot( weights, color.rgb );
163: }
164: 
165: vec3 packNormalToRGB( const in vec3 normal ) {
166: 	return normalize( normal ) * 0.5 + 0.5;
167: }
168: vec3 unpackRGBToNormal( const in vec3 rgb ) {
169: 	return 2.0 * rgb.xyz - 1.0;
170: }
171: const float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;
172: const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256.,  256. );
173: const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );
174: const float ShiftRight8 = 1. / 256.;
175: vec4 packDepthToRGBA( const in float v ) {
176: 	vec4 r = vec4( fract( v * PackFactors ), v );
177: 	r.yzw -= r.xyz * ShiftRight8;	return r * PackUpscale;
178: }
179: float unpackRGBAToDepth( const in vec4 v ) {
180: 	return dot( v, UnpackFactors );
181: }
182: float viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {
183: 	return ( viewZ + near ) / ( near - far );
184: }
185: float orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {
186: 	return linearClipZ * ( near - far ) - near;
187: }
188: float viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {
189: 	return (( near + viewZ ) * far ) / (( far - near ) * viewZ );
190: }
191: float perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {
192: 	return ( near * far ) / ( ( far - near ) * invClipZ - far );
193: }
194: 
195: varying vec2 vUv;
196: uniform sampler2D tColor;
197: uniform sampler2D tDepth;
198: uniform float textureWidth;
199: uniform float textureHeight;
200: uniform float focalDepth;  //focal distance value in meters, but you may use autofocus option below
201: uniform float focalLength; //focal length in mm
202: uniform float fstop; //f-stop value
203: uniform bool showFocus; //show debug focus point and focal range (red = focal point, green = focal range)
204: /*
205: make sure that these two values are the same for your camera, otherwise distances will be wrong.
206: */
207: uniform float znear; // camera clipping start
208: uniform float zfar; // camera clipping end
209: //------------------------------------------
210: //user variables
211: const int samples = SAMPLES; //samples on the first ring
212: const int rings = RINGS; //ring count
213: const int maxringsamples = rings * samples;
214: uniform bool manualdof; // manual dof calculation
215: float ndofstart = 1.0; // near dof blur start
216: float ndofdist = 2.0; // near dof blur falloff distance
217: float fdofstart = 1.0; // far dof blur start
218: float fdofdist = 3.0; // far dof blur falloff distance
219: float CoC = 0.03; //circle of confusion size in mm (35mm film = 0.03mm)
220: uniform bool vignetting; // use optical lens vignetting
221: float vignout = 1.3; // vignetting outer border
222: float vignin = 0.0; // vignetting inner border
223: float vignfade = 22.0; // f-stops till vignete fades
224: uniform bool shaderFocus;
225: // disable if you use external focalDepth value
226: uniform vec2 focusCoords;
227: // autofocus point on screen (0.0,0.0 - left lower corner, 1.0,1.0 - upper right)
228: // if center of screen use vec2(0.5, 0.5);
229: uniform float maxblur;
230: //clamp value of max blur (0.0 = no blur, 1.0 default)
231: uniform float threshold; // highlight threshold;
232: uniform float gain; // highlight gain;
233: uniform float bias; // bokeh edge bias
234: uniform float fringe; // bokeh chromatic aberration / fringing
235: uniform bool noise; //use noise instead of pattern for sample dithering
236: uniform float dithering;
237: uniform bool depthblur; // blur the depth buffer
238: float dbsize = 1.25; // depth blur size
239: /*
240: next part is experimental
241: not looking good with small sample and ring count
242: looks okay starting from samples = 4, rings = 4
243: */
244: uniform bool pentagon; //use pentagon as bokeh shape?
245: float feather = 0.4; //pentagon shape feather
246: //------------------------------------------
247: float getDepth( const in vec2 screenPosition ) {
248: 	#if DEPTH_PACKING == 1
249: 	return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );
250: 	#else
251: 	return texture2D( tDepth, screenPosition ).x;
252: 	#endif
253: }
254: float penta(vec2 coords) {
255: //pentagonal shape
256: float scale = float(rings) - 1.3;
257: vec4  HS0 = vec4( 1.0,         0.0,         0.0,  1.0);
258: vec4  HS1 = vec4( 0.309016994, 0.951056516, 0.0,  1.0);
259: vec4  HS2 = vec4(-0.809016994, 0.587785252, 0.0,  1.0);
260: vec4  HS3 = vec4(-0.809016994,-0.587785252, 0.0,  1.0);
261: vec4  HS4 = vec4( 0.309016994,-0.951056516, 0.0,  1.0);
262: vec4  HS5 = vec4( 0.0        ,0.0         , 1.0,  1.0);
263: vec4  one = vec4( 1.0 );
264: vec4 P = vec4((coords),vec2(scale, scale));
265: vec4 dist = vec4(0.0);
266: float inorout = -4.0;
267: dist.x = dot( P, HS0 );
268: dist.y = dot( P, HS1 );
269: dist.z = dot( P, HS2 );
270: dist.w = dot( P, HS3 );
271: dist = smoothstep( -feather, feather, dist );
272: inorout += dot( dist, one );
273: dist.x = dot( P, HS4 );
274: dist.y = HS5.w - abs( P.z );
275: dist = smoothstep( -feather, feather, dist );
276: inorout += dist.x;
277: return clamp( inorout, 0.0, 1.0 );
278: }
279: float bdepth(vec2 coords) {
280: // Depth buffer blur
281: float d = 0.0;
282: float kernel[9];
283: vec2 offset[9];
284: vec2 wh = vec2(1.0/textureWidth,1.0/textureHeight) * dbsize;
285: offset[0] = vec2(-wh.x,-wh.y);
286: offset[1] = vec2( 0.0, -wh.y);
287: offset[2] = vec2( wh.x -wh.y);
288: offset[3] = vec2(-wh.x,  0.0);
289: offset[4] = vec2( 0.0,   0.0);
290: offset[5] = vec2( wh.x,  0.0);
291: offset[6] = vec2(-wh.x, wh.y);
292: offset[7] = vec2( 0.0,  wh.y);
293: offset[8] = vec2( wh.x, wh.y);
294: kernel[0] = 1.0/16.0;   kernel[1] = 2.0/16.0;   kernel[2] = 1.0/16.0;
295: kernel[3] = 2.0/16.0;   kernel[4] = 4.0/16.0;   kernel[5] = 2.0/16.0;
296: kernel[6] = 1.0/16.0;   kernel[7] = 2.0/16.0;   kernel[8] = 1.0/16.0;
297: for( int i=0; i<9; i++ ) {
298: float tmp = getDepth( coords + offset[ i ] );
299: d += tmp * kernel[i];
300: }
301: return d;
302: }
303: vec3 color(vec2 coords,float blur) {
304: //processing the sample
305: vec3 col = vec3(0.0);
306: vec2 texel = vec2(1.0/textureWidth,1.0/textureHeight);
307: col.r = texture2D(tColor,coords + vec2(0.0,1.0)*texel*fringe*blur).r;
308: col.g = texture2D(tColor,coords + vec2(-0.866,-0.5)*texel*fringe*blur).g;
309: col.b = texture2D(tColor,coords + vec2(0.866,-0.5)*texel*fringe*blur).b;
310: vec3 lumcoeff = vec3(0.299,0.587,0.114);
311: float lum = dot(col.rgb, lumcoeff);
312: float thresh = max((lum-threshold)*gain, 0.0);
313: return col+mix(vec3(0.0),col,thresh*blur);
314: }
315: vec3 debugFocus(vec3 col, float blur, float depth) {
316: float edge = 0.002*depth; //distance based edge smoothing
317: float m = clamp(smoothstep(0.0,edge,blur),0.0,1.0);
318: float e = clamp(smoothstep(1.0-edge,1.0,blur),0.0,1.0);
319: col = mix(col,vec3(1.0,0.5,0.0),(1.0-m)*0.6);
320: col = mix(col,vec3(0.0,0.5,1.0),((1.0-e)-(1.0-m))*0.2);
321: return col;
322: }
323: float linearize(float depth) {
324: return -zfar * znear / (depth * (zfar - znear) - zfar);
325: }
326: float vignette() {
327: float dist = distance(vUv.xy, vec2(0.5,0.5));
328: dist = smoothstep(vignout+(fstop/vignfade), vignin+(fstop/vignfade), dist);
329: return clamp(dist,0.0,1.0);
330: }
331: float gather(float i, float j, int ringsamples, inout vec3 col, float w, float h, float blur) {
332: float rings2 = float(rings);
333: float step = PI*2.0 / float(ringsamples);
334: float pw = cos(j*step)*i;
335: float ph = sin(j*step)*i;
336: float p = 1.0;
337: if (pentagon) {
338: p = penta(vec2(pw,ph));
339: }
340: col += color(vUv.xy + vec2(pw*w,ph*h), blur) * mix(1.0, i/rings2, bias) * p;
341: return 1.0 * mix(1.0, i /rings2, bias) * p;
342: }
343: void main() {
344: //scene depth calculation
345: float depth = linearize( getDepth( vUv.xy ) );
346: // Blur depth?
347: if (depthblur) {
348: depth = linearize(bdepth(vUv.xy));
349: }
350: //focal plane calculation
351: float fDepth = focalDepth;
352: if (shaderFocus) {
353: fDepth = linearize( getDepth( focusCoords ) );
354: }
355: // dof blur factor calculation
356: float blur = 0.0;
357: if (manualdof) {
358: float a = depth-fDepth; // Focal plane
359: float b = (a-fdofstart)/fdofdist; // Far DoF
360: float c = (-a-ndofstart)/ndofdist; // Near Dof
361: blur = (a>0.0) ? b : c;
362: } else {
363: float f = focalLength; // focal length in mm
364: float d = fDepth*1000.0; // focal plane in mm
365: float o = depth*1000.0; // depth in mm
366: float a = (o*f)/(o-f);
367: float b = (d*f)/(d-f);
368: float c = (d-f)/(d*fstop*CoC);
369: blur = abs(a-b)*c;
370: }
371: blur = clamp(blur,0.0,1.0);
372: // calculation of pattern for dithering
373: vec2 noise = vec2(rand(vUv.xy), rand( vUv.xy + vec2( 0.4, 0.6 ) ) )*dithering*blur;
374: // getting blur x and y step factor
375: float w = (1.0/textureWidth)*blur*maxblur+noise.x;
376: float h = (1.0/textureHeight)*blur*maxblur+noise.y;
377: // calculation of final color
378: vec3 col = vec3(0.0);
379: if(blur < 0.05) {
380: //some optimization thingy
381: col = texture2D(tColor, vUv.xy).rgb;
382: } else {
383: col = texture2D(tColor, vUv.xy).rgb;
384: float s = 1.0;
385: int ringsamples;
386: for (int i = 1; i <= rings; i++) {
387: /*unboxstart*/
388: ringsamples = i * samples;
389: for (int j = 0 ; j < maxringsamples ; j++) {
390: if (j >= ringsamples) break;
391: s += gather(float(i), float(j), ringsamples, col, w, h, blur);
392: }
393: /*unboxend*/
394: }
395: col /= s; //divide by sample count
396: }
397: if (showFocus) {
398: col = debugFocus(col, blur, depth);
399: }
400: if (vignetting) {
401: col *= vignette();
402: }
403: gl_FragColor.rgb = col;
404: gl_FragColor.a = 1.0;
405: }
Three.js version
  • Dev
  • r91
Browser
  • Chrome
  • Firefox
OS
  • Windows
Hardware Requirements (graphics card, VR Device, ...)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions