Texture not showing when updating Three.js version - javascript

I followed this post hoping to add my own spin on things. I noticed the example located
here is using a very old revision of Three.JS (49). When I changed the source file to a more up-to-date version, the texture no longer appears. See Demo
I've been spending a lot of time trying to figure out what depreciations occurred and I've narrowed down my search to these lines.
// material
uniforms = {
sunDirection: { type: "v3", value: new THREE.Vector3(0,1,0) },
dayTexture: { type: "t", value: 0, texture: THREE.ImageUtils.loadTexture( "/images/world2.png" ) },
nightTexture: { type: "t", value: 1, texture: THREE.ImageUtils.loadTexture( "/images/world5.png" ) }
};
uniforms.dayTexture.texture.wrapS = uniforms.dayTexture.texture.wrapT = THREE.Repeat;
uniforms.nightTexture.texture.wrapS = uniforms.nightTexture.texture.wrapT = THREE.Repeat;
material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
} );
More misc stuff that probably has something to do with my problem
<script id="fragmentShader" type="x-shader/x-fragment">
uniform sampler2D dayTexture;
uniform sampler2D nightTexture;
uniform vec3 sunDirection;
varying vec2 vUv;
varying vec3 vNormal;
void main( void ) {
vec3 dayColor = texture2D( dayTexture, vUv ).rgb;
vec3 nightColor = texture2D( nightTexture, vUv ).rgb;
// compute cosine sun to normal so -1 is away from sun and +1 is toward sun.
float cosineAngleSunToNormal = dot(normalize(vNormal), sunDirection);
// sharpen the edge beween the transition
cosineAngleSunToNormal = clamp( cosineAngleSunToNormal * 10.0, -1.0, 1.0);
// convert to 0 to 1 for mixing
float mixAmount = cosineAngleSunToNormal * 0.5 + 0.5;
// Select day or night texture based on mix.
vec3 color = mix( nightColor, dayColor, mixAmount );
gl_FragColor = vec4( color, 1.0 );
//gl_FragColor = vec4( mixAmount, mixAmount, mixAmount, 1.0 );
}
</script>
<script id="vertexShader" type="x-shader/x-vertex">
varying vec2 vUv;
varying vec3 vNormal;
void main()
{
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
vNormal = normalMatrix * normal;
gl_Position = projectionMatrix * mvPosition;
}
</script>
I've checked the migrations docx here
There isn't much on "uniforms" or "shaders" for that fact.

In the Migration Wiki you referenced, it specifies a new pattern for assigning textures to uniforms as of r.51:
{ type: "t", value: 0, texture: map } => { type: "t", value: map }
So in you case, it would be
dayTexture: { type: "t", value: THREE.ImageUtils.loadTexture( "/images/world2.png" ) },
nightTexture: { type: "t", value: THREE.ImageUtils.loadTexture( "/images/world5.png" ) }
three.js r.59

Related

Three.js fragment shader: texture renders completely transparent

Here is my fragment shader code
uniform sampler2D texture;
precision mediump float;
varying vec2 vUv;
void main()
{
gl_FragColor = texture2D(texture, vUv);
// gl_FragColor = texture2D(texture, vUv.xy); // also tried this
}
Here is code for uniforms:
uniforms = {
"uTime": { type: "f", value: 0.0 },
texture: { value: new THREE.TextureLoader().load("lol.png") },
}
Here is texture I load:
And as result - it's completely transparent. If I render any other stuff (color, circle etc.) it works.

Texture not rotating with the object

