Trying to add depth of field to my project from:
http://www.andrewberg.com/prototypes/threejs/bokeh/
But getting an error from the shader:
three.js:16612THREE.WebGLProgram: shader error: 0 gl.VALIDATE_STATUS
false gl.getProgramInfoLog invalid shaders ERROR: 0:101:
'DEPTH_PACKING' : unexpected token after conditional expression
ERROR: 0:228: 'DEPTH_PACKING' : unexpected token after conditional
expression ERROR: 0:248: 'DEPTH_PACKING' : unexpected token after
conditional expression ERROR: 0:250: 'DEPTH_PACKING' : unexpected
token after conditional expression
And the shader which shows error:
HREE.WebGLShader: gl.getShaderInfoLog() fragment ERROR: 0:101: 'DEPTH_PACKING' : unexpected token after conditional expression
ERROR: 0:228: 'DEPTH_PACKING' : unexpected token after conditional expression
ERROR: 0:248: 'DEPTH_PACKING' : unexpected token after conditional expression
ERROR: 0:250: 'DEPTH_PACKING' : unexpected token after conditional expression
1: precision highp float;
2: precision highp int;
3: #define SHADER_NAME ShaderMaterial
4: #define GAMMA_FACTOR 2
5: #define NUM_CLIPPING_PLANES 0
6: #define UNION_CLIPPING_PLANES 0
7: uniform mat4 viewMatrix;
8: uniform vec3 cameraPosition;
9: #define TONE_MAPPING
10: #define saturate(a) clamp( a, 0.0, 1.0 )
11: uniform float toneMappingExposure;
12: uniform float toneMappingWhitePoint;
13: vec3 LinearToneMapping( vec3 color ) {
14: return toneMappingExposure * color;
15: }
16: vec3 ReinhardToneMapping( vec3 color ) {
17: color *= toneMappingExposure;
18: return saturate( color / ( vec3( 1.0 ) + color ) );
19: }
20: #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 ) )
21: vec3 Uncharted2ToneMapping( vec3 color ) {
22: color *= toneMappingExposure;
23: return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );
24: }
25: vec3 OptimizedCineonToneMapping( vec3 color ) {
26: color *= toneMappingExposure;
27: color = max( vec3( 0.0 ), color - 0.004 );
28: return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );
29: }
30:
31: vec3 toneMapping( vec3 color ) { return LinearToneMapping( color ); }
32:
33: vec4 LinearToLinear( in vec4 value ) {
34: return value;
35: }
36: vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {
37: return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );
38: }
39: vec4 LinearToGamma( in vec4 value, in float gammaFactor ) {
40: return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );
41: }
42: vec4 sRGBToLinear( in vec4 value ) {
43: 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 );
44: }
45: vec4 LinearTosRGB( in vec4 value ) {
46: 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 );
47: }
48: vec4 RGBEToLinear( in vec4 value ) {
49: return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );
50: }
51: vec4 LinearToRGBE( in vec4 value ) {
52: float maxComponent = max( max( value.r, value.g ), value.b );
53: float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );
54: return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );
55: }
56: vec4 RGBMToLinear( in vec4 value, in float maxRange ) {
57: return vec4( value.xyz * value.w * maxRange, 1.0 );
58: }
59: vec4 LinearToRGBM( in vec4 value, in float maxRange ) {
60: float maxRGB = max( value.x, 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: vec4 RGBDToLinear( in vec4 value, in float maxRange ) {
66: return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );
67: }
68: vec4 LinearToRGBD( in vec4 value, in float maxRange ) {
69: float maxRGB = max( value.x, max( value.g, value.b ) );
70: float D = max( maxRange / maxRGB, 1.0 );
71: D = min( floor( D ) / 255.0, 1.0 );
72: return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );
73: }
74: const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );
75: vec4 LinearToLogLuv( in vec4 value ) {
76: vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;
77: Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));
78: vec4 vResult;
79: vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;
80: float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
81: vResult.w = fract(Le);
82: vResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;
83: return vResult;
84: }
85: const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );
86: vec4 LogLuvToLinear( in vec4 value ) {
87: float Le = value.z * 255.0 + value.w;
88: vec3 Xp_Y_XYZp;
89: Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);
90: Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;
91: Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;
92: vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;
93: return vec4( max(vRGB, 0.0), 1.0 );
94: }
95:
96: vec4 mapTexelToLinear( vec4 value ) { return LinearToLinear( value ); }
97: vec4 envMapTexelToLinear( vec4 value ) { return LinearToLinear( value ); }
98: vec4 emissiveMapTexelToLinear( vec4 value ) { return LinearToLinear( value ); }
99: vec4 linearToOutputTexel( vec4 value ) { return LinearToLinear( value ); }
100:
101: #if DEPTH_PACKING == 3200
102: uniform float opacity;
103: #endif
104: #define PI 3.14159265359
105: #define PI2 6.28318530718
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:
154: vec3 packNormalToRGB( const in vec3 normal ) {
155: return normalize( normal ) * 0.5 + 0.5;
156: }
157: vec3 unpackRGBToNormal( const in vec3 rgb ) {
158: return 1.0 - 2.0 * rgb.xyz;
159: }
160: const float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;
161: const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );
162: const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );
163: const float ShiftRight8 = 1. / 256.;
164: vec4 packDepthToRGBA( const in float v ) {
165: vec4 r = vec4( fract( v * PackFactors ), v );
166: r.yzw -= r.xyz * ShiftRight8; return r * PackUpscale;
167: }
168: float unpackRGBAToDepth( const in vec4 v ) {
169: return dot( v, UnpackFactors );
170: }
171: float viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {
172: return ( viewZ + near ) / ( near - far );
173: }
174: float orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {
175: return linearClipZ * ( near - far ) - near;
176: }
177: float viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {
178: return (( near + viewZ ) * far ) / (( far - near ) * viewZ );
179: }
180: float perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {
181: return ( near * far ) / ( ( far - near ) * invClipZ - far );
182: }
183:
184: #if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )
185: varying vec2 vUv;
186: #endif
187: #ifdef USE_MAP
188: uniform sampler2D map;
189: #endif
190:
191: #ifdef USE_ALPHAMAP
192: uniform sampler2D alphaMap;
193: #endif
194:
195: #ifdef USE_LOGDEPTHBUF
196: uniform float logDepthBufFC;
197: #ifdef USE_LOGDEPTHBUF_EXT
198: varying float vFragDepth;
199: #endif
200: #endif
201:
202: #if NUM_CLIPPING_PLANES > 0
203: #if ! defined( PHYSICAL ) && ! defined( PHONG )
204: varying vec3 vViewPosition;
205: #endif
206: uniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];
207: #endif
208:
209: void main() {
210: #if NUM_CLIPPING_PLANES > 0
211: for ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {
212: vec4 plane = clippingPlanes[ i ];
213: if ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;
214: }
215:
216: #if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES
217: bool clipped = true;
218: for ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {
219: vec4 plane = clippingPlanes[ i ];
220: clipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;
221: }
222: if ( clipped ) discard;
223:
224: #endif
225: #endif
226:
227: vec4 diffuseColor = vec4( 1.0 );
228: #if DEPTH_PACKING == 3200
229: diffuseColor.a = opacity;
230: #endif
231: #ifdef USE_MAP
232: vec4 texelColor = texture2D( map, vUv );
233: texelColor = mapTexelToLinear( texelColor );
234: diffuseColor *= texelColor;
235: #endif
236:
237: #ifdef USE_ALPHAMAP
238: diffuseColor.a *= texture2D( alphaMap, vUv ).g;
239: #endif
240:
241: #ifdef ALPHATEST
242: if ( diffuseColor.a < ALPHATEST ) discard;
243: #endif
244:
245: #if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)
246: gl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;
247: #endif
248: #if DEPTH_PACKING == 3200
249: gl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );
250: #elif DEPTH_PACKING == 3201
251: gl_FragColor = packDepthToRGBA( gl_FragCoord.z );
252: #endif
253: }
254:
DEPTH_PACKING seems to be not defined.
I think the depth shader is used by another parent shader and it is why it get and error when we want to use him alone.
I resolve the problem by rewriting and removing all DEPTH_PACKING conditions :
Exemple with the depth_frag.glsl:
#include <common>
#include <packing>
#include <uv_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
void main() {
#include <clipping_planes_fragment>
vec4 diffuseColor = vec4( 1.0 );
#include <map_fragment>
#include <alphamap_fragment>
#include <alphatest_fragment>
#include <logdepthbuf_fragment>
gl_FragColor = packDepthToRGBA( gl_FragCoord.z );
}
You can find the base of this shader here: /r86/src/renderers/shaders/ShaderLib/depth_frag.glsl.
Related
My three.js version is v-125, the code blew is initializing and rendering the ShaderMaterial on six PlaneGeometry, it is modified from the code in version 88.
This is the shaders 's code.
import noise from 'glsl-noise/classic/3d';
varying vec2 vUv;
uniform int index;
uniform float seed;
uniform float resolution;
uniform float res1;
uniform float res2;
uniform float resMix;
uniform float mixScale;
uniform float doesRidged;
const int octaves = 16;
// #define M_PI 3.1415926535897932384626433832795;
vec3 getSphericalCoord(int index, float x, float y, float width) {
width /= 2.0;
x -= width;
y -= width;
vec3 coord = vec3(0.0, 0.0, 0.0);
if (index == 0) {coord.x=width; coord.y=-y; coord.z=-x;}
else if (index == 1) {coord.x=-width; coord.y=-y; coord.z=x;}
else if (index == 2) {coord.x=x; coord.y=width; coord.z=y;}
else if (index == 3) {coord.x=x; coord.y=-width; coord.z=-y;}
else if (index == 4) {coord.x=x; coord.y=-y; coord.z=width;}
else if (index == 5) {coord.x=-x; coord.y=-y; coord.z=-width;}
return normalize(coord);
}
float simplexRidged(vec3 pos, float seed) {
float n = noise(vec3(pos + seed));
n = (n + 1.0) * 0.5;
n = 2.0 * (0.5 - abs(0.5 - n));
return n;
}
float simplex(vec3 pos, float seed) {
float n = noise(vec3(pos + seed));
return (n + 1.0) * 0.5;
}
float baseNoise(vec3 pos, float frq, float seed ) {
float amp = 0.5;
float n = 0.0;
float gain = 1.0;
for(int i=0; i<octaves; i++) {
n += simplex(vec3(pos.x*gain/frq, pos.y*gain/frq, pos.z*gain/frq), seed+float(i)*10.0) * amp/gain;
gain *= 2.0;
}
// increase contrast
n = ( (n - 0.5) * 2.0 ) + 0.5;
return n;
}
float ridgedNoise(vec3 pos, float frq, float seed) {
float amp = 0.5;
float n = 0.0;
float gain = 1.0;
for(int i=0; i<octaves; i++) {
n += simplexRidged(vec3(pos.x*gain/frq, pos.y*gain/frq, pos.z*gain/frq), seed+float(i)*10.0) * amp/gain;
gain *= 2.0;
}
n = pow(n, 4.0);
return n;
}
float invRidgedNoise(vec3 pos, float frq, float seed) {
float amp = 0.5;
float n = 0.0;
float gain = 1.0;
for(int i=0; i<octaves; i++) {
n += simplexRidged(vec3(pos.x*gain/frq, pos.y*gain/frq, pos.z*gain/frq), seed+float(i)*10.0) * amp/gain;
gain *= 2.0;
}
n = pow(n, 4.0);
n = 1.0 - n;
return n;
}
float cloud(vec3 pos, float seed) {
float n = noise(vec3(pos + seed));
// n = sin(n*4.0 * cos(n*2.0));
n = sin(n*5.0);
// n = abs(sin(n*5.0));
// n = 1.0 - n;
n = n*0.5 + 0.5;
// n = 1.0-n;
// n = n*1.2;
// n = 1.0-n;
return n;
}
float cloudNoise(vec3 pos, float frq, float seed) {
float amp = 0.5;
float n = 0.0;
float gain = 1.0;
for(int i=0; i<octaves; i++) {
n += cloud(vec3(pos.x*gain/frq, pos.y*gain/frq, pos.z*gain/frq), seed+float(i)*10.0) * amp/gain;
gain *= 2.0;
}
// n = pow(n, 5.0);
n = 1.0-n;
n = pow(n, 1.0);
n = 1.0-n;
return n;
}
void main() {
float x = vUv.x;
float y = 1.0 - vUv.y;
vec3 sphericalCoord = getSphericalCoord(index, x*resolution, y*resolution, resolution);
float sub1, sub2, sub3, n;
float resMod = 1.0; // overall res magnification
float resMod2 = mixScale; // minimum res mod
if (doesRidged == 0.0) {
sub1 = cloudNoise(sphericalCoord, res1*resMod, seed+11.437);
sub2 = cloudNoise(sphericalCoord, res2*resMod, seed+93.483);
sub3 = cloudNoise(sphericalCoord, resMix*resMod, seed+23.675);
n = cloudNoise(sphericalCoord + vec3((sub1/sub3)*0.1), resMod2+sub2, seed+78.236);
}
else if (doesRidged == 1.0) {
sub1 = ridgedNoise(sphericalCoord, res1*resMod, seed+83.706);
sub2 = ridgedNoise(sphericalCoord, res2*resMod, seed+29.358);
sub3 = ridgedNoise(sphericalCoord, resMix*resMod, seed+53.041);
n = ridgedNoise(sphericalCoord + vec3((sub1/sub3)*0.1), resMod2+sub2, seed+34.982);
}
else if (doesRidged == 2.0) {
sub1 = invRidgedNoise(sphericalCoord, res1*resMod, seed+49.684);
sub2 = invRidgedNoise(sphericalCoord, res2*resMod, seed+136.276);
sub3 = invRidgedNoise(sphericalCoord, resMix*resMod, seed+3.587);
n = invRidgedNoise(sphericalCoord + vec3((sub1/sub3)*0.1), resMod2+sub2, seed+33.321);
}
else {
sub1 = baseNoise(sphericalCoord, res1*resMod, seed+52.284);
sub2 = baseNoise(sphericalCoord, res2*resMod, seed+137.863);
sub3 = baseNoise(sphericalCoord, resMix*resMod, seed+37.241);
float alpha = sub1*3.14*2.0;
float beta = sub2*3.14*2.0;
float fx = cos(alpha)*cos(beta);
float fz = sin(alpha)*cos(beta);
float fy = sin(beta);
n = baseNoise(sphericalCoord + (vec3(fx,fy,fz) * sub3), 1.0, seed+28.634);
}
gl_FragColor = vec4(vec3(n), 1.0);
}
This is the code to apply shader to the
import * as THREE from 'three'
import fragShader from './flowNoiseMap.frag'
import seedrandom from 'seedrandom';
class NoiseMap
{
constructor() {
window.rng = seedrandom('adfadfadf');
this.setupMaterial();
this.setupPlane();
let resMin = 0.01;
let resMax = 5.0;
this.resolution = 1024;
this.seed = this.randRange(0, 1) * 1000.0;
this.render({
seed: this.seed,
resolution: this.resolution,
res1: this.randRange(resMin, resMax),
res2: this.randRange(resMin, resMax),
resMix: this.randRange(resMin, resMax),
mixScale: this.randRange(0.5, 1.0),
doesRidged: Math.floor(this.randRange(0, 4))
});
}
setupPlane() {
this.maps = [];
this.textures = [];
this.textureCameras = [];
this.textureScenes = [];
this.planes = [];
this.geos = [];
for (let i = 0; i < 6; i++) {
let tempRes = 1000;
this.textures[i] = new THREE.WebGLRenderTarget(tempRes, tempRes, {minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat});
this.textureCameras[i] = new THREE.OrthographicCamera(-tempRes/2, tempRes/2, tempRes/2, -tempRes/2, -100, 100);
this.textureCameras[i].position.z = 10;
this.textureScenes[i] = new THREE.Scene();
this.geos[i] = new THREE.PlaneGeometry(1, 1);
this.planes[i] = new THREE.Mesh(this.geos[i], this.mats[i]);
this.planes[i].position.z = -10;
this.textureScenes[i].add(this.planes[i]);
//window.renderer.render(textureScene, textureCamera);
this.maps.push(this.textures[i].texture);
}
}
setup() {
this.mats = [];
for (let i = 0; i < 6; i++) {
this.mats[i] = new THREE.ShaderMaterial({
uniforms: {
index: {type: "i", value: i},
seed: {type: "f", value: 0},
resolution: {type: "f", value: 0},
res1: {type: "f", value: 0},
res2: {type: "f", value: 0},
resMix: {type: "f", value: 0},
mixScale: {type: "f", value: 0},
doesRidged: {type: "f", value: 0}
},
vertexShader: vertShader,
fragmentShader: fragShader,
transparent: true,
depthWrite: false
});
}
}
render(props) {
let resolution = props.resolution;
for (let i = 0; i < 6; i++) {
this.mats[i].uniforms.seed.value = props.seed;
this.mats[i].uniforms.resolution.value = props.resolution;
this.mats[i].uniforms.res1.value = props.res1;
this.mats[i].uniforms.res2.value = props.res2;
this.mats[i].uniforms.resMix.value = props.resMix;
this.mats[i].uniforms.mixScale.value = props.mixScale;
this.mats[i].uniforms.doesRidged.value = props.doesRidged;
this.mats[i].needsUpdat = true;
}
this.renderMaterial(props)
}
renderMaterial(props) {
let resolution = props.resolution;
console.log('map render')
for (let i = 0; i < 6; i++) {
this.textures[i].setSize(resolution, resolution);
this.textures[i].needsUpdate = true;
this.textureCameras[i].left = -resolution/2;
this.textureCameras[i].right = resolution/2;
this.textureCameras[i].top = resolution/2;
this.textureCameras[i].bottom = -resolution/2;
this.textureCameras[i].updateProjectionMatrix();
this.geos[i] = new THREE.PlaneGeometry(resolution, resolution);
this.planes[i].geometry = this.geos[i];
window.renderer.render(this.textureScenes[i], this.textureCameras[i]);
this.geos[i].dispose();
}
}
randRange(low, high) {
let range = high - low;
let n = window.rng() * range;
return low + n;
}
}
new NoiseMap();
Running the code gave me the error
three.module.js?3179:19503 WebGL: INVALID_OPERATION: useProgram: program not valid
useProgram # three.module.js?3179:19503
setProgram # three.module.js?3179:24390
WebGLRenderer.renderBufferDirect # three.module.js?3179:23631
WebGL: INVALID_OPERATION: drawElements: no valid shader program in use
three.module.js?3179:17081 THREE.WebGLProgram: shader error: 0 35715 false gl.getProgramInfoLog invalid shaders THREE.WebGLShader: gl.getShaderInfoLog() fragment
ERROR: 0:89: 'import' : syntax error
1: #version 300 es
2: #define varying in
3: out highp vec4 pc_fragColor;
4: #define gl_FragColor pc_fragColor
5: #define gl_FragDepthEXT gl_FragDepth
6: #define texture2D texture
7: #define textureCube texture
8: #define texture2DProj textureProj
9: #define texture2DLodEXT textureLod
10: #define texture2DProjLodEXT textureProjLod
11: #define textureCubeLodEXT textureLod
12: #define texture2DGradEXT textureGrad
13: #define texture2DProjGradEXT textureProjGrad
14: #define textureCubeGradEXT textureGrad
15: precision highp float;
16: precision highp int;
17: #define HIGH_PRECISION
18: #define SHADER_NAME ShaderMaterial
19: #define GAMMA_FACTOR 2
20: uniform mat4 viewMatrix;
21: uniform vec3 cameraPosition;
22: uniform bool isOrthographic;
23:
24: vec4 LinearToLinear( in vec4 value ) {
25: return value;
26: }
27: vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {
28: return vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );
29: }
30: vec4 LinearToGamma( in vec4 value, in float gammaFactor ) {
31: return vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );
32: }
33: vec4 sRGBToLinear( in vec4 value ) {
34: 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 );
35: }
36: vec4 LinearTosRGB( in vec4 value ) {
37: 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 );
38: }
39: vec4 RGBEToLinear( in vec4 value ) {
40: return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );
41: }
42: vec4 LinearToRGBE( in vec4 value ) {
43: float maxComponent = max( max( value.r, value.g ), value.b );
44: float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );
45: return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );
46: }
47: vec4 RGBMToLinear( in vec4 value, in float maxRange ) {
48: return vec4( value.rgb * value.a * maxRange, 1.0 );
49: }
50: vec4 LinearToRGBM( in vec4 value, in float maxRange ) {
51: float maxRGB = max( value.r, max( value.g, value.b ) );
52: float M = clamp( maxRGB / maxRange, 0.0, 1.0 );
53: M = ceil( M * 255.0 ) / 255.0;
54: return vec4( value.rgb / ( M * maxRange ), M );
55: }
56: vec4 RGBDToLinear( in vec4 value, in float maxRange ) {
57: return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );
58: }
59: vec4 LinearToRGBD( in vec4 value, in float maxRange ) {
60: float maxRGB = max( value.r, max( value.g, value.b ) );
61: float D = max( maxRange / maxRGB, 1.0 );
62: D = clamp( floor( D ) / 255.0, 0.0, 1.0 );
63: return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );
64: }
65: const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );
66: vec4 LinearToLogLuv( in vec4 value ) {
67: vec3 Xp_Y_XYZp = cLogLuvM * value.rgb;
68: Xp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );
69: vec4 vResult;
70: vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;
71: float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
72: vResult.w = fract( Le );
73: vResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;
74: return vResult;
75: }
76: const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );
77: vec4 LogLuvToLinear( in vec4 value ) {
78: float Le = value.z * 255.0 + value.w;
79: vec3 Xp_Y_XYZp;
80: Xp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );
81: Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;
82: Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;
83: vec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;
84: return vec4( max( vRGB, 0.0 ), 1.0 );
85: }
86: vec4 linearToOutputTexel( vec4 value ) { return LinearToLinear( value ); }
87:
88: #define GLSLIFY 1
89: import noise from 'glsl-noise/classic/3d'
90:
91: varying vec2 vUv;
92: uniform int index;
93: uniform float seed;
94: uniform float resolution;
95: uniform float res1;
96: uniform float res2;
97: uniform float resMix;
98: uniform float mixScale;
99: uniform float doesRidged;
100: const int octaves = 16;
101:
102: // #define M_PI 3.1415926535897932384626433832795;
103:
104: vec3 getSphericalCoord(int index, float x, float y, float width) {
105: width /= 2.0;
106: x -= width;
107: y -= width;
108: vec3 coord = vec3(0.0, 0.0, 0.0);
109:
110: if (index == 0) {coord.x=width; coord.y=-y; coord.z=-x;}
111: else if (index == 1) {coord.x=-width; coord.y=-y; coord.z=x;}
112: else if (index == 2) {coord.x=x; coord.y=width; coord.z=y;}
113: else if (index == 3) {coord.x=x; coord.y=-width; coord.z=-y;}
114: else if (index == 4) {coord.x=x; coord.y=-y; coord.z=width;}
115: else if (index == 5) {coord.x=-x; coord.y=-y; coord.z=-width;}
116:
117: return normalize(coord);
118: }
119: ..................
what is wrong with this shader code, as it is used to work in version 88
You have this line in your compiled shader:
import noise from 'glsl-noise/classic/3d';
This is no valid GLSL. It seems you are missing a step in you build that resolves the import and injects the code from glsl-noise/classic/3d into your shader.
We have a new problem that has just appeared in Safari.
Aframe Text is no longer rendering in Safari with this error. The shader I think it is refering to is the Three.Meshline shader, which is rendering fine in the scene.
Renders fine on all other browsers, anyone know what has changed!?
Error] THREE.WebGLProgram: shader error: – 1282 – "35715" – false – "gl.getProgramInfoLog" – "" (2)
"THREE.WebGLShader: gl.getShaderInfoLog() vertex
ERROR: unsupported shader version1: #version 300 es
2: in vec2 uv;
3: in vec3 position;
4: uniform mat4 projectionMatrix;
5: uniform mat4 modelViewMatrix;
6: out vec2 vUV;
7: void main(void) {
8: gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
9: vUV = uv;
10: }"
"THREE.WebGLShader: gl.getShaderInfoLog() fragment
ERROR: unsupported shader version1: #version 300 es
2: precision highp float;
3: uniform bool negate;
4: uniform float alphaTest;
5: uniform float opacity;
6: uniform sampler2D map;
7: uniform vec3 color;
8: in vec2 vUV;
9: out vec4 fragColor;
10: float median(float r, float g, float b) {
11: return max(min(r, g), min(max(r, g), b));
12: }
13: #define BIG_ENOUGH 0.001
14: #define MODIFIED_ALPHATEST (0.02 * isBigEnough / BIG_ENOUGH)
15: void main() {
16: vec3 sampleColor = texture(map, vUV).rgb;
17: if (negate) { sampleColor = 1.0 - sampleColor; }
18: float sigDist = median(sampleColor.r, sampleColor.g, sampleColor.b) - 0.5;
19: float alpha = clamp(sigDist / fwidth(sigDist) + 0.5, 0.0, 1.0);
20: float dscale = 0.353505;
21: vec2 duv = dscale * (dFdx(vUV) + dFdy(vUV));
22: float isBigEnough = max(abs(duv.x), abs(duv.y));
23: // Do modified alpha test.
24: if (isBigEnough > BIG_ENOUGH) {
25: float ratio = BIG_ENOUGH / isBigEnough;
26: alpha = ratio * alpha + (1.0 - ratio) * (sigDist + 0.5);
27: }
28: // Do modified alpha test.
29: if (alpha < alphaTest * MODIFIED_ALPHATEST) { discard; return; }
30: fragColor = vec4(color.xyz, alpha * opacity);
31: }"
Problem in latest Aframe. Reverted to last stable and it went away.
I'm building 2D Graph structure based on Three.js, all elements of the graph (nodes, edges, triangles for arrows) calculated in shaders. I was able to reach a good level of antialiasing for nodes (circles) but stuck with same task for lines and triangles.
I was able to reach a good antialiasing results for nodes (circles) with and without stroke following this question: How can I add a uniform width outline to WebGL shader drawn circles/ellipses (drawn using edge/distance antialiasing) , my code, responsible for antialiasing alpha:
`float strokeWidth = 0.09;
float outerEdgeCenter = 0.5 - strokeWidth;
float d = distance(vUV, vec2(.5, .5));
float delta = fwidth(d);
float alpha = 1.0 - smoothstep(0.45 - delta, 0.45, d);
float stroke = 1.0 - smoothstep(outerEdgeCenter - delta,
outerEdgeCenter + delta, d);`
But now I'm completely stack with edges and triangles to do same stuff.
Here is an example of shapes images that I have now (on non retina displays):
To reduce under-sampling artifacts I want to do similar algorithms (as for circles) directly in shaders by manipulating alpha and already find some materials related to this topic:
https://thebookofshaders.com/glossary/?search=smoothstep - seems to be the closest solution but unfortunately I wasn't able to implement it properly and figure out how to set up y equation for segmented lines.
https://discourse.threejs.org/t/shader-to-create-an-offset-inward-growing-stroke/6060/12 - last answer, looks promising but not give me proper result.
https://www.shadertoy.com/view/4dcfW8 - also do not give proper result.
Here is an examples of my shaders for lines and triangles:
Line VertexShader (is a slightly adapted version of WestLangley's LineMaterial shader):
`precision highp float;
#include <common>
#include <color_pars_vertex>
#include <fog_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
uniform float linewidth;
uniform vec2 resolution;
attribute vec3 instanceStart;
attribute vec3 instanceEnd;
attribute vec3 instanceColorStart;
attribute vec3 instanceColorEnd;
attribute float alphaStart;
attribute float alphaEnd;
attribute float widthStart;
attribute float widthEnd;
varying vec2 vUv;
varying float alphaTest;
void trimSegment( const in vec4 start, inout vec4 end ) {
// trim end segment so it terminates between the camera plane and the near plane
// conservative estimate of the near plane
float a = projectionMatrix[ 2 ][ 2 ]; // 3nd entry in 3th column
float b = projectionMatrix[ 3 ][ 2 ]; // 3nd entry in 4th column
float nearEstimate = - 0.5 * b / a;
float alpha = ( nearEstimate - start.z ) / ( end.z - start.z );
end.xyz = mix( start.xyz, end.xyz, alpha );
}
void main() {
#ifdef USE_COLOR
vColor.xyz = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;
alphaTest = ( position.y < 0.5 ) ? alphaStart : alphaEnd;
#endif
float aspect = resolution.x / resolution.y;
vUv = uv;
// camera space
vec4 start = modelViewMatrix * vec4( instanceStart, 1.0 );
vec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );
// special case for perspective projection, and segments that terminate either in, or behind, the camera plane
// clearly the gpu firmware has a way of addressing this issue when projecting into ndc space
// but we need to perform ndc-space calculations in the shader, so we must address this issue directly
// perhaps there is a more elegant solution -- WestLangley
bool perspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 ); // 4th entry in the 3rd column
if (perspective) {
if (start.z < 0.0 && end.z >= 0.0) {
trimSegment( start, end );
} else if (end.z < 0.0 && start.z >= 0.0) {
trimSegment( end, start );
}
}
// clip space
vec4 clipStart = projectionMatrix * start;
vec4 clipEnd = projectionMatrix * end;
// ndc space
vec2 ndcStart = clipStart.xy / clipStart.w;
vec2 ndcEnd = clipEnd.xy / clipEnd.w;
// direction
vec2 dir = ndcEnd - ndcStart;
// account for clip-space aspect ratio
dir.x *= aspect;
dir = normalize( dir );
// perpendicular to dir
vec2 offset = vec2( dir.y, - dir.x );
// undo aspect ratio adjustment
dir.x /= aspect;
offset.x /= aspect;
// sign flip
if ( position.x < 0.0 ) offset *= - 1.0;
// endcaps, to round line corners
if ( position.y < 0.0 ) {
// offset += - dir;
} else if ( position.y > 1.0 ) {
// offset += dir;
}
// adjust for linewidth
offset *= (linewidth * widthStart);
// adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...
offset /= resolution.y;
// select end
vec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;
// back to clip space
offset *= clip.w;
clip.xy += offset;
gl_Position = clip;
vec4 mvPosition = ( position.y < 0.5 ) ? start : end; // this is an approximation
#include <logdepthbuf_vertex>
#include <clipping_planes_vertex>
#include <fog_vertex>
}`
Line FragmentShader:
`precision highp float;
#include <common>
#include <color_pars_fragment>
#include <fog_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
uniform vec3 diffuse;
uniform float opacity;
varying vec2 vUv;
varying float alphaTest;
void main() {
if ( abs( vUv.y ) > 1.0 ) {
float a = vUv.x;
float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
float len2 = a * a + b * b;
if ( len2 > 1.0 ) discard;
}
vec4 diffuseColor = vec4( diffuse, alphaTest );
#include <logdepthbuf_fragment>
#include <color_fragment>
gl_FragColor = vec4( diffuseColor.rgb, diffuseColor.a );
#include <premultiplied_alpha_fragment>
#include <tonemapping_fragment>
#include <encodings_fragment>
#include <fog_fragment>
}`
Triangle vertex shader:
`precision highp float;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform float zoomLevel;
attribute vec3 position;
attribute vec3 vertexPos;
attribute vec3 color;
attribute float alpha;
attribute float xAngle;
attribute float yAngle;
attribute float xScale;
attribute float yScale;
varying vec4 vColor;
// transforms the 'positions' geometry with instance attributes
vec3 transform( inout vec3 position, vec3 T) {
position.x *= xScale;
position.y *= yScale;
// Rotate the position
vec3 rotatedPosition = vec3(
position.x * yAngle + position.y * xAngle,
position.y * yAngle - position.x * xAngle, 0);
position = rotatedPosition + T;
// return the transformed position
return position;
}
void main() {
vec3 pos = position;
vColor = vec4(color, alpha);
// transform it
transform(pos, vertexPos);
gl_Position = projectionMatrix * modelViewMatrix * vec4( pos, 1.0 );
}`
Triangle FragmentShader:
`precision highp float;
varying vec4 vColor;
void main() {
gl_FragColor = vColor;
}`
Will really appreciate any help on how to do it or suggestion of right direction for further investigations. Thank you!
I'm trying to build a three.js scene using the OutlineEffect.js from the examples (https://github.com/mrdoob/three.js/blob/dev/examples/js/effects/OutlineEffect.js). This works great.
However, when I add fog to the scene, I then get this error, and the outline doesn't show up:
THREE.WebGLProgram: shader error: 1282 gl.VALIDATE_STATUS false gl.getProgramInfoLog invalid shaders ERROR: 0:204: 'fogDepth' : redefinition
The relevant parts of the code (I hope) are:
var outline = new THREE.OutlineEffect(window.renderer, {
defaultThickness : window.sceneSettings.lineThickness
});
if (window.sceneSettings.useFog) {
var newFog = new THREE.Fog(0xffffff, window.sceneSettings.fogNear, window.sceneSettings.fogFar)
scene.fog = newFog
}
function render(e) {
outline.render(scene, window.camera)
}
I apologize if this question is naive; I'm not really a js or threejs person, I'm a data scientist trying to feel my way around this.
Thank you in advance for any advice!
EDIT:
More from the logs:
The first error is three.module.js:16963 THREE.WebGLShader: Shader couldn't compile. with the following source dump:
THREE.WebGLShader: gl.getShaderInfoLog() vertex ERROR: 0:178: 'fogDepth' : redefinition
1: precision highp float;
2: precision highp int;
3: #define SHADER_NAME ShaderMaterial
4: #define VERTEX_TEXTURES
5: #define GAMMA_FACTOR 2
6: #define MAX_BONES 0
7: #define USE_FOG
8: #define BONE_TEXTURE
9: #define FLIP_SIDED
10: uniform mat4 modelMatrix;
11: uniform mat4 modelViewMatrix;
12: uniform mat4 projectionMatrix;
13: uniform mat4 viewMatrix;
14: uniform mat3 normalMatrix;
15: uniform vec3 cameraPosition;
16: attribute vec3 position;
17: attribute vec3 normal;
18: attribute vec2 uv;
19: #ifdef USE_COLOR
20: attribute vec3 color;
21: #endif
22: #ifdef USE_MORPHTARGETS
23: attribute vec3 morphTarget0;
24: attribute vec3 morphTarget1;
25: attribute vec3 morphTarget2;
26: attribute vec3 morphTarget3;
27: #ifdef USE_MORPHNORMALS
28: attribute vec3 morphNormal0;
29: attribute vec3 morphNormal1;
30: attribute vec3 morphNormal2;
31: attribute vec3 morphNormal3;
32: #else
33: attribute vec3 morphTarget4;
34: attribute vec3 morphTarget5;
35: attribute vec3 morphTarget6;
36: attribute vec3 morphTarget7;
37: #endif
38: #endif
39: #ifdef USE_SKINNING
40: attribute vec4 skinIndex;
41: attribute vec4 skinWeight;
42: #endif
43:
44: #define PI 3.14159265359
45: #define PI2 6.28318530718
46: #define PI_HALF 1.5707963267949
47: #define RECIPROCAL_PI 0.31830988618
48: #define RECIPROCAL_PI2 0.15915494
49: #define LOG2 1.442695
50: #define EPSILON 1e-6
51: #define saturate(a) clamp( a, 0.0, 1.0 )
52: #define whiteCompliment(a) ( 1.0 - saturate( a ) )
53: float pow2( const in float x ) { return x*x; }
54: float pow3( const in float x ) { return x*x*x; }
55: float pow4( const in float x ) { float x2 = x*x; return x2*x2; }
56: float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }
57: highp float rand( const in vec2 uv ) {
58: const highp float a = 12.9898, b = 78.233, c = 43758.5453;
59: highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );
60: return fract(sin(sn) * c);
61: }
62: struct IncidentLight {
63: vec3 color;
64: vec3 direction;
65: bool visible;
66: };
67: struct ReflectedLight {
68: vec3 directDiffuse;
69: vec3 directSpecular;
70: vec3 indirectDiffuse;
71: vec3 indirectSpecular;
72: };
73: struct GeometricContext {
74: vec3 position;
75: vec3 normal;
76: vec3 viewDir;
77: };
78: vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
79: return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
80: }
81: vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {
82: return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );
83: }
84: vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
85: float distance = dot( planeNormal, point - pointOnPlane );
86: return - distance * planeNormal + point;
87: }
88: float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
89: return sign( dot( point - pointOnPlane, planeNormal ) );
90: }
91: vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {
92: return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;
93: }
94: mat3 transposeMat3( const in mat3 m ) {
95: mat3 tmp;
96: tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );
97: tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );
98: tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );
99: return tmp;
100: }
101: float linearToRelativeLuminance( const in vec3 color ) {
102: vec3 weights = vec3( 0.2126, 0.7152, 0.0722 );
103: return dot( weights, color.rgb );
104: }
105:
106: #if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )
107: varying vec2 vUv;
108: uniform mat3 uvTransform;
109: #endif
110:
111: #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )
112: attribute vec2 uv2;
113: varying vec2 vUv2;
114: #endif
115: #ifdef USE_ENVMAP
116: #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )
117: varying vec3 vWorldPosition;
118: #else
119: varying vec3 vReflect;
120: uniform float refractionRatio;
121: #endif
122: #endif
123:
124: #ifdef USE_COLOR
125: varying vec3 vColor;
126: #endif
127: #ifdef USE_FOG
128: varying float fogDepth;
129: #endif
130:
131: #ifdef USE_MORPHTARGETS
132: #ifndef USE_MORPHNORMALS
133: uniform float morphTargetInfluences[ 8 ];
134: #else
135: uniform float morphTargetInfluences[ 4 ];
136: #endif
137: #endif
138: #ifdef USE_SKINNING
139: uniform mat4 bindMatrix;
140: uniform mat4 bindMatrixInverse;
141: #ifdef BONE_TEXTURE
142: uniform sampler2D boneTexture;
143: uniform int boneTextureSize;
144: mat4 getBoneMatrix( const in float i ) {
145: float j = i * 4.0;
146: float x = mod( j, float( boneTextureSize ) );
147: float y = floor( j / float( boneTextureSize ) );
148: float dx = 1.0 / float( boneTextureSize );
149: float dy = 1.0 / float( boneTextureSize );
150: y = dy * ( y + 0.5 );
151: vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );
152: vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );
153: vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );
154: vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );
155: mat4 bone = mat4( v1, v2, v3, v4 );
156: return bone;
157: }
158: #else
159: uniform mat4 boneMatrices[ MAX_BONES ];
160: mat4 getBoneMatrix( const in float i ) {
161: mat4 bone = boneMatrices[ int(i) ];
162: return bone;
163: }
164: #endif
165: #endif
166:
167: #ifdef USE_LOGDEPTHBUF
168: #ifdef USE_LOGDEPTHBUF_EXT
169: varying float vFragDepth;
170: #endif
171: uniform float logDepthBufFC;
172: #endif
173: #if 0 > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )
174: varying vec3 vViewPosition;
175: #endif
176:
177: #ifdef USE_FOG
178: varying float fogDepth;
179: #endif
180:
181: uniform float outlineThickness;
182: vec4 calculateOutline( vec4 pos, vec3 objectNormal, vec4 skinned ) {
183: float thickness = outlineThickness;
184: const float ratio = 1.0;
185: vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + objectNormal, 1.0 );
186: vec4 norm = normalize( pos - pos2 );
187: return pos + norm * thickness * pos.w * ratio;
188: }
189: void main() {
190: #if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )
191: vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
192: #endif
193: #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )
194: vUv2 = uv2;
195: #endif
196: #ifdef USE_COLOR
197: vColor.xyz = color.xyz;
198: #endif
199: #ifdef USE_SKINNING
200: mat4 boneMatX = getBoneMatrix( skinIndex.x );
201: mat4 boneMatY = getBoneMatrix( skinIndex.y );
202: mat4 boneMatZ = getBoneMatrix( skinIndex.z );
203: mat4 boneMatW = getBoneMatrix( skinIndex.w );
204: #endif
205: #ifdef USE_ENVMAP
206:
207: vec3 objectNormal = vec3( normal );
208:
209: #ifdef USE_MORPHNORMALS
210: objectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];
211: objectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];
212: objectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];
213: objectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];
214: #endif
215:
216: #ifdef USE_SKINNING
217: mat4 skinMatrix = mat4( 0.0 );
218: skinMatrix += skinWeight.x * boneMatX;
219: skinMatrix += skinWeight.y * boneMatY;
220: skinMatrix += skinWeight.z * boneMatZ;
221: skinMatrix += skinWeight.w * boneMatW;
222: skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;
223: objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;
224: #endif
225:
226: vec3 transformedNormal = normalMatrix * objectNormal;
227: #ifdef FLIP_SIDED
228: transformedNormal = - transformedNormal;
229: #endif
230:
231: #endif
232:
233: vec3 transformed = vec3( position );
234:
235: #ifdef USE_MORPHTARGETS
236: transformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];
237: transformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];
238: transformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];
239: transformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];
240: #ifndef USE_MORPHNORMALS
241: transformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];
242: transformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];
243: transformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];
244: transformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];
245: #endif
246: #endif
247:
248: #ifdef USE_SKINNING
249: vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
250: vec4 skinned = vec4( 0.0 );
251: skinned += boneMatX * skinVertex * skinWeight.x;
252: skinned += boneMatY * skinVertex * skinWeight.y;
253: skinned += boneMatZ * skinVertex * skinWeight.z;
254: skinned += boneMatW * skinVertex * skinWeight.w;
255: transformed = ( bindMatrixInverse * skinned ).xyz;
256: #endif
257:
258: vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );
259: gl_Position = projectionMatrix * mvPosition;
260:
261: #ifdef USE_LOGDEPTHBUF
262: #ifdef USE_LOGDEPTHBUF_EXT
263: vFragDepth = 1.0 + gl_Position.w;
264: #else
265: gl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;
266: gl_Position.z *= gl_Position.w;
267: #endif
268: #endif
269:
270: #if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )
271: vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );
272: #endif
273:
274: #if 0 > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )
275: vViewPosition = - mvPosition.xyz;
276: #endif
277:
278: #ifdef USE_ENVMAP
279: #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )
280: vWorldPosition = worldPosition.xyz;
281: #else
282: vec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );
283: vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );
284: #ifdef ENVMAP_MODE_REFLECTION
285: vReflect = reflect( cameraToVertex, worldNormal );
286: #else
287: vReflect = refract( cameraToVertex, worldNormal, refractionRatio );
288: #endif
289: #endif
290: #endif
291:
292:
293: #ifdef USE_FOG
294: fogDepth = -mvPosition.z;
295: #endif
296: #if ! defined( LAMBERT ) && ! defined( PHONG ) && ! defined( TOON ) && ! defined( PHYSICAL )
297: #ifndef USE_ENVMAP
298: vec3 objectNormal = normalize( normal );
299: #endif
300: #endif
301: #ifdef FLIP_SIDED
302: objectNormal = -objectNormal;
303: #endif
304: #ifdef DECLARE_TRANSFORMED
305: vec3 transformed = vec3( position );
306: #endif
307: gl_Position = calculateOutline( gl_Position, objectNormal, vec4( transformed, 1.0 ) );
308:
309: #ifdef USE_FOG
310: fogDepth = -mvPosition.z;
311: #endif
312: }
That code isn't in the OutlineEffect source. But the way OutlineEffect works, it includes this code where it redefines the vertex shader code using a regex:
var vertexShader = originalVertexShader
// put vertexShaderChunk right before "void main() {...}"
.replace( /void\s+main\s*\(\s*\)/, vertexShaderChunk + '\nvoid main()' )
// put vertexShaderChunk2 the end of "void main() {...}"
// Note: here assums originalVertexShader ends with "}" of "void main() {...}"
.replace( /\}\s*$/, vertexShaderChunk2 + '\n}' )
// remove any light related lines
// Note: here is very sensitive to originalVertexShader
// TODO: consider safer way
.replace( /#include\s+<[\w_]*light[\w_]*>/g, '' );
And here is the source dump from the error that refers to line 204 (note that I'm cutting these lengthy source dumps after the relevant line)
gl.getShaderInfoLog() vertex ERROR: 0:204: 'fogDepth' : redefinition
1: precision highp float;
2: precision highp int;
3: #define SHADER_NAME ShaderMaterial
4: #define VERTEX_TEXTURES
5: #define GAMMA_FACTOR 2
6: #define MAX_BONES 0
7: #define USE_FOG
8: #define BONE_TEXTURE
9: #define FLIP_SIDED
10: uniform mat4 modelMatrix;
11: uniform mat4 modelViewMatrix;
12: uniform mat4 projectionMatrix;
13: uniform mat4 viewMatrix;
14: uniform mat3 normalMatrix;
15: uniform vec3 cameraPosition;
16: attribute vec3 position;
17: attribute vec3 normal;
18: attribute vec2 uv;
19: #ifdef USE_COLOR
20: attribute vec3 color;
21: #endif
22: #ifdef USE_MORPHTARGETS
23: attribute vec3 morphTarget0;
24: attribute vec3 morphTarget1;
25: attribute vec3 morphTarget2;
26: attribute vec3 morphTarget3;
27: #ifdef USE_MORPHNORMALS
28: attribute vec3 morphNormal0;
29: attribute vec3 morphNormal1;
30: attribute vec3 morphNormal2;
31: attribute vec3 morphNormal3;
32: #else
33: attribute vec3 morphTarget4;
34: attribute vec3 morphTarget5;
35: attribute vec3 morphTarget6;
36: attribute vec3 morphTarget7;
37: #endif
38: #endif
39: #ifdef USE_SKINNING
40: attribute vec4 skinIndex;
41: attribute vec4 skinWeight;
42: #endif
43:
44: #define PHONG
45: varying vec3 vViewPosition;
46: #ifndef FLAT_SHADED
47: varying vec3 vNormal;
48: #endif
49: #define PI 3.14159265359
50: #define PI2 6.28318530718
51: #define PI_HALF 1.5707963267949
52: #define RECIPROCAL_PI 0.31830988618
53: #define RECIPROCAL_PI2 0.15915494
54: #define LOG2 1.442695
55: #define EPSILON 1e-6
56: #define saturate(a) clamp( a, 0.0, 1.0 )
57: #define whiteCompliment(a) ( 1.0 - saturate( a ) )
58: float pow2( const in float x ) { return x*x; }
59: float pow3( const in float x ) { return x*x*x; }
60: float pow4( const in float x ) { float x2 = x*x; return x2*x2; }
61: float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }
62: highp float rand( const in vec2 uv ) {
63: const highp float a = 12.9898, b = 78.233, c = 43758.5453;
64: highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );
65: return fract(sin(sn) * c);
66: }
67: struct IncidentLight {
68: vec3 color;
69: vec3 direction;
70: bool visible;
71: };
72: struct ReflectedLight {
73: vec3 directDiffuse;
74: vec3 directSpecular;
75: vec3 indirectDiffuse;
76: vec3 indirectSpecular;
77: };
78: struct GeometricContext {
79: vec3 position;
80: vec3 normal;
81: vec3 viewDir;
82: };
83: vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
84: return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
85: }
86: vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {
87: return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );
88: }
89: vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
90: float distance = dot( planeNormal, point - pointOnPlane );
91: return - distance * planeNormal + point;
92: }
93: float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
94: return sign( dot( point - pointOnPlane, planeNormal ) );
95: }
96: vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {
97: return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;
98: }
99: mat3 transposeMat3( const in mat3 m ) {
100: mat3 tmp;
101: tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );
102: tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );
103: tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );
104: return tmp;
105: }
106: float linearToRelativeLuminance( const in vec3 color ) {
107: vec3 weights = vec3( 0.2126, 0.7152, 0.0722 );
108: return dot( weights, color.rgb );
109: }
110:
111: #if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )
112: varying vec2 vUv;
113: uniform mat3 uvTransform;
114: #endif
115:
116: #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )
117: attribute vec2 uv2;
118: varying vec2 vUv2;
119: #endif
120: #ifdef USE_DISPLACEMENTMAP
121: uniform sampler2D displacementMap;
122: uniform float displacementScale;
123: uniform float displacementBias;
124: #endif
125:
126: #ifdef USE_ENVMAP
127: #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )
128: varying vec3 vWorldPosition;
129: #else
130: varying vec3 vReflect;
131: uniform float refractionRatio;
132: #endif
133: #endif
134:
135: #ifdef USE_COLOR
136: varying vec3 vColor;
137: #endif
138: #ifdef USE_FOG
139: varying float fogDepth;
140: #endif
141:
142: #ifdef USE_MORPHTARGETS
143: #ifndef USE_MORPHNORMALS
144: uniform float morphTargetInfluences[ 8 ];
145: #else
146: uniform float morphTargetInfluences[ 4 ];
147: #endif
148: #endif
149: #ifdef USE_SKINNING
150: uniform mat4 bindMatrix;
151: uniform mat4 bindMatrixInverse;
152: #ifdef BONE_TEXTURE
153: uniform sampler2D boneTexture;
154: uniform int boneTextureSize;
155: mat4 getBoneMatrix( const in float i ) {
156: float j = i * 4.0;
157: float x = mod( j, float( boneTextureSize ) );
158: float y = floor( j / float( boneTextureSize ) );
159: float dx = 1.0 / float( boneTextureSize );
160: float dy = 1.0 / float( boneTextureSize );
161: y = dy * ( y + 0.5 );
162: vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );
163: vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );
164: vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );
165: vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );
166: mat4 bone = mat4( v1, v2, v3, v4 );
167: return bone;
168: }
169: #else
170: uniform mat4 boneMatrices[ MAX_BONES ];
171: mat4 getBoneMatrix( const in float i ) {
172: mat4 bone = boneMatrices[ int(i) ];
173: return bone;
174: }
175: #endif
176: #endif
177:
178: #ifdef USE_SHADOWMAP
179: #if 1 > 0
180: uniform mat4 directionalShadowMatrix[ 1 ];
181: varying vec4 vDirectionalShadowCoord[ 1 ];
182: #endif
183: #if 0 > 0
184: uniform mat4 spotShadowMatrix[ 0 ];
185: varying vec4 vSpotShadowCoord[ 0 ];
186: #endif
187: #if 4 > 0
188: uniform mat4 pointShadowMatrix[ 4 ];
189: varying vec4 vPointShadowCoord[ 4 ];
190: #endif
191: #endif
192:
193: #ifdef USE_LOGDEPTHBUF
194: #ifdef USE_LOGDEPTHBUF_EXT
195: varying float vFragDepth;
196: #endif
197: uniform float logDepthBufFC;
198: #endif
199: #if 0 > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )
200: varying vec3 vViewPosition;
201: #endif
202:
203: #ifdef USE_FOG
204: varying float fogDepth;
205: #endif
206:
207: uniform float outlineThickness;
208: vec4 calculateOutline( vec4 pos, vec3 objectNormal, vec4 skinned ) {
209: float thickness = outlineThickness;
210: const float ratio = 1.0;
211: vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + objectNormal, 1.0 );
212: vec4 norm = normalize( pos - pos2 );
213: return pos + norm * thickness * pos.w * ratio;
214: }
215: void main() {
216: #if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )
217: vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
218: #endif
219: #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )
220: vUv2 = uv2;
221: #endif
222: #ifdef USE_COLOR
223: vColor.xyz = color.xyz;
224: #endif
225:
226: vec3 objectNormal = vec3( normal );
227:
228: #ifdef USE_MORPHNORMALS
229: objectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];
230: objectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];
231: objectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];
232: objectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];
233: #endif
234:
235: #ifdef USE_SKINNING
236: mat4 boneMatX = getBoneMatrix( skinIndex.x );
237: mat4 boneMatY = getBoneMatrix( skinIndex.y );
238: mat4 boneMatZ = getBoneMatrix( skinIndex.z );
239: mat4 boneMatW = getBoneMatrix( skinIndex.w );
240: #endif
241: #ifdef USE_SKINNING
242: mat4 skinMatrix = mat4( 0.0 );
243: skinMatrix += skinWeight.x * boneMatX;
244: skinMatrix += skinWeight.y * boneMatY;
245: skinMatrix += skinWeight.z * boneMatZ;
246: skinMatrix += skinWeight.w * boneMatW;
247: skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;
248: objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;
249: #endif
250:
251: vec3 transformedNormal = normalMatrix * objectNormal;
252: #ifdef FLIP_SIDED
253: transformedNormal = - transformedNormal;
254: #endif
255:
256: #ifndef FLAT_SHADED
257: vNormal = normalize( transformedNormal );
258: #endif
259:
260: vec3 transformed = vec3( position );
261:
262: #ifdef USE_MORPHTARGETS
263: transformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];
264: transformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];
265: transformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];
266: transformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];
267: #ifndef USE_MORPHNORMALS
268: transformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];
269: transformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];
270: transformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];
271: transformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];
272: #endif
273: #endif
274:
275: #ifdef USE_SKINNING
276: vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
277: vec4 skinned = vec4( 0.0 );
278: skinned += boneMatX * skinVertex * skinWeight.x;
279: skinned += boneMatY * skinVertex * skinWeight.y;
280: skinned += boneMatZ * skinVertex * skinWeight.z;
281: skinned += boneMatW * skinVertex * skinWeight.w;
282: transformed = ( bindMatrixInverse * skinned ).xyz;
283: #endif
284:
285: #ifdef USE_DISPLACEMENTMAP
286: transformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );
287: #endif
288:
289: vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );
290: gl_Position = projectionMatrix * mvPosition;
291:
292: #ifdef USE_LOGDEPTHBUF
293: #ifdef USE_LOGDEPTHBUF_EXT
294: vFragDepth = 1.0 + gl_Position.w;
295: #else
296: gl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;
297: gl_Position.z *= gl_Position.w;
298: #endif
299: #endif
300:
301: #if 0 > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )
302: vViewPosition = - mvPosition.xyz;
303: #endif
304:
305: vViewPosition = - mvPosition.xyz;
306: #if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )
307: vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );
308: #endif
309:
310: #ifdef USE_ENVMAP
311: #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )
312: vWorldPosition = worldPosition.xyz;
313: #else
314: vec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );
315: vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );
316: #ifdef ENVMAP_MODE_REFLECTION
317: vReflect = reflect( cameraToVertex, worldNormal );
318: #else
319: vReflect = refract( cameraToVertex, worldNormal, refractionRatio );
320: #endif
321: #endif
322: #endif
323:
324: #ifdef USE_SHADOWMAP
325: #if 1 > 0
326:
327: vDirectionalShadowCoord[ 0 ] = directionalShadowMatrix[ 0 ] * worldPosition;
328:
329: #endif
330: #if 0 > 0
331:
332: #endif
333: #if 4 > 0
334:
335: vPointShadowCoord[ 0 ] = pointShadowMatrix[ 0 ] * worldPosition;
336:
337: vPointShadowCoord[ 1 ] = pointShadowMatrix[ 1 ] * worldPosition;
338:
339: vPointShadowCoord[ 2 ] = pointShadowMatrix[ 2 ] * worldPosition;
340:
341: vPointShadowCoord[ 3 ] = pointShadowMatrix[ 3 ] * worldPosition;
342:
343: #endif
344: #endif
345:
346:
347: #ifdef USE_FOG
348: fogDepth = -mvPosition.z;
349: #endif
350: #if ! defined( LAMBERT ) && ! defined( PHONG ) && ! defined( TOON ) && ! defined( PHYSICAL )
351: #ifndef USE_ENVMAP
352: vec3 objectNormal = normalize( normal );
353: #endif
354: #endif
355: #ifdef FLIP_SIDED
356: objectNormal = -objectNormal;
357: #endif
358: #ifdef DECLARE_TRANSFORMED
359: vec3 transformed = vec3( position );
360: #endif
361: gl_Position = calculateOutline( gl_Position, objectNormal, vec4( transformed, 1.0 ) );
362:
363: #ifdef USE_FOG
364: fogDepth = -mvPosition.z;
365: #endif
366: }
I'm trying to port this shader https://www.shadertoy.com/view/MsB3WR to
THREE.JS and actually it's almost there, but I have an issue with UV mapping,
so by now have something like this:
SHADER CODE:
vertexShader:
void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }
fragmentShader:
//mouse.z - left click
//mouse.w - right click
//texture A > iChannel0 > assets/textureA.png
//texture B > iChannel1 > assets/textureB.png
//texture C > iChannel2 > assets/textureC.png
#define BUMPFACTOR 0.1
#define EPSILON 0.1
#define BUMPDISTANCE 60.
//(iGlobalTime + 285.)
uniform float time;
uniform sampler2D textureA;
uniform sampler2D textureB;
uniform sampler2D textureC;
uniform vec2 resolution;
uniform vec3 mouse;
mat2 rot(const in float a) { return mat2(cos(a), sin(a), -sin(a), cos(a)); }
const mat2 m2 = mat2( 0.60, -0.80, 0.80, 0.60 );
const mat3 m3 = mat3( 0.00, 0.80, 0.60, -0.80, 0.36, -0.48, -0.60, -0.48, 0.64 );
float noise( const in vec2 x ) {
vec2 p = floor(x);
vec2 f = fract(x);
f = f * f * (3.0 - 2.0 * f);
vec2 uv = (p.xy) + f.xy;
return texture2D( textureA, (uv + 0.5) / 256.0, 0.0 ).x;
}
float noise( const in vec3 x ) {
vec3 p = floor(x);
vec3 f = fract(x);
f = f*f*(3.0-2.0*f);
vec2 uv = (p.xy + vec2(37.0, 17.0) * p.z) + f.xy;
vec2 rg = texture2D( textureA, (uv + 0.5) / 256.0, 0.0 ).yx;
return mix( rg.x, rg.y, f.z );
}
float fbm( in vec3 p ) {
float f = 0.0;
f += 0.5000 * noise(p); p = m3 * p * 2.02;
f += 0.2500 * noise(p); p = m3 * p * 2.03;
f += 0.1250 * noise(p); p = m3 * p * 2.01;
f += 0.0625 * noise(p);
return f / 0.9375;
}
float hash( in float n ) { return fract(sin(n) * 43758.5453); }
//INTERSECTION FUNCTION
bool intersectPlane(const in vec3 ro, const in vec3 rd, const in float height, inout float dist) {
if (rd.y == 0.0) { return false; }
float d = -(ro.y - height)/rd.y;
d = min(100000.0, d);
if( d > 0. && d < dist ) {
dist = d;
return true;
}
return false;
}
//LIGHT DIRECTION
vec3 lig = normalize(vec3( 0.3, 0.5, 0.6));
vec3 bgColor( const in vec3 rd ) {
float sun = clamp( dot(lig, rd), 0.0, 1.0 );
vec3 col = vec3(0.5, 0.52, 0.55) - rd.y * 0.2 * vec3(1.0, 0.8, 1.0) + 0.15 * 0.75;
col += vec3(1.0, 0.6, 0.1) * pow( sun, 8.0 );
col *= 0.95;
return col;
}
//CLOUDS
#define CLOUDSCALE (500. / (64. * 0.03))
float cloudMap( const in vec3 p, const in float ani ) {
vec3 r = p / CLOUDSCALE;
float den = -1.8 + cos(r.y * 5.-4.3);
float f;
vec3 q = 2.5 * r * vec3(0.75, 1.0, 0.75) + vec3(1.0, 1.0, 15.0) * ani * 0.15;
f = 0.50000 * noise(q); q = q * 2.02 - vec3(-1.0,1.0,-1.0) * ani * 0.15;
f += 0.25000 * noise(q); q = q * 2.03 + vec3(1.0, -1.0, 1.0) * ani * 0.15;
f += 0.12500 * noise(q); q = q * 2.01 - vec3(1.0, 1.0, -1.0) * ani * 0.15;
f += 0.06250 * noise(q); q = q * 2.02 + vec3(1.0, 1.0, 1.0) * ani * 0.15;
f += 0.03125 * noise(q);
return 0.065 * clamp( den + 4.4 * f, 0.0, 1.0 );
}
vec3 raymarchClouds( const in vec3 ro, const in vec3 rd, const in vec3 bgc, const in vec3 fgc, const in float startdist, const in float maxdist, const in float ani ) {
float t = startdist + CLOUDSCALE * 0.02 * hash(rd.x + 35.6987221 * rd.y + time);
vec4 sum = vec4( 0.0 );
for( int i=0; i<64; i++ ) {
if( sum.a > 0.99 || t > maxdist ) continue;
vec3 pos = ro + t*rd;
float a = cloudMap( pos, ani );
float dif = clamp(0.1 + 0.8*(a - cloudMap( pos + lig*0.15*CLOUDSCALE, ani )), 0., 0.5);
vec4 col = vec4( (1.+dif)*fgc, a );
col.rgb *= col.a;
sum = sum + col*(1.0 - sum.a);
t += (0.03*CLOUDSCALE)+t*0.012;
}
sum.xyz = mix( bgc, sum.xyz/(sum.w+0.0001), sum.w );
return clamp( sum.xyz, 0.0, 1.0 );
}
//TERRAIN
float terrainMap( const in vec3 p ) {
return (texture2D( textureB, (-p.zx*m2)*0.000046, 0. ).x*600.) * smoothstep( 820., 1000., length(p.xz) ) - 2. + noise(p.xz*0.5)*15.;
}
vec3 raymarchTerrain( const in vec3 ro, const in vec3 rd, const in vec3 bgc, const in float startdist, inout float dist ) {
float t = startdist;
vec4 sum = vec4( 0.0 );
bool hit = false;
vec3 col = bgc;
for( int i=0; i<80; i++ ) {
if( hit ) break;
t += 8. + t/300.;
vec3 pos = ro + t*rd;
if( pos.y < terrainMap(pos) ) {
hit = true;
}
}
if( hit ) {
float dt = 4.+t/400.;
t -= dt;
vec3 pos = ro + t*rd;
t += (0.5 - step( pos.y , terrainMap(pos) )) * dt;
for( int j=0; j<2; j++ ) {
pos = ro + t*rd;
dt *= 0.5;
t += (0.5 - step( pos.y , terrainMap(pos) )) * dt;
}
pos = ro + t*rd;
vec3 dx = vec3( 100.*EPSILON, 0., 0. );
vec3 dz = vec3( 0., 0., 100.*EPSILON );
vec3 normal = vec3( 0., 0., 0. );
normal.x = (terrainMap(pos + dx) - terrainMap(pos-dx) ) / (200. * EPSILON);
normal.z = (terrainMap(pos + dz) - terrainMap(pos-dz) ) / (200. * EPSILON);
normal.y = 1.;
normal = normalize( normal );
col = vec3(0.2) + 0.7 * texture2D( textureC , pos.xz * 0.01 ).xyz *
vec3(1.0, 0.9, 0.6);
float veg = 0.3*fbm(pos*0.2)+normal.y;
if( veg > 0.75 ) {
col = vec3( 0.45, 0.6, 0.3 )*(0.5+0.5*fbm(pos*0.5))*0.6;
} else
if( veg > 0.66 ) {
col = col*0.6+vec3( 0.4, 0.5, 0.3 )*(0.5+0.5*fbm(pos*0.25))*0.3;
}
col *= vec3(0.5, 0.52, 0.65)*vec3(1.,.9,0.8);
vec3 brdf = col;
float diff = clamp( dot( normal, -lig ), 0., 1.);
col = brdf*diff*vec3(1.0,.6,0.1);
col += brdf*clamp( dot( normal, lig ), 0., 1.)*vec3(0.8,.6,0.5)*0.8;
col += brdf*clamp( dot( normal, vec3(0.,1.,0.) ), 0., 1.)*vec3(0.8,.8,1.)*0.2;
dist = t;
t -= pos.y*3.5;
col = mix( col, bgc, 1.0-exp(-0.0000005*t*t) );
}
return col;
}
float waterMap( vec2 pos ) { vec2 posm = pos * m2; return abs( fbm( vec3( 8. * posm, time ))-0.5 ) * 0.1; }
void main(void)
{
vec2 q = gl_FragCoord.xy / resolution.xy;
vec2 p = -1.0 + 2.0 * q;
p.x *= resolution.x / resolution.y;
vec3 ro = vec3(0.0, 0.5, 0.0);
vec3 ta = vec3(0.0, 0.45,1.0);
if (mouse.z >= 1.0) { ta.xz *= rot( (mouse.x / resolution.x - 0.5) * 7.0 ); }
ta.xz *= rot( mod(time * 0.05, 6.2831852) );
vec3 ww = normalize( ta - ro);
vec3 uu = normalize(cross( vec3(0.0,1.0,0.0), ww ));
vec3 vv = normalize(cross(ww,uu));
vec3 rd = normalize( p.x*uu + p.y*vv + 2.5*ww );
float fresnel, refldist = 5000., maxdist = 5000.;
bool reflected = false;
vec3 normal, col = bgColor( rd );
vec3 roo = ro, rdo = rd, bgc = col;
if( intersectPlane( ro, rd, 0., refldist ) && refldist < 200. ) {
ro += refldist*rd;
vec2 coord = ro.xz;
float bumpfactor = BUMPFACTOR * (1. - smoothstep( 0., BUMPDISTANCE, refldist) );
vec2 dx = vec2( EPSILON, 0. );
vec2 dz = vec2( 0., EPSILON );
normal = vec3( 0., 1., 0. );
normal.x = -bumpfactor * (waterMap(coord + dx) - waterMap(coord-dx) ) / (2. * EPSILON);
normal.z = -bumpfactor * (waterMap(coord + dz) - waterMap(coord-dz) ) / (2. * EPSILON);
normal = normalize( normal );
float ndotr = dot(normal,rd);
fresnel = pow(1.0-abs(ndotr),5.);
rd = reflect( rd, normal);
reflected = true;
bgc = col = bgColor( rd );
}
col = raymarchTerrain( ro, rd, col, reflected?(800.-refldist):800., maxdist );
col = raymarchClouds( ro, rd, col, bgc, reflected?max(0.,min(150.,(150.-refldist))):150., maxdist, time*0.05 );
if( reflected ) {
col = mix( col.xyz, bgc, 1.0-exp(-0.0000005 *refldist * refldist) );
col *= fresnel * 0.9;
vec3 refr = refract( rdo, normal, 1./1.3330 );
intersectPlane( ro, refr, -2., refldist );
col += mix( texture2D( textureC, (roo+refldist*refr).xz*1.3 ).xyz * vec3(1.0, 0.9, 0.6), vec3(1.0, 0.9, 0.8)*0.5, clamp( refldist / 3.0, 0.0, 1.0) ) * (1.-fresnel)*0.125;
}
col = pow( col, vec3(0.7) );
col = col * col * (3.0-2.0 * col);
col = mix( col, vec3(dot(col,vec3(0.33))), -0.5 );
col *= 0.25 + 0.75*pow( 16.0*q.x*q.y*(1.0-q.x)*(1.0-q.y), 0.1 );
//vec4 color = texture2D( textureA, vUv );
gl_FragColor = vec4( col, 1.0 );
}
And JavaScript [initialising]:
clock = new THREE.Clock();
mouse = new THREE.Vector4();
var loaderA = new THREE.TextureLoader();
var bitmapA = loaderA.load("assets/textureA.png");
var loaderB = new THREE.TextureLoader();
var bitmapB = loaderB.load("assets/textureB.png");
var loaderC = new THREE.TextureLoader();
var bitmapC = loaderC.load("assets/textureC.png");
var uniforms = {
textureA: { type: 't', value: bitmapA },
textureB: { type: 't', value: bitmapB },
textureC: { type: 't', value: bitmapC },
time: {
type: 'f',
value: clock.getDelta() + 285.
},
resolution: {
type: 'v2',
value: new THREE.Vector2( window.innerWidth, window.innerHeight)
},
mouse: {
type: 'v4',
value: new THREE.Vector4(window.innerWidth / 2, window.innerHeight / 2, 0.0, 0.0)
}
};
var glslMat = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById("vertexShader").textContent,
fragmentShader: document.getElementById("fragmentShader").textContent
} );
var geometry = new THREE.PlaneGeometry(window.innerWidth * 4 , window.innerHeight * 4, 1, 1);
var plane = new THREE.Mesh(geometry, glslMat);
Any suggestions?
The issue was solved by implementing texture wrapping and its sampling
var loaderA = new THREE.TextureLoader();
var bitmapA = loaderA.load( 'assets/originalRGBA.png', function ( texture ) {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.offset.set( 0, 0 );
texture.repeat.set( 2, 2 );
} );