Skip to content

Instantly share code, notes, and snippets.

@cdata
Last active December 9, 2019 23:32
Show Gist options
  • Save cdata/784a5b3ac632de4aaff2149d6a6b4fff to your computer and use it in GitHub Desktop.
Save cdata/784a5b3ac632de4aaff2149d6a6b4fff to your computer and use it in GitHub Desktop.
THREE.WebGLShader: gl.getShaderInfoLog() fragment
Compile failed.
WARNING: 0:254: Calls to any function that may require a gradient calculation inside a conditional block may return undefined results
WARNING: 0:256: Calls to any function that may require a gradient calculation inside a conditional block may return undefined results
WARNING: 0:258: Calls to any function that may require a gradient calculation inside a conditional block may return undefined results
WARNING: 0:260: Calls to any function that may require a gradient calculation inside a conditional block may return undefined results
WARNING: 4 compilation warnings.
�1: #define n 20
2:
3: precision mediump float;
4: precision mediump int;
5: varying vec3 vOutputDirection;
6: uniform sampler2D envMap;
7: uniform bool copyEquirectangular;
8: uniform vec2 texelSize;
9: uniform int samples;
10: uniform float weights[n];
11: uniform bool latitudinal;
12: uniform float dTheta;
13: uniform float mipInt;
14: #define RECIPROCAL_PI 0.31830988618
15: #define RECIPROCAL_PI2 0.15915494
16:
17: uniform int inputEncoding;
18: uniform int outputEncoding;
19:
20: // For a discussion of what this is, please read this: http://lousodrome.net/blog/light/2013/05/26/gamma-correct-and-hdr-rendering-in-a-32-bits-buffer/
21:
22: vec4 LinearToLinear( in vec4 value ) {
23: return value;
24: }
25:
26: vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {
27: return vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );
28: }
29:
30: vec4 LinearToGamma( in vec4 value, in float gammaFactor ) {
31: return vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );
32: }
33:
34: vec4 sRGBToLinear( in vec4 value ) {
35: 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.a );
36: }
37:
38: vec4 LinearTosRGB( in vec4 value ) {
39: 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.a );
40: }
41:
42: vec4 RGBEToLinear( in vec4 value ) {
43: return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );
44: }
45:
46: vec4 LinearToRGBE( in vec4 value ) {
47: float maxComponent = max( max( value.r, value.g ), value.b );
48: float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );
49: return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );
50: // return vec4( value.brg, ( 3.0 + 128.0 ) / 256.0 );
51: }
52:
53: // reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html
54: vec4 RGBMToLinear( in vec4 value, in float maxRange ) {
55: return vec4( value.rgb * value.a * maxRange, 1.0 );
56: }
57:
58: vec4 LinearToRGBM( in vec4 value, in float maxRange ) {
59: float maxRGB = max( value.r, max( value.g, value.b ) );
60: float M = clamp( maxRGB / maxRange, 0.0, 1.0 );
61: M = ceil( M * 255.0 ) / 255.0;
62: return vec4( value.rgb / ( M * maxRange ), M );
63: }
64:
65: // reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html
66: vec4 RGBDToLinear( in vec4 value, in float maxRange ) {
67: return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );
68: }
69:
70: vec4 LinearToRGBD( in vec4 value, in float maxRange ) {
71: float maxRGB = max( value.r, 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:
77: // LogLuv reference: http://graphicrants.blogspot.ca/2009/04/rgbm-color-encoding.html
78:
79: // M matrix, for encoding
80: const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );
81: vec4 LinearToLogLuv( in vec4 value ) {
82: vec3 Xp_Y_XYZp = cLogLuvM * value.rgb;
83: Xp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );
84: vec4 vResult;
85: vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;
86: float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
87: vResult.w = fract( Le );
88: vResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;
89: return vResult;
90: }
91:
92: // Inverse M matrix, for decoding
93: const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );
94: vec4 LogLuvToLinear( in vec4 value ) {
95: float Le = value.z * 255.0 + value.w;
96: vec3 Xp_Y_XYZp;
97: Xp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );
98: Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;
99: Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;
100: vec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;
101: return vec4( max( vRGB, 0.0 ), 1.0 );
102: }
103:
104: vec4 inputTexelToLinear(vec4 value){
105: if(inputEncoding == 0){
106: return value;
107: }else if(inputEncoding == 1){
108: return sRGBToLinear(value);
109: }else if(inputEncoding == 2){
110: return RGBEToLinear(value);
111: }else if(inputEncoding == 3){
112: return RGBMToLinear(value, 7.0);
113: }else if(inputEncoding == 4){
114: return RGBMToLinear(value, 16.0);
115: }else if(inputEncoding == 5){
116: return RGBDToLinear(value, 256.0);
117: }else{
118: return GammaToLinear(value, 2.2);
119: }
120: }
121: vec4 linearToOutputTexel(vec4 value){
122: if(outputEncoding == 0){
123: return value;
124: }else if(outputEncoding == 1){
125: return LinearTosRGB(value);
126: }else if(outputEncoding == 2){
127: return LinearToRGBE(value);
128: }else if(outputEncoding == 3){
129: return LinearToRGBM(value, 7.0);
130: }else if(outputEncoding == 4){
131: return LinearToRGBM(value, 16.0);
132: }else if(outputEncoding == 5){
133: return LinearToRGBD(value, 256.0);
134: }else{
135: return LinearToGamma(value, 2.2);
136: }
137: }
138:
139: vec4 envMapTexelToLinear(vec4 color) {
140: return inputTexelToLinear(color);
141: }
142:
143: #define cubeUV_maxMipLevel 8.0
144: #define cubeUV_minMipLevel 4.0
145: #define cubeUV_maxTileSize 256.0
146: #define cubeUV_minTileSize 16.0
147:
148: float getFace(vec3 direction) {
149: vec3 absDirection = abs(direction);
150: float face = -1.0;
151: if (absDirection.x > absDirection.z) {
152: if (absDirection.x > absDirection.y)
153: face = direction.x > 0.0 ? 0.0 : 3.0;
154: else
155: face = direction.y > 0.0 ? 1.0 : 4.0;
156: } else {
157: if (absDirection.z > absDirection.y)
158: face = direction.z > 0.0 ? 2.0 : 5.0;
159: else
160: face = direction.y > 0.0 ? 1.0 : 4.0;
161: }
162: return face;
163: }
164:
165:
166: vec2 getUV(vec3 direction, float face) {
167: vec2 uv;
168: if (face == 0.0) {
169: uv = vec2(-direction.z, direction.y) / abs(direction.x);
170: } else if (face == 1.0) {
171: uv = vec2(direction.x, -direction.z) / abs(direction.y);
172: } else if (face == 2.0) {
173: uv = direction.xy / abs(direction.z);
174: } else if (face == 3.0) {
175: uv = vec2(direction.z, direction.y) / abs(direction.x);
176: } else if (face == 4.0) {
177: uv = direction.xz / abs(direction.y);
178: } else {
179: uv = vec2(-direction.x, direction.y) / abs(direction.z);
180: }
181: return 0.5 * (uv + 1.0);
182: }
183:
184: vec3 bilinearCubeUV(sampler2D envMap, vec3 direction, float mipInt) {
185: float face = getFace(direction);
186: float filterInt = max(cubeUV_minMipLevel - mipInt, 0.0);
187: mipInt = max(mipInt, cubeUV_minMipLevel);
188: float faceSize = exp2(mipInt);
189:
190: float texelSize = 1.0 / (3.0 * cubeUV_maxTileSize);
191:
192: vec2 uv = getUV(direction, face) * (faceSize - 1.0);
193: vec2 f = fract(uv);
194: uv += 0.5 - f;
195: if (face > 2.0) {
196: uv.y += faceSize;
197: face -= 3.0;
198: }
199: uv.x += face * faceSize;
200: if(mipInt < cubeUV_maxMipLevel){
201: uv.y += 2.0 * cubeUV_maxTileSize;
202: }
203: uv.y += filterInt * 2.0 * cubeUV_minTileSize;
204: uv.x += 3.0 * max(0.0, cubeUV_maxTileSize - 2.0 * faceSize);
205: uv *= texelSize;
206:
207: vec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
208: uv.x += texelSize;
209: vec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
210: uv.y += texelSize;
211: vec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
212: uv.x -= texelSize;
213: vec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
214: vec3 tm = mix(tl, tr, f.x);
215: vec3 bm = mix(bl, br, f.x);
216: return mix(tm, bm, f.y);
217: }
218:
219: void main() {
220: gl_FragColor = vec4(0.0);
221: if (copyEquirectangular) {
222: vec3 direction = normalize(vOutputDirection);
223: vec2 uv;
224: uv.y = asin(clamp(direction.y, -1.0, 1.0)) * RECIPROCAL_PI + 0.5;
225: uv.x = atan(direction.z, direction.x) * RECIPROCAL_PI2 + 0.5;
226: vec2 f = fract(uv / texelSize - 0.5);
227: uv -= f * texelSize;
228: vec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
229: uv.x += texelSize.x;
230: vec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
231: uv.y += texelSize.y;
232: vec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
233: uv.x -= texelSize.x;
234: vec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
235: vec3 tm = mix(tl, tr, f.x);
236: vec3 bm = mix(bl, br, f.x);
237: gl_FragColor.rgb = mix(tm, bm, f.y);
238: } else {
239: float xz = length(vOutputDirection.xz);
240: for (int i = 0; i < n; i++) {
241: if (i >= samples)
242: break;
243: for (int dir = -1; dir < 2; dir += 2) {
244: if (i == 0 && dir == 1)
245: continue;
246: vec3 sampleDirection = vOutputDirection;
247: if (latitudinal) {
248: float diTheta = dTheta * float(dir * i) / xz;
249: mat2 R =
250: mat2(cos(diTheta), sin(diTheta), -sin(diTheta), cos(diTheta));
251: sampleDirection.xz = R * sampleDirection.xz;
252: } else {
253: float diTheta = dTheta * float(dir * i);
254: mat2 R =
255: mat2(cos(diTheta), sin(diTheta), -sin(diTheta), cos(diTheta));
256: vec2 xzY = R * vec2(xz, sampleDirection.y);
257: if (xzY.x < 0.0) {
258: sampleDirection = vec3(0.0, sign(sampleDirection.y), 0.0);
259: } else {
260: sampleDirection.xz *= xzY.x / xz;
261: sampleDirection.y = xzY.y;
262: }
263: }
264: gl_FragColor.rgb +=
265: weights[i] * bilinearCubeUV(envMap, sampleDirection, mipInt);
266: }
267: }
268: }
269: gl_FragColor = linearToOutputTexel(gl_FragColor);
270: }
271:
THREE.WebGLShader: gl.getShaderInfoLog() fragment
Compile failed.
WARNING: 0:255: Calls to any function that may require a gradient calculation inside a conditional block may return undefined results
WARNING: 0:257: Calls to any function that may require a gradient calculation inside a conditional block may return undefined results
WARNING: 0:259: Calls to any function that may require a gradient calculation inside a conditional block may return undefined results
WARNING: 0:261: Calls to any function that may require a gradient calculation inside a conditional block may return undefined results
WARNING: 4 compilation warnings.
1: #define n 20
2:
3: precision mediump float;
4: precision mediump int;
5: varying vec3 vOutputDirection;
6: uniform sampler2D envMap;
7: uniform bool copyEquirectangular;
8: uniform vec2 texelSize;
9: uniform int samples;
10: uniform float weights[n];
11: uniform bool latitudinal;
12: uniform float dTheta;
13: uniform float mipInt;
14: uniform vec3 poleAxis;
15: #define RECIPROCAL_PI 0.31830988618
16: #define RECIPROCAL_PI2 0.15915494
17:
18: uniform int inputEncoding;
19: uniform int outputEncoding;
20:
21: // For a discussion of what this is, please read this: http://lousodrome.net/blog/light/2013/05/26/gamma-correct-and-hdr-rendering-in-a-32-bits-buffer/
22:
23: vec4 LinearToLinear( in vec4 value ) {
24: return value;
25: }
26:
27: vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {
28: return vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );
29: }
30:
31: vec4 LinearToGamma( in vec4 value, in float gammaFactor ) {
32: return vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );
33: }
34:
35: vec4 sRGBToLinear( in vec4 value ) {
36: 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.a );
37: }
38:
39: vec4 LinearTosRGB( in vec4 value ) {
40: 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.a );
41: }
42:
43: vec4 RGBEToLinear( in vec4 value ) {
44: return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );
45: }
46:
47: vec4 LinearToRGBE( in vec4 value ) {
48: float maxComponent = max( max( value.r, value.g ), value.b );
49: float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );
50: return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );
51: // return vec4( value.brg, ( 3.0 + 128.0 ) / 256.0 );
52: }
53:
54: // reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html
55: vec4 RGBMToLinear( in vec4 value, in float maxRange ) {
56: return vec4( value.rgb * value.a * maxRange, 1.0 );
57: }
58:
59: vec4 LinearToRGBM( in vec4 value, in float maxRange ) {
60: float maxRGB = max( value.r, max( value.g, value.b ) );
61: float M = clamp( maxRGB / maxRange, 0.0, 1.0 );
62: M = ceil( M * 255.0 ) / 255.0;
63: return vec4( value.rgb / ( M * maxRange ), M );
64: }
65:
66: // reference: http://iwasbeingirony.blogspot.ca/2010/06/difference-between-rgbm-and-rgbd.html
67: vec4 RGBDToLinear( in vec4 value, in float maxRange ) {
68: return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );
69: }
70:
71: vec4 LinearToRGBD( in vec4 value, in float maxRange ) {
72: float maxRGB = max( value.r, max( value.g, value.b ) );
73: float D = max( maxRange / maxRGB, 1.0 );
74: D = min( floor( D ) / 255.0, 1.0 );
75: return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );
76: }
77:
78: // LogLuv reference: http://graphicrants.blogspot.ca/2009/04/rgbm-color-encoding.html
79:
80: // M matrix, for encoding
81: const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );
82: vec4 LinearToLogLuv( in vec4 value ) {
83: vec3 Xp_Y_XYZp = cLogLuvM * value.rgb;
84: Xp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );
85: vec4 vResult;
86: vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;
87: float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
88: vResult.w = fract( Le );
89: vResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;
90: return vResult;
91: }
92:
93: // Inverse M matrix, for decoding
94: const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );
95: vec4 LogLuvToLinear( in vec4 value ) {
96: float Le = value.z * 255.0 + value.w;
97: vec3 Xp_Y_XYZp;
98: Xp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );
99: Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;
100: Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;
101: vec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;
102: return vec4( max( vRGB, 0.0 ), 1.0 );
103: }
104:
105: vec4 inputTexelToLinear(vec4 value){
106: if(inputEncoding == 0){
107: return value;
108: }else if(inputEncoding == 1){
109: return sRGBToLinear(value);
110: }else if(inputEncoding == 2){
111: return RGBEToLinear(value);
112: }else if(inputEncoding == 3){
113: return RGBMToLinear(value, 7.0);
114: }else if(inputEncoding == 4){
115: return RGBMToLinear(value, 16.0);
116: }else if(inputEncoding == 5){
117: return RGBDToLinear(value, 256.0);
118: }else{
119: return GammaToLinear(value, 2.2);
120: }
121: }
122: vec4 linearToOutputTexel(vec4 value){
123: if(outputEncoding == 0){
124: return value;
125: }else if(outputEncoding == 1){
126: return LinearTosRGB(value);
127: }else if(outputEncoding == 2){
128: return LinearToRGBE(value);
129: }else if(outputEncoding == 3){
130: return LinearToRGBM(value, 7.0);
131: }else if(outputEncoding == 4){
132: return LinearToRGBM(value, 16.0);
133: }else if(outputEncoding == 5){
134: return LinearToRGBD(value, 256.0);
135: }else{
136: return LinearToGamma(value, 2.2);
137: }
138: }
139:
140: vec4 envMapTexelToLinear(vec4 color) {
141: return inputTexelToLinear(color);
142: }
143:
144: #define cubeUV_maxMipLevel 8.0
145: #define cubeUV_minMipLevel 4.0
146: #define cubeUV_maxTileSize 256.0
147: #define cubeUV_minTileSize 16.0
148:
149: float getFace(vec3 direction) {
150: vec3 absDirection = abs(direction);
151: float face = -1.0;
152: if (absDirection.x > absDirection.z) {
153: if (absDirection.x > absDirection.y)
154: face = direction.x > 0.0 ? 0.0 : 3.0;
155: else
156: face = direction.y > 0.0 ? 1.0 : 4.0;
157: } else {
158: if (absDirection.z > absDirection.y)
159: face = direction.z > 0.0 ? 2.0 : 5.0;
160: else
161: face = direction.y > 0.0 ? 1.0 : 4.0;
162: }
163: return face;
164: }
165:
166:
167: vec2 getUV(vec3 direction, float face) {
168: vec2 uv;
169: if (face == 0.0) {
170: uv = vec2(-direction.z, direction.y) / abs(direction.x);
171: } else if (face == 1.0) {
172: uv = vec2(direction.x, -direction.z) / abs(direction.y);
173: } else if (face == 2.0) {
174: uv = direction.xy / abs(direction.z);
175: } else if (face == 3.0) {
176: uv = vec2(direction.z, direction.y) / abs(direction.x);
177: } else if (face == 4.0) {
178: uv = direction.xz / abs(direction.y);
179: } else {
180: uv = vec2(-direction.x, direction.y) / abs(direction.z);
181: }
182: return 0.5 * (uv + 1.0);
183: }
184:
185: vec3 bilinearCubeUV(sampler2D envMap, vec3 direction, float mipInt) {
186: float face = getFace(direction);
187: float filterInt = max(cubeUV_minMipLevel - mipInt, 0.0);
188: mipInt = max(mipInt, cubeUV_minMipLevel);
189: float faceSize = exp2(mipInt);
190:
191: float texelSize = 1.0 / (3.0 * cubeUV_maxTileSize);
192:
193: vec2 uv = getUV(direction, face) * (faceSize - 1.0);
194: vec2 f = fract(uv);
195: uv += 0.5 - f;
196: if (face > 2.0) {
197: uv.y += faceSize;
198: face -= 3.0;
199: }
200: uv.x += face * faceSize;
201: if(mipInt < cubeUV_maxMipLevel){
202: uv.y += 2.0 * cubeUV_maxTileSize;
203: }
204: uv.y += filterInt * 2.0 * cubeUV_minTileSize;
205: uv.x += 3.0 * max(0.0, cubeUV_maxTileSize - 2.0 * faceSize);
206: uv *= texelSize;
207:
208: vec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
209: uv.x += texelSize;
210: vec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
211: uv.y += texelSize;
212: vec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
213: uv.x -= texelSize;
214: vec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
215: vec3 tm = mix(tl, tr, f.x);
216: vec3 bm = mix(bl, br, f.x);
217: return mix(tm, bm, f.y);
218: }
219:
220: void main() {
221: gl_FragColor = vec4(0.0);
222: if (copyEquirectangular) {
223: vec3 direction = normalize(vOutputDirection);
224: vec2 uv;
225: uv.y = asin(clamp(direction.y, -1.0, 1.0)) * RECIPROCAL_PI + 0.5;
226: uv.x = atan(direction.z, direction.x) * RECIPROCAL_PI2 + 0.5;
227: vec2 f = fract(uv / texelSize - 0.5);
228: uv -= f * texelSize;
229: vec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
230: uv.x += texelSize.x;
231: vec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
232: uv.y += texelSize.y;
233: vec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
234: uv.x -= texelSize.x;
235: vec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
236: vec3 tm = mix(tl, tr, f.x);
237: vec3 bm = mix(bl, br, f.x);
238: gl_FragColor.rgb = mix(tm, bm, f.y);
239: } else {
240: for (int i = 0; i < n; i++) {
241: if (i >= samples)
242: break;
243: for (int dir = -1; dir < 2; dir += 2) {
244: if (i == 0 && dir == 1)
245: continue;
246: vec3 axis = latitudinal ? poleAxis : cross(poleAxis, vOutputDirection);
247: if (all(equal(axis, vec3(0.0))))
248: axis = cross(vec3(0.0, 1.0, 0.0), vOutputDirection);
249: axis = normalize(axis);
250: float theta = dTheta * float(dir * i);
251: float cosTheta = cos(theta);
252: // Rodrigues' axis-angle rotation
253: vec3 sampleDirection = vOutputDirection * cosTheta
254: + cross(axis, vOutputDirection) * sin(theta)
255: + axis * dot(axis, vOutputDirection) * (1.0 - cosTheta);
256: gl_FragColor.rgb +=
257: weights[i] * bilinearCubeUV(envMap, sampleDirection, mipInt);
258: }
259: }
260: }
261: gl_FragColor = linearToOutputTexel(gl_FragColor);
262: }
263:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment