three.js WebGL: INVALID_OPERATION: drawElements: no valid shader program in use - three.js

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.

Related

Three.js ShaderMaterial Post Processing and Transparent Background

I'm trying to work with this shader, but I need a transparent background and it renders a black background.
I realized that this is done within the fragmentShader, but I haven't figured out how to change it, and I don't even know if it's possible.
Would anyone with experience in shaders know how to tell me?
var myEffect = {
uniforms: {
"tDiffuse": { value: null },
"distort": { value: 0 },
"resolution": { value: new THREE.Vector2(1., innerHeight / innerWidth) },
"uMouse": { value: new THREE.Vector2(-10, -10) },
"uVelo": { value: 0 },
"time": { value: 0 }
},
vertexShader: `uniform float time;
uniform float progress;
uniform vec2 resolution;
varying vec2 vUv;
uniform sampler2D texture1;
const float pi = 3.1415925;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0 );
}`,
fragmentShader: `uniform float time;
uniform float progress;
uniform sampler2D tDiffuse;
uniform vec2 resolution;
varying vec2 vUv;
uniform vec2 uMouse;
uniform float uVelo;
float circle(vec2 uv, vec2 disc_center, float disc_radius, float border_size) {
uv -= disc_center;
uv*=resolution;
float dist = sqrt(dot(uv, uv));
return smoothstep(disc_radius+border_size, disc_radius-border_size, dist);
}
float map(float value, float min1, float max1, float min2, float max2) {
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
}
float remap(float value, float inMin, float inMax, float outMin, float outMax) {
return outMin + (outMax - outMin) * (value - inMin) / (inMax - inMin);
}
float hash12(vec2 p) {
float h = dot(p,vec2(127.1,311.7));
return fract(sin(h)*43758.5453123);
}
// #define HASHSCALE3 vec3(.1031, .1030, .0973)
vec2 hash2d(vec2 p)
{
vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));
p3 += dot(p3, p3.yzx+19.19);
return fract((p3.xx+p3.yz)*p3.zy);
}
void main() {
vec2 newUV = vUv;
vec4 color = vec4(1.,0.,0.,1.);
float c = circle(newUV, uMouse, 0.0, 0.2);
float r = texture2D(tDiffuse, newUV.xy += c * (uVelo * .5)).x;
float g = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).y;
float b = texture2D(tDiffuse, newUV.xy += c * (uVelo * .55)).z;
color = vec4(r, g, b, 1.);
gl_FragColor = color;
}`
}
Well, assuming you set up three.js for transparency then my guess is
the last part
void main() {
vec2 newUV = vUv;
vec4 color = vec4(1.,0.,0.,1.);
float c = circle(newUV, uMouse, 0.0, 0.2);
float r = texture2D(tDiffuse, newUV.xy += c * (uVelo * .5)).x;
float g = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).y;
float b = texture2D(tDiffuse, newUV.xy += c * (uVelo * .55)).z;
float a = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).w; // added
color = vec4(r, g, b, a); // changed
gl_FragColor = color;
}`
This might also work better
vec4 c1 = texture2D(tDiffuse, newUV.xy += c * (0.1 * .5));
vec4 c2 = texture2D(tDiffuse, newUV.xy += c * (0.1 * .525));
vec4 c3 = texture2D(tDiffuse, newUV.xy += c * (0.1 * .55));
float a = min(min(c1.a, c2.a), c3.a);
vec4 color = vec4(c1.r, c2.g, c3.b, a);
gl_FragColor = color;
You maybe also need to premultiply the alpha
gl_FragColor = color;
gl_FragColor.rgb *= gl_FragColor.a;
Thanks #gman, you helped me understand the algorithm. I solved it as follows.
void main() {
vec2 newUV = vUv;
float c = circle(newUV, uMouse, 0.0, 0.2);
float a = texture2D(tDiffuse, newUV.xy+c*(uVelo)).w; //added
float r = texture2D(tDiffuse, newUV.xy += c * (uVelo * .5)).x;
float g = texture2D(tDiffuse, newUV.xy += c * (uVelo * .525)).y;
float b = texture2D(tDiffuse, newUV.xy += c * (uVelo * .55)).z;
vec4 color = vec4(r, g, b, r+g+b+a); //changed
gl_FragColor = color;
}

What is this called and how to achieve! Visuals in processing

Hey does anyone know how to achieve this effect using processing or what this is called?
I have been trying to use the wave gradient example in the processing library and implementing Perlin noise but I can not get close to the gif quality.
I know the artist used processing but can not figure out how!
Link to gif:
https://giphy.com/gifs/processing-jodeus-QInYLzY33wMwM
The effect is reminescent of Op Art (optical illusion art): I recommend reading/learning more about this fascinating genre and artists like:
Bridget Riley
(Bridget Riley, Intake, 1964)
(Bridget Riley, Hesistate, 1964,
Copyright: (c) Bridget Riley 2018. All rights reserved. / Photo (c) Tate)
Victor Vasarely
(Victor Vasarely, Zebra Couple)
(Victor Vasarely, VegaII)
Frank Stella
(Frank Stella, Untitled 1965, Image curtesy of Art Gallery NSW)
and more
You notice this waves are reminiscent/heavily inspired by Bridget Riley's work.
I also recommend checking out San Charoenchai;s album visualiser for Beach House - 7
As mentioned in my comment: you should post your attempt.
Waves and perlin noise could work for sure.
There are many ways to achieve a similar look.
Here's tweaked version of Daniel Shiffman's Noise Wave example:
int numWaves = 24;
float[] yoff = new float[numWaves]; // 2nd dimension of perlin noise
float[] yoffIncrements = new float[numWaves];
void setup() {
size(640, 360);
noStroke();
for(int i = 0 ; i < numWaves; i++){
yoffIncrements[i] = map(i, 0, numWaves - 1, 0.01, 0.03);
}
}
void draw() {
background(0);
float waveHeight = height / numWaves;
for(int i = 0 ; i < numWaves; i++){
float waveY = i * waveHeight;
fill(i % 2 == 0 ? color(255) : color(0));
// We are going to draw a polygon out of the wave points
beginShape();
float xoff = 0; // Option #1: 2D Noise
// float xoff = yoff; // Option #2: 1D Noise
// Iterate over horizontal pixels
for (float x = 0; x <= width + 30; x += 20) {
// Calculate a y value according to noise, map to
float y = map(noise(xoff, yoff[i]), 0, 1, waveY , waveY + (waveHeight * 3)); // Option #1: 2D Noise
// float y = map(noise(xoff), 0, 1, 200,300); // Option #2: 1D Noise
// Set the vertex
vertex(x, y);
// Increment x dimension for noise
xoff += 0.05;
}
// increment y dimension for noise
yoff[i] += yoffIncrements[i];
vertex(width, height);
vertex(0, height);
endShape(CLOSE);
}
}
Notice the quality of the noise wave in comparison to the image you're trying to emulate: there is a constant rhythm to it. To me that is a hint that it's using cycling sine waves changing phase and amplitude (potentially even adding waves together).
I've written an extensive answer on animating sine waves here
(Reuben Margolin's kinectic sculpture system demo)
From your question it sounds like you would be comfortable implementing a sine wave animation. It it helps, here's an example of adding two waves together:
void setup(){
size(600,600);
noStroke();
}
void draw(){
background(0);
// how many waves per sketch height
int heightDivisions = 30;
// split the sketch height into equal height sections
float heightDivisionSize = (float)height / heightDivisions;
// for each height division
for(int j = 0 ; j < heightDivisions; j++){
// use % 2 to alternate between black and white
// see https://processing.org/reference/modulo.html and
// https://processing.org/reference/conditional.html for more
fill(j % 2 == 0 ? color(255) : color(0));
// offset drawing on Y axis
translate(0,(j * heightDivisionSize));
// start a wave shape
beginShape();
// first vertex is at the top left corner
vertex(0,height);
// how many horizontal (per wave) divisions ?
int widthDivisions = 12;
// equally space the points on the wave horizontally
float widthDivsionSize = (float)width / widthDivisions;
// for each point on the wave
for(int i = 0; i <= widthDivisions; i++){
// calculate different phases
// play with arithmetic operators to make interesting wave additions
float phase1 = (frameCount * 0.01) + ((i * j) * 0.025);
float phase2 = (frameCount * 0.05) + ((i + j) * 0.25);
// calculate vertex x position
float x = widthDivsionSize * i;
// multiple sine waves
// (can use cos() and use other ratios too
// 150 in this case is the wave amplitude (e.g. from -150 to + 150)
float y = ((sin(phase1) * sin(phase2) * 150));
// draw calculated vertex
vertex(x,y);
}
// last vertex is at bottom right corner
vertex(width,height);
// finish the shape
endShape();
}
}
The result:
Minor note on performance: this could be implemented more efficiently using PShape, however I recommend playing with the maths/geometry to find the form you're after, then as a last step think of optimizing it.
My intention is not to show you how to create an exact replica, but to show there's more to Op Art than an effect and hopefully inspire you to explore other methods of achieving something similar in the hope that you will discover your own methods and outcomes: something new and of your own through fun happy accidents.
In terms of other techniques/avenues to explore:
displacement maps:
Using an alternating black/white straight bars texture on wavy 3D geometry
using shaders:
Shaders are a huge topic on their own, but it's worth noting:
There's a very good Processing Shader Tutorial
You might be able to explore frament shaders on shadertoy, tweak the code in browser then make slight changes so you can run them in Processing.
Here are a few quick examples:
https://www.shadertoy.com/view/Wts3DB
tweaked for black/white waves in Processing as shader-Wts3DB.frag
// https://www.shadertoy.com/view/Wts3DB
uniform vec2 iResolution;
uniform float iTime;
#define COUNT 6.
#define COL_BLACK vec3(23,32,38) / 255.0
#define SF 1./min(iResolution.x,iResolution.y)
#define SS(l,s) smoothstep(SF,-SF,l-s)
#define hue(h) clamp( abs( fract(h + vec4(3,2,1,0)/3.) * 6. - 3.) -1. , 0., 1.)
// Original noise code from https://www.shadertoy.com/view/4sc3z2
#define MOD3 vec3(.1031,.11369,.13787)
vec3 hash33(vec3 p3)
{
p3 = fract(p3 * MOD3);
p3 += dot(p3, p3.yxz+19.19);
return -1.0 + 2.0 * fract(vec3((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y, (p3.y+p3.z)*p3.x));
}
float simplex_noise(vec3 p)
{
const float K1 = 0.333333333;
const float K2 = 0.166666667;
vec3 i = floor(p + (p.x + p.y + p.z) * K1);
vec3 d0 = p - (i - (i.x + i.y + i.z) * K2);
vec3 e = step(vec3(0.0), d0 - d0.yzx);
vec3 i1 = e * (1.0 - e.zxy);
vec3 i2 = 1.0 - e.zxy * (1.0 - e);
vec3 d1 = d0 - (i1 - 1.0 * K2);
vec3 d2 = d0 - (i2 - 2.0 * K2);
vec3 d3 = d0 - (1.0 - 3.0 * K2);
vec4 h = max(0.6 - vec4(dot(d0, d0), dot(d1, d1), dot(d2, d2), dot(d3, d3)), 0.0);
vec4 n = h * h * h * h * vec4(dot(d0, hash33(i)), dot(d1, hash33(i + i1)), dot(d2, hash33(i + i2)), dot(d3, hash33(i + 1.0)));
return dot(vec4(31.316), n);
}
void mainImage( vec4 fragColor, vec2 fragCoord )
{
}
void main(void) {
//vec2 uv = vec2(gl_FragColor.x / iResolution.y, gl_FragColor.y / iResolution.y);
vec2 uv = gl_FragCoord.xy / iResolution.y;
float m = 0.;
float t = iTime *.5;
vec3 col;
for(float i=COUNT; i>=0.; i-=1.){
float edge = simplex_noise(vec3(uv * vec2(2., 0.) + vec2(0, t + i*.15), 3.))*.2 + (.95/COUNT)*i;
float mi = SS(edge, uv.y) - SS(edge + .095, uv.y);
m += mi;
if(mi > 0.){
col = vec3(1.0);
}
}
col = mix(COL_BLACK, col, m);
gl_FragColor = vec4(col,1.0);
// mainImage(gl_FragColor,gl_FragCoord);
}
loaded in Processing as:
PShader shader;
void setup(){
size(300,300,P2D);
noStroke();
shader = loadShader("shader-Wts3DB.frag");
shader.set("iResolution",(float)width, float(height));
}
void draw(){
background(0);
shader.set("iTime",frameCount * 0.05);
shader(shader);
rect(0,0,width,height);
}
https://www.shadertoy.com/view/MtsXzl
tweaked as shader-MtsXzl.frag
//https://www.shadertoy.com/view/MtsXzl
#define SHOW_GRID 1
const float c_scale = 0.5;
const float c_rate = 2.0;
#define FLT_MAX 3.402823466e+38
uniform vec3 iMouse;
uniform vec2 iResolution;
uniform float iTime;
//=======================================================================================
float CubicHermite (float A, float B, float C, float D, float t)
{
float t2 = t*t;
float t3 = t*t*t;
float a = -A/2.0 + (3.0*B)/2.0 - (3.0*C)/2.0 + D/2.0;
float b = A - (5.0*B)/2.0 + 2.0*C - D / 2.0;
float c = -A/2.0 + C/2.0;
float d = B;
return a*t3 + b*t2 + c*t + d;
}
//=======================================================================================
float hash(float n) {
return fract(sin(n) * 43758.5453123);
}
//=======================================================================================
float GetHeightAtTile(vec2 T)
{
float rate = hash(hash(T.x) * hash(T.y))*0.5+0.5;
return (sin(iTime*rate*c_rate) * 0.5 + 0.5) * c_scale;
}
//=======================================================================================
float HeightAtPos(vec2 P)
{
vec2 tile = floor(P);
P = fract(P);
float CP0X = CubicHermite(
GetHeightAtTile(tile + vec2(-1.0,-1.0)),
GetHeightAtTile(tile + vec2(-1.0, 0.0)),
GetHeightAtTile(tile + vec2(-1.0, 1.0)),
GetHeightAtTile(tile + vec2(-1.0, 2.0)),
P.y
);
float CP1X = CubicHermite(
GetHeightAtTile(tile + vec2( 0.0,-1.0)),
GetHeightAtTile(tile + vec2( 0.0, 0.0)),
GetHeightAtTile(tile + vec2( 0.0, 1.0)),
GetHeightAtTile(tile + vec2( 0.0, 2.0)),
P.y
);
float CP2X = CubicHermite(
GetHeightAtTile(tile + vec2( 1.0,-1.0)),
GetHeightAtTile(tile + vec2( 1.0, 0.0)),
GetHeightAtTile(tile + vec2( 1.0, 1.0)),
GetHeightAtTile(tile + vec2( 1.0, 2.0)),
P.y
);
float CP3X = CubicHermite(
GetHeightAtTile(tile + vec2( 2.0,-1.0)),
GetHeightAtTile(tile + vec2( 2.0, 0.0)),
GetHeightAtTile(tile + vec2( 2.0, 1.0)),
GetHeightAtTile(tile + vec2( 2.0, 2.0)),
P.y
);
return CubicHermite(CP0X, CP1X, CP2X, CP3X, P.x);
}
//=======================================================================================
vec3 NormalAtPos( vec2 p )
{
float eps = 0.01;
vec3 n = vec3( HeightAtPos(vec2(p.x-eps,p.y)) - HeightAtPos(vec2(p.x+eps,p.y)),
2.0*eps,
HeightAtPos(vec2(p.x,p.y-eps)) - HeightAtPos(vec2(p.x,p.y+eps)));
return normalize( n );
}
//=======================================================================================
float RayIntersectSphere (vec4 sphere, in vec3 rayPos, in vec3 rayDir)
{
//get the vector from the center of this circle to where the ray begins.
vec3 m = rayPos - sphere.xyz;
//get the dot product of the above vector and the ray's vector
float b = dot(m, rayDir);
float c = dot(m, m) - sphere.w * sphere.w;
//exit if r's origin outside s (c > 0) and r pointing away from s (b > 0)
if(c > 0.0 && b > 0.0)
return -1.0;
//calculate discriminant
float discr = b * b - c;
//a negative discriminant corresponds to ray missing sphere
if(discr < 0.0)
return -1.0;
//ray now found to intersect sphere, compute smallest t value of intersection
float collisionTime = -b - sqrt(discr);
//if t is negative, ray started inside sphere so clamp t to zero and remember that we hit from the inside
if(collisionTime < 0.0)
collisionTime = -b + sqrt(discr);
return collisionTime;
}
//=======================================================================================
vec3 DiffuseColor (in vec3 pos)
{
#if SHOW_GRID
pos = mod(floor(pos),2.0);
return vec3(mod(pos.x, 2.0) < 1.0 ? 1.0 : 0.0);
#else
return vec3(0.1, 0.8, 0.9);
#endif
}
//=======================================================================================
vec3 ShadePoint (in vec3 pos, in vec3 rayDir, float time, bool fromUnderneath)
{
vec3 diffuseColor = DiffuseColor(pos);
vec3 reverseLightDir = normalize(vec3(1.0,1.0,-1.0));
vec3 lightColor = vec3(1.0);
vec3 ambientColor = vec3(0.05);
vec3 normal = NormalAtPos(pos.xz);
normal *= fromUnderneath ? -1.0 : 1.0;
// diffuse
vec3 color = diffuseColor;
float dp = dot(normal, reverseLightDir);
if(dp > 0.0)
color += (diffuseColor * lightColor);
return color;
}
//=======================================================================================
vec3 HandleRay (in vec3 rayPos, in vec3 rayDir, in vec3 pixelColor, out float hitTime)
{
float time = 0.0;
float lastHeight = 0.0;
float lastY = 0.0;
float height;
bool hitFound = false;
hitTime = FLT_MAX;
bool fromUnderneath = false;
vec2 timeMinMax = vec2(0.0, 20.0);
time = timeMinMax.x;
const int c_numIters = 100;
float deltaT = (timeMinMax.y - timeMinMax.x) / float(c_numIters);
vec3 pos = rayPos + rayDir * time;
float firstSign = sign(pos.y - HeightAtPos(pos.xz));
for (int index = 0; index < c_numIters; ++index)
{
pos = rayPos + rayDir * time;
height = HeightAtPos(pos.xz);
if (sign(pos.y - height) * firstSign < 0.0)
{
fromUnderneath = firstSign < 0.0;
hitFound = true;
break;
}
time += deltaT;
lastHeight = height;
lastY = pos.y;
}
if (hitFound) {
time = time - deltaT + deltaT*(lastHeight-lastY)/(pos.y-lastY-height+lastHeight);
pos = rayPos + rayDir * time;
pixelColor = ShadePoint(pos, rayDir, time, fromUnderneath);
hitTime = time;
}
return pixelColor;
}
//=======================================================================================
void main()
{
// scrolling camera
vec3 cameraOffset = vec3(iTime, 0.5, iTime);
//----- camera
vec2 mouse = iMouse.xy / iResolution.xy;
vec3 cameraAt = vec3(0.5,0.5,0.5) + cameraOffset;
float angleX = iMouse.z > 0.0 ? 6.28 * mouse.x : 3.14 + iTime * 0.25;
float angleY = iMouse.z > 0.0 ? (mouse.y * 6.28) - 0.4 : 0.5;
vec3 cameraPos = (vec3(sin(angleX)*cos(angleY), sin(angleY), cos(angleX)*cos(angleY))) * 5.0;
// float angleX = 0.8;
// float angleY = 0.8;
// vec3 cameraPos = vec3(0.0,0.0,0.0);
cameraPos += vec3(0.5,0.5,0.5) + cameraOffset;
vec3 cameraFwd = normalize(cameraAt - cameraPos);
vec3 cameraLeft = normalize(cross(normalize(cameraAt - cameraPos), vec3(0.0,sign(cos(angleY)),0.0)));
vec3 cameraUp = normalize(cross(cameraLeft, cameraFwd));
float cameraViewWidth = 6.0;
float cameraViewHeight = cameraViewWidth * iResolution.y / iResolution.x;
float cameraDistance = 6.0; // intuitively backwards!
// Objects
vec2 rawPercent = (gl_FragCoord.xy / iResolution.xy);
vec2 percent = rawPercent - vec2(0.5,0.5);
vec3 rayTarget = (cameraFwd * vec3(cameraDistance,cameraDistance,cameraDistance))
- (cameraLeft * percent.x * cameraViewWidth)
+ (cameraUp * percent.y * cameraViewHeight);
vec3 rayDir = normalize(rayTarget);
float hitTime = FLT_MAX;
vec3 pixelColor = vec3(1.0, 1.0, 1.0);
pixelColor = HandleRay(cameraPos, rayDir, pixelColor, hitTime);
gl_FragColor = vec4(clamp(pixelColor,0.0,1.0), 1.0);
}
and the mouse interactive Processing sketch:
PShader shader;
void setup(){
size(300,300,P2D);
noStroke();
shader = loadShader("shader-MtsXzl.frag");
shader.set("iResolution",(float)width, float(height));
}
void draw(){
background(0);
shader.set("iTime",frameCount * 0.05);
shader.set("iMouse",(float)mouseX , (float)mouseY, mousePressed ? 1.0 : 0.0);
shader(shader);
rect(0,0,width,height);
}
Shadertoy is great way to play/learn: have fun !
Update
Here's a quick test tweaking Daniel Shiffman's 3D Terrain Generation example to add a stripped texture and basic sine waves instead of perlin noise:
// Daniel Shiffman
// http://codingtra.in
// http://patreon.com/codingtrain
// Code for: https://youtu.be/IKB1hWWedMk
int cols, rows;
int scl = 20;
int w = 2000;
int h = 1600;
float flying = 0;
float[][] terrain;
PImage texture;
void setup() {
size(600, 600, P3D);
textureMode(NORMAL);
noStroke();
cols = w / scl;
rows = h/ scl;
terrain = new float[cols][rows];
texture = getBarsTexture(512,512,96);
}
void draw() {
flying -= 0.1;
float yoff = flying;
for (int y = 0; y < rows; y++) {
float xoff = 0;
for (int x = 0; x < cols; x++) {
//terrain[x][y] = map(noise(xoff, yoff), 0, 1, -100, 100);
terrain[x][y] = map(sin(xoff) * sin(yoff), 0, 1, -60, 60);
xoff += 0.2;
}
yoff += 0.2;
}
background(0);
translate(width/2, height/2+50);
rotateX(PI/9);
translate(-w/2, -h/2);
for (int y = 0; y < rows-1; y++) {
beginShape(TRIANGLE_STRIP);
texture(texture);
for (int x = 0; x < cols; x++) {
float u0 = map(x,0,cols-1,0.0,1.0);
float u1 = map(x+1,0,cols-1,0.0,1.0);
float v0 = map(y,0,rows-1,0.0,1.0);
float v1 = map(y+1,0,rows-1,0.0,1.0);
vertex(x*scl, y*scl, terrain[x][y], u0, v0);
vertex(x*scl, (y+1)*scl, terrain[x][y+1], u1, v1);
}
endShape();
}
}
PGraphics getBarsTexture(int textureWidth, int textureHeight, int numBars){
PGraphics texture = createGraphics(textureWidth, textureHeight);
int moduleSide = textureWidth / numBars;
texture.beginDraw();
texture.background(0);
texture.noStroke();
for(int i = 0; i < numBars; i+= 2){
texture.rect(0, i * moduleSide, textureWidth, moduleSide);
}
texture.endDraw();
return texture;
}

Why is wrapping coordinates not making my simplex noise tile seamlessly?

I've been trying to create a fake 3D texture that repeats in shadertoy (see here, use wasd to move, arrow keys to rotate) But as you can see, it doesn't tile.
I generate the noise myself, and I've isolated the noise generation in this minimal example, however it does not generate seamlessly tileable noise seemingly no matter what I do.
Here is the code:
//Common, you probably won't have to look here.
vec2 modv(vec2 value, float modvalue){
return vec2(mod(value.x, modvalue),
mod(value.y, modvalue));
}
vec3 modv(vec3 value, float modvalue){
return vec3(mod(value.x, modvalue),
mod(value.y, modvalue),
mod(value.z, modvalue));
}
vec4 modv(vec4 value, float modvalue){
return vec4(mod(value.x, modvalue),
mod(value.y, modvalue),
mod(value.z, modvalue),
mod(value.w, modvalue));
}
//MATH CONSTANTS
const float pi = 3.1415926535897932384626433832795;
const float tau = 6.2831853071795864769252867665590;
const float eta = 1.5707963267948966192313216916397;
const float SQRT3 = 1.7320508075688772935274463415059;
const float SQRT2 = 1.4142135623730950488016887242096;
const float LTE1 = 0.9999999999999999999999999999999;
const float inf = uintBitsToFloat(0x7F800000u);
#define saturate(x) clamp(x,0.0,1.0)
#define norm01(x) ((x + 1.0) / 2.0)
vec2 pos3DTo2D(in vec3 pos,
const in int size_dim,
const in ivec2 z_size){
float size_dimf = float(size_dim);
pos = vec3(mod(pos.x, size_dimf), mod(pos.y, size_dimf), mod(pos.z, size_dimf));
int z_dim_x = int(pos.z) % z_size.x;
int z_dim_y = int(pos.z) / z_size.x;
float x = pos.x + float(z_dim_x * size_dim);
float y = pos.y + float(z_dim_y * size_dim);
return vec2(x,y);
}
vec4 textureAs3D(const in sampler2D iChannel,
in vec3 pos,
const in int size_dim,
const in ivec2 z_size,
const in vec3 iResolution){
//only need whole, will do another texture read to make sure interpolated?
vec2 tex_pos = pos3DTo2D(pos, size_dim, z_size)/iResolution.xy;
vec4 base_vec4 = texture(iChannel, tex_pos);
vec2 tex_pos_z1 = pos3DTo2D(pos+vec3(0.0,0.0,1.0), size_dim, z_size.xy)/iResolution.xy;
vec4 base_vec4_z1 = texture(iChannel, tex_pos_z1);
//return base_vec4;
return mix(base_vec4, base_vec4_z1, fract(pos.z));
}
vec4 textureZ3D(const in sampler2D iChannel,
in int y,
in int z,
in int offsetX,
const in int size_dim,
const in ivec2 z_size,
const in vec3 iResolution){
int tx = (z%z_size.x);
int ty = z/z_size.x;
int sx = offsetX + size_dim * tx;
int sy = y + (ty *size_dim);
if(ty < z_size.y){
return texelFetch(iChannel, ivec2(sx, sy),0);
}else{
return vec4(0.0);
}
//return texelFetch(iChannel, ivec2(x, y - (ty *32)),0);
}
//Buffer B this is what you are going to have to look at.
//noise
//NOISE CONSTANTS
// captured from https://en.wikipedia.org/wiki/SHA-2#Pseudocode
const uint CONST_A = 0xcc9e2d51u;
const uint CONST_B = 0x1b873593u;
const uint CONST_C = 0x85ebca6bu;
const uint CONST_D = 0xc2b2ae35u;
const uint CONST_E = 0xe6546b64u;
const uint CONST_F = 0x510e527fu;
const uint CONST_G = 0x923f82a4u;
const uint CONST_H = 0x14292967u;
const uint CONST_0 = 4294967291u;
const uint CONST_1 = 604807628u;
const uint CONST_2 = 2146583651u;
const uint CONST_3 = 1072842857u;
const uint CONST_4 = 1396182291u;
const uint CONST_5 = 2227730452u;
const uint CONST_6 = 3329325298u;
const uint CONST_7 = 3624381080u;
uvec3 singleHash(uvec3 uval){
uval ^= uval >> 16;
uval.x *= CONST_A;
uval.y *= CONST_B;
uval.z *= CONST_C;
return uval;
}
uint combineHash(uint seed, uvec3 uval){
// can move this out to compile time if need be.
// with out multiplying by one of the randomizing constants
// will result in not very different results from seed to seed.
uint un = seed * CONST_5;
un ^= (uval.x^uval.y)* CONST_0;
un ^= (un >> 16);
un = (un^uval.z)*CONST_1;
un ^= (un >> 16);
return un;
}
/*
//what the above hashes are based upon, seperate
//out this mumurhash based coherent noise hash
uint fullHash(uint seed, uvec3 uval){
uval ^= uval >> 16;
uval.x *= CONST_A;
uval.y *= CONST_B;
uval.z *= CONST_D;
uint un = seed * CONST_6;
un ^= (uval.x ^ uval.y) * CONST_0;
un ^= un >> 16;
un = (un^uval.z) * CONST_2;
un ^= un >> 16;
return un;
}
*/
const vec3 gradArray3d[8] = vec3[8](
vec3(1, 1, 1), vec3(1,-1, 1), vec3(-1, 1, 1), vec3(-1,-1, 1),
vec3(1, 1,-1), vec3(1,-1,-1), vec3(-1, 1,-1), vec3(-1,-1,-1)
);
vec3 getGradient3Old(uint uval){
vec3 grad = gradArray3d[uval & 7u];
return grad;
}
//source of some constants
//https://github.com/Auburns/FastNoise/blob/master/FastNoise.cpp
const float SKEW3D = 1.0 / 3.0;
const float UNSKEW3D = 1.0 / 6.0;
const float FAR_CORNER_UNSKEW3D = -1.0 + 3.0*UNSKEW3D;
const float NORMALIZE_SCALE3D = 30.0;// * SQRT3;
const float DISTCONST_3D = 0.6;
float simplexNoiseV(uint seed, in vec3 pos, in uint wrap){
pos = modv(pos, float(wrap));
float skew_factor = (pos.x + pos.y + pos.z)*SKEW3D;
vec3 fsimplex_corner0 = floor(pos + skew_factor);
ivec3 simplex_corner0 = ivec3(fsimplex_corner0);
float unskew_factor = (fsimplex_corner0.x + fsimplex_corner0.y + fsimplex_corner0.z) * UNSKEW3D;
vec3 pos0 = fsimplex_corner0 - unskew_factor;
//subpos's are positions with in grid cell.
vec3 subpos0 = pos - pos0;
//precomputed values used in determining hash, reduces redundant hash computation
//shows 10% -> 20% speed boost.
uvec3 wrapped_corner0 = uvec3(simplex_corner0);
uvec3 wrapped_corner1 = uvec3(simplex_corner0+1);
wrapped_corner0 = wrapped_corner0 % wrap;
wrapped_corner1 = wrapped_corner1 % wrap;
//uvec3 hashes_offset0 = singleHash(uvec3(simplex_corner0));
//uvec3 hashes_offset1 = singleHash(uvec3(simplex_corner0+1));
uvec3 hashes_offset0 = singleHash(wrapped_corner0);
uvec3 hashes_offset1 = singleHash(wrapped_corner1);
//near corner hash value
uint hashval0 = combineHash(seed, hashes_offset0);
//mid corner hash value
uint hashval1;
uint hashval2;
//far corner hash value
uint hashval3 = combineHash(seed, hashes_offset1);
ivec3 simplex_corner1;
ivec3 simplex_corner2;
if (subpos0.x >= subpos0.y)
{
if (subpos0.y >= subpos0.z)
{
hashval1 = combineHash(seed, uvec3(hashes_offset1.x, hashes_offset0.yz));
hashval2 = combineHash(seed, uvec3(hashes_offset1.xy, hashes_offset0.z));
simplex_corner1 = ivec3(1,0,0);
simplex_corner2 = ivec3(1,1,0);
}
else if (subpos0.x >= subpos0.z)
{
hashval1 = combineHash(seed, uvec3(hashes_offset1.x, hashes_offset0.yz));
hashval2 = combineHash(seed, uvec3(hashes_offset1.x, hashes_offset0.y, hashes_offset1.z));
simplex_corner1 = ivec3(1,0,0);
simplex_corner2 = ivec3(1,0,1);
}
else // subpos0.x < subpos0.z
{
hashval1 = combineHash(seed, uvec3(hashes_offset0.xy, hashes_offset1.z));
hashval2 = combineHash(seed, uvec3(hashes_offset1.x, hashes_offset0.y, hashes_offset1.z));
simplex_corner1 = ivec3(0,0,1);
simplex_corner2 = ivec3(1,0,1);
}
}
else // subpos0.x < subpos0.y
{
if (subpos0.y < subpos0.z)
{
hashval1 = combineHash(seed, uvec3(hashes_offset0.xy, hashes_offset1.z));
hashval2 = combineHash(seed, uvec3(hashes_offset0.x, hashes_offset1.yz));
simplex_corner1 = ivec3(0,0,1);
simplex_corner2 = ivec3(0,1,1);
}
else if (subpos0.x < subpos0.z)
{
hashval1 = combineHash(seed, uvec3(hashes_offset0.x, hashes_offset1.y, hashes_offset0.z));
hashval2 = combineHash(seed, uvec3(hashes_offset0.x, hashes_offset1.yz));
simplex_corner1 = ivec3(0,1,0);
simplex_corner2 = ivec3(0,1,1);
}
else // subpos0.x >= subpos0.z
{
hashval1 = combineHash(seed, uvec3(hashes_offset0.x, hashes_offset1.y, hashes_offset0.z));
hashval2 = combineHash(seed, uvec3(hashes_offset1.xy, hashes_offset0.z));
simplex_corner1 = ivec3(0,1,0);
simplex_corner2 = ivec3(1,1,0);
}
}
//we would do this if we didn't want to seperate the hash values.
//hashval0 = fullHash(seed, uvec3(simplex_corner0));
//hashval1 = fullHash(seed, uvec3(simplex_corner0+simplex_corner1));
//hashval2 = fullHash(seed, uvec3(simplex_corner0+simplex_corner2));
//hashval3 = fullHash(seed, uvec3(simplex_corner0+1));
vec3 subpos1 = subpos0 - vec3(simplex_corner1) + UNSKEW3D;
vec3 subpos2 = subpos0 - vec3(simplex_corner2) + 2.0*UNSKEW3D;
vec3 subpos3 = subpos0 + FAR_CORNER_UNSKEW3D;
float n0, n1, n2, n3;
//http://catlikecoding.com/unity/tutorials/simplex-noise/
//circle distance factor to make sure second derivative is continuous
// t variables represent (1 - x^2 + y^2 + ...)^3, a distance function with
// continous first and second derivatives that are zero when x is one.
float t0 = DISTCONST_3D - subpos0.x*subpos0.x - subpos0.y*subpos0.y - subpos0.z*subpos0.z;
//if t < 0, we get odd dips in continuity at the ends, so we just force it to zero
// to prevent it
if(t0 < 0.0){
n0 = 0.0;
}else{
float t0_pow2 = t0 * t0;
float t0_pow4 = t0_pow2 * t0_pow2;
vec3 grad = getGradient3Old(hashval0);
float product = dot(subpos0, grad);
n0 = t0_pow4 * product;
}
float t1 = DISTCONST_3D - subpos1.x*subpos1.x - subpos1.y*subpos1.y - subpos1.z*subpos1.z;
if(t1 < 0.0){
n1 = 0.0;
}else{
float t1_pow2 = t1 * t1;
float t1_pow4 = t1_pow2 * t1_pow2;
vec3 grad = getGradient3Old(hashval1);
float product = dot(subpos1, grad);
n1 = t1_pow4 * product;
}
float t2 = DISTCONST_3D - subpos2.x*subpos2.x - subpos2.y*subpos2.y - subpos2.z*subpos2.z;
if(t2 < 0.0){
n2 = 0.0;
}else{
float t2_pow2 = t2 * t2;
float t2_pow4 = t2_pow2*t2_pow2;
vec3 grad = getGradient3Old(hashval2);
float product = dot(subpos2, grad);
n2 = t2_pow4 * product;
}
float t3 = DISTCONST_3D - subpos3.x*subpos3.x - subpos3.y*subpos3.y - subpos3.z*subpos3.z;
if(t3 < 0.0){
n3 = 0.0;
}else{
float t3_pow2 = t3 * t3;
float t3_pow4 = t3_pow2*t3_pow2;
vec3 grad = getGradient3Old(hashval3);
float product = dot(subpos3, grad);
n3 = t3_pow4 * product;
}
return (n0 + n1 + n2 + n3);
}
//settings for fractal brownian motion noise
struct BrownianFractalSettings{
uint seed;
int octave_count;
float frequency;
float lacunarity;
float persistence;
float amplitude;
};
float accumulateSimplexNoiseV(in BrownianFractalSettings settings, vec3 pos, float wrap){
float accumulated_noise = 0.0;
wrap *= settings.frequency;
vec3 octave_pos = pos * settings.frequency;
for (int octave = 0; octave < settings.octave_count; octave++) {
octave_pos = modv(octave_pos, wrap);
float noise = simplexNoiseV(settings.seed, octave_pos, uint(wrap));
noise *= pow(settings.persistence, float(octave));
accumulated_noise += noise;
octave_pos *= settings.lacunarity;
wrap *= settings.lacunarity;
}
float scale = 2.0 - pow(settings.persistence, float(settings.octave_count - 1));
return (accumulated_noise/scale) * NORMALIZE_SCALE3D * settings.amplitude;
}
const float FREQUENCY = 1.0/8.0;
const float WRAP = 32.0;
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
//set to zero in order to stop scrolling, scrolling shows the lack of tilability between
//wrapping.
const float use_sin_debug = 1.0;
vec3 origin = vec3(norm01(sin(iTime))*64.0*use_sin_debug,0.0,0.0);
vec3 color = vec3(0.0,0.0,0.0);
BrownianFractalSettings brn_settings =
BrownianFractalSettings(203u, 1, FREQUENCY, 2.0, 0.4, 1.0);
const int size_dim = 32;
ivec2 z_size = ivec2(8, 4);
ivec2 iFragCoord = ivec2(fragCoord.x, fragCoord.y);
int z_dim_x = iFragCoord.x / size_dim;
int z_dim_y = iFragCoord.y / size_dim;
if(z_dim_x < z_size.x && z_dim_y < z_size.y){
int ix = iFragCoord.x % size_dim;
int iy = iFragCoord.y % size_dim;
int iz = (z_dim_x) + ((z_dim_y)*z_size.x);
vec3 pos = vec3(ix,iy,iz) + origin;
float value = accumulateSimplexNoiseV(brn_settings, pos, WRAP);
color = vec3(norm01(value));
}else{
color = vec3(1.0,0.0,0.0);
}
fragColor = vec4(color,1.0);
}
//Image, used to finally display
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
const float fcm = 4.0;
//grabs a single 32x32 tile in order to test tileability, currently generates
//a whole array of images however.
vec2 fragCoordMod = vec2(mod(fragCoord.x, 32.0 * fcm), mod(fragCoord.y, 32.0 * fcm));
vec3 color = texture(iChannel2, fragCoordMod/(fcm*iResolution.xy)).xyz;
fragColor = vec4(color, 1.0);
}
What I've tried position % wrap value, modifying wrap value by lacunarity, and after warp % wrap value, which are currently in use (look in simplexNoiseV for the core algorithm, accumulateSimplexNoiseV for the octave summation).
According to these answers it should be that simple (mod position used for hashing), however this clearly just doesn't work. I'm not sure if it's partially because my hashing function is not Ken Perlin's, but it doesn't seem like that should make a difference. It does seem the skewing of coordinates should make this method not work at all, but apparently others have had success with this.
Here's an example of it not tiling:
Why is wrapping coordinates not making my simplex noise tile seamlessly?
UPDATE:
I've still not fixed the issue, but it appears that tiling works appropriately along the simplicies, and not the grid seen here:
Do I have to modify my modulus to account for the skewing?

Porting ShaderToy to THREE.JS issue

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 );
} );

unexpected token after conditional expression

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.

Resources