I have a very simple object and a texture drown to it (using shader). Everything works great, except when rotating the object, the texture is not rotating along it, but appears to stay in the 2D space, creating the 'mask' effect below:
Texture not rotating along the object
When I use a regular material and attach texture to it, all works fine, so I'm guessing I'm doing something wrong at the vertex shader.
I load the model the following way:
var loader = new THREE.JSONLoader();
loader.load( "models/cube.json", addModelToScene );
var texture = THREE.ImageUtils.loadTexture( "images/woods.jpg" );
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 1.0, 1.0 );
uniforms =
{
time:
{
type: "f",
value: 1.0
},
texture1: { type: "t", value: THREE.ImageUtils.loadTexture( "images/woods.jpg" ) }
};
function addModelToScene( geometry, materials ) {
var material = new THREE.MeshFaceMaterial( materials );
var shaderMaterial = new THREE.ShaderMaterial
(
{
vertexShader: $('#vertexshader').text(),
fragmentShader: $('#fragmentshader').text(),
uniforms: uniforms
}
);
model = new THREE.Mesh( geometry, shaderMaterial );
model.scale.set( 2.5, 2.5, 2.5 );
scene.add( model );
}
Vertex shader:
varying vec2 vUv;
#ifdef GL_ES
precision highp float;
#endif
uniform float time;
uniform sampler2D texture1;
void main()
{
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
Fragment shader:
varying vec2 vUv;
#ifdef GL_ES
precision highp float;
#endif
uniform sampler2D texture1;
uniform float time;
void main()
{
vec2 u_resolution = vec2( 1700, 1000 );
vec2 uv = gl_FragCoord.xy / u_resolution.xy;
gl_FragColor = texture2D( texture1, uv );
}
And finally I rotate the object the following way:
model.rotation.z += 0.00013;
model.rotation.z += 0.004;
Why is the texture not one with the object, but instead stays in static position? Thanks!
That's because you should use vUv varying to address the texture, not gl_FragCoord.xy:
gl_FragColor = texture2D(texture1, vUv);
gl_FragColor.xy is just pixel's (or, to be more accurate, fragment's) coordinates on a screen (i.e., window coordinates). They don't depend on rotation (or any transformations for that matter) of your object (or the object itself). They only depend upon where the pixel currently being shaded lies on the screen.

How to pass a dynamic variable into a JavaScript Shader

I have created a primitive sphere using THREE.SphereGeometry. I am applying a displacement shader, to give it a bumpy effect. I am trying to animate the scale of the bumps with volume from the microphone. I am unable to pass my volume variable into the shader to affect the scale. I am logging the volume variable and I see that it is appropriately updating from my microphone.
The dynamic variable is:
var volume = meter.volume * 1000.0;
function drawLoop(time) {
rafID = window.requestAnimationFrame(drawLoop);
var volume = meter.volume * 1000.0;
//var volume = THREE.UniformsUtils.clone(meter.volume);
javascript: console.log(typeof(volume));
THREE.DisplacementShader = {
uniforms: {
texture1: {
type: "t",
value: null
},
scale: {
type: "f",
value: 100 + volume
},
volume: {
type: "f",
value: meter.volume
},
},
vertexShader: [
"varying vec2 vUv;",
"varying float noise;",
"varying vec3 fNormal;",
"uniform sampler2D texture1;",
"uniform float scale;",
"uniform float time;",
"varying float volume;",
"void main() {",
"vUv = uv;",
"fNormal = normal;",
"vec4 noiseTex = texture2D( texture1, vUv );",
"noise = noiseTex.r + time;",
//adding the normal scales it outward
//(normal scale equals sphere diameter)
"vec3 newPosition = position + normal * noise * scale * (volume*100.0);",
"gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );",
"}"
].join("\n"),
fragmentShader: [
"varying vec2 vUv;",
"varying float noise;",
"varying vec3 fNormal;",
"void main( void ) {",
// compose the colour using the normals then
// whatever is heightened by the noise is lighter
"gl_FragColor = vec4( fNormal * noise, 1. );",
"}"
].join("\n")
};
}
You defined
varying float volume;
in your vertex-shader. It should instead read
uniform float volume;

Three js Shader Material - Pixelated glitching when transparency is set to true

