Creating a quad texture with shaders

Hello, I need to create a quad texture of around 99pixels which I want to color each pixel in the fragment shader.

The code:

var geometry = new THREE.BufferGeometry();
var colors = new Float32Array(99 * 4);
for (j = 0; j < 1; j++) {
for (i = 1; i < 100; i++) {
const id = (i-1) * 4;
colors[id + 0] = tStudent;
colors[id + 1] = tStudent * tStudent * x;
colors[id + 2] = tStudent * tStudent * y;
colors[id + 3] = 1;
}
}
console.log(colors);
geometry.addAttribute( ‘color’, new THREE.BufferAttribute( colors, 4 ) );
uniforms = {
time: { type: “f”, value: 1.0 }
};
material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( ‘vertexShader’ ).textContent,
fragmentShader: document.getElementById( ‘fragmentShader’ ).textContent
});
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );

The shaders are as follows:

<script id="vertexShader" type="x-shader/x-vertex">
	uniform float time;
	attribute vec4 color;
	varying vec4 vColor;
	void main()	{
		vColor = color;
		gl_Position = vec4( position, 1.0 );
	}
</script>

<script id="fragmentShader" type="x-shader/x-fragment">
	uniform float time;
	varying vec4 vColor;
	void main()	{
		vec4 color = vec4( vColor );
		gl_FragColor = vec4(0,255,0,1);
	}

I got a black screen without any output. Any help please?

Hard to tell why you’re getting a black screen without more details. Where’s your render loop? Do you get any console errors? Are you getting shader compilation errors? I can tell you off the bat, your line gl_FragColor = vec4(0,255,0,1); won’t work, because you need to use floats, not integers. Try using gl_FragColor = vec4(0.0, 255.0, 0.0, 1.0); instead.

Just tried it on shadertoy.com and glslsandbox.com, works as expected.

@Wedad_Anbtawi
Could you provide a working live code example? codepen, jsfiddle or github repo?

2 Likes

Oh, wow you’re right! My shaders have always given me the error:

cannot convert from 'const int' to 'highp float'

when I assign an integer to a float variable. But it looks like gl_FragColor can also handle integers in the [0, 255] range… Guess I learned something new today!

2 Likes

The examples are advanced like https://threejs.org/examples/#webgl_buffergeometry_rawshader
I only need a plane of 99 pixels each will be assigned color from the attribute value. I think the position is wrong but not sure.

Where is your position attribute?

I don’t think that gl_Position = vec4(position,1.); is doing anything since you don’t have anything in position.
Apply your ShaderMaterial to

new PlaneBufferGeometry(2,2,1,1)

Double yu tee F on the int in gl_FragColor i learned something today! But how is alpha treated, is 1 basically 1/255?

1 Like

Thank you! it worked! do you have any idea on how to set the number of pixels on the geometry? Like if I need only 100*100 pixels

You don’t do it like that. On the geometry you could perhaps arrange a grid of points and then render it as THREE.Points but i think it would be tricky.

What would be better i think, is to make an attribute on the geometry that looks up the texture.
One of these:

attribute float aIndex;
attribute vec2 aIndex;

I didn’t get you.

What I need is to have two textures, each with 100*100 pixels whose color will be passed as attribute, then apply blender to both textures to get the mixed color per pixel. I also should get the color of each pixel. I’m new to Three.js so I’m not sure if this is applicable.

I don’t understand what you are trying to do:

1 Like