I'm playing around with shaders for the first time and using THREE.RawShaderMaterial on a few meshes.
I'm getting some strange artifacts on my very simple shaders:
Vertex shader:
precision mediump float;
precision mediump int;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
attribute vec3 position;
attribute vec4 color;
varying vec3 vPosition;
void main() {
vPosition = position;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
Fragment shader:
precision mediump float;
precision mediump int;
varying vec3 vPosition;
void main() {
gl_FragColor.r = vPosition.x;
gl_FragColor.g = vPosition.y;
gl_FragColor.b = 1.0;
}
which I use on a whole bunch of objects which are created like so:
asdfobject = new THREE.Object3D();
scene.add(asdfobject);
var geometry = new THREE.SphereGeometry(1, 4, 4);
var material = new THREE.RawShaderMaterial({
uniforms: {
time: { type: "f", value: 1.0 }
},
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
side: THREE.DoubleSide,
transparent: true,
} );
for(var i = 0; i < 80; i++) {
var mesh = new THREE.Mesh(geometry, material);
mesh.position.set(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5);
mesh.position.multiplyScalar(400);
mesh.rotation.set(Math.random() * 2, Math.random() * 2, Math.random() * 2);
mesh.scale.x = mesh.scale.y = mesh.scale.z = Math.random() * 50;
asdfobject.add(mesh);
}
The colour on the objects should be completely smooth, but sometimes they look a bit "glitchy" and pixelated like shown in this fiddle:
https://jsfiddle.net/weqqv5z5/
This happens especially when resizing the window.
I cannot figure out why this happens, I just know that the effect does not happen when transparent in the material is set to false (on line 23 in the fiddle)
I haven't been able to test this on any other devices yet, so it may be a graphics card specific problem, too. I am running a 64-bit Arch Linux laptop with Intel HD 4000 graphics.
Thanks in advance for any help!
You need to set the alpha value of your fragment color.
gl_FragColor.a = 0.5;
fiddle: https://jsfiddle.net/weqqv5z5/1/
three.js r.71

Three.js glow shader front face not rendering in chrome, works in other browsers

I am running into an issue where I am trying to apply a custom shader material to a series of nested objects to simulate a glow effect around each node. The effect works well on my home laptop (windows 8.1 latest chrome), but my work computer does not render the frontface of the glowing object, only the backface. I have checked it against a few systems and it seems to be mostly a chrome rendering issue on windows devices.
http://i.imgur.com/uYLtoxm.gif
I have included a codepen example where I shifted the glow off to the side and you can see that in some versions it is not rendering the front group of normals. The red dots should have a glow applied to each of them that shows up on the front and back(left and right in example). Any help would be appreciated, I am stumped as to what is going on.
Here is the shader material settings
local.glowNodeMat = new THREE.ShaderMaterial(
{
uniforms:
{
"c": { type: "f", value: 0 },
"p": { type: "f", value: 5.5 },
glowColor: { type: "c", value: new THREE.Color(0xaaccff) },
viewVector: { type: "v3", value: local.camera.position }
},
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
side: THREE.FrontSide,
blending: THREE.AdditiveBlending,
transparent: true
});
http://codepen.io/sniejadlik/pen/oDarE
///////////////////
FIXED thanks to Volune. Thanks for the help!
Fixed Vertex shader
<script id="vertexShader" type="x-shader/x-vertex">
uniform vec3 viewVector;
uniform float c;
uniform float p;
varying float intensity;
void main()
{
vec3 vNormal = normalize( normalMatrix * normal );
vec3 vNormel = normalize( normalMatrix * viewVector );
// incorrect intensity = pow( c - dot(vNormal, vNormel), p );
intensity = pow( abs(c - dot(vNormal, vNormel) ), p );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<!-- fragment shader a.k.a. pixel shader -->
<script id="fragmentShader" type="x-shader/x-vertex">
uniform vec3 glowColor;
varying float intensity;
void main()
{
vec3 glow = glowColor * intensity;
gl_FragColor = vec4( glow, 1.0 );
}
</script>
The error is in your vertex shader:
intensity = pow( c - dot(vNormal, vNormel), p );
You have c = 0 and p = 0.5. c - dot(vNormal, vNormel) may be negative (when the dot product returns a positive value), so you're trying to get the square of a negative value.
For some unknown reason, the fallback in Firefox looks like pow( abs(...), 0.5 ), while the fallback in Chrome seems to be 0.0.
Try to fix your shader like this:
intensity = pow( abs( c - dot(vNormal, vNormel) ), p );

Categories

Resources