Thank you @titansoftime for the above. But I m still facing an issue with this… basically in understanding the shader logic.
After making the changes, I see the below error in the console
WebGL: INVALID_OPERATION: useProgram: program not valid
useProgram @ three.min.js:112
k @ three.min.js:172
renderBufferDirect @ three.min.js:196
q @ three.min.js:165
m @ three.min.js:165
render @ three.min.js:203
render @ defaults.js:143
init @ defaults.js:130
(anonymous) @ v2Common.js:10
three.min.js:112
My lack of knowledge in GLSL is taking a toll on me. Below are the Vertex and fragment shader codes I implemented.
Vertex Shader:
precision highp float;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
attribute vec3 position;
attribute vec3 offset;
attribute vec2 uv;
attribute vec4 orientation;
varying vec2 vUv;
attribute vec3 instancePosition;
attribute vec4 instanceQuaternion;
attribute vec3 instanceScale;
vec3 applyTRS( vec3 position, vec3 translation, vec4 quaternion, vec3 scale ) {
position *= scale;
position += 2.0 * cross( quaternion.xyz, cross( quaternion.xyz, position ) + quaternion.w * position );
return position + translation;
}
vec3 applyQuaternionToVector( vec4 q, vec3 v ){
return v + 2.0 * cross( q.xyz, cross( q.xyz, v ) + q.w * v );
}
void main() {
// vec3 vPosition = applyQuaternionToVector( orientation, position );
// vUv = uv;
// gl_Position = projectionMatrix * modelViewMatrix * vec4( offset + vPosition, 1.0 );
transformed = applyTRS( transformed.xyz, instancePosition, instanceQuaternion, instanceScale );
gl_Position = projectionMatrix * modelViewMatrix * vec4( transformed, 1.0 );
}
Fragment Shader
precision highp float;
uniform sampler2D map;
varying vec2 vUv;
void main() {
gl_FragColor = texture2D( map, vUv );
}
And my JS:
var material = new THREE.RawShaderMaterial( {
uniforms: {
map: { value: wallTexture }
},
side: THREE.DoubleSide,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
} );
var bufferGeometry = new THREE.PlaneBufferGeometry( 500 , 500, 50, 50 );
var data = [
{
position: new THREE.Vector3(-125,100,-375),
rotationInRadians : 0,
scale: new THREE.Vector3(1,1,1)
},
{
position: new THREE.Vector3(125,100,-125),
rotationInRadians : -Math.PI/2,
scale: new THREE.Vector3(1,1,1)
},
{
position: new THREE.Vector3(-375,100,-125),
rotationInRadians : Math.PI/2,
scale: new THREE.Vector3(1,1,1)
},
{
position: new THREE.Vector3(-125,100,125),
rotationInRadians : Math.PI,
scale: new THREE.Vector3(1,1,1)
},
]
createInstance(bufferGeometry,data);
function createInstance(geo,data) {
var quaternion = new THREE.Quaternion();
var upVector = new THREE.Vector3(0,1,0);
var instancePositions = [];
var instanceQuaternions = [];
var instanceScales = [];
for( var i=0, len=data.length; i<len; i++ ){
quaternion.setFromAxisAngle( upVector, data[i].rotationInRadians );
quaternion.normalize(); // no sure if this is actually needed, but I use it just in case
instancePositions.push( data[i].position.x, data[i].position.y, data[i].position.z );
instanceQuaternions.push( quaternion.x, quaternion.y, quaternion.z, quaternion.w );
instanceScales.push( data[i].scale.x, data[i].scale.y, data[i].scale.z );
}
var instancedGeometry = new THREE.InstancedBufferGeometry();
// copy over data from original geometry
instancedGeometry.attributes.position = geo.attributes.position;
instancedGeometry.attributes.uv = geo.attributes.uv;
instancedGeometry.attributes.normal = geo.attributes.normal;
instancedGeometry.index = geo.index;
instancedGeometry.groups = geo.groups;
// set instance position/rotation/scale buffer attributes
instancedGeometry.addAttribute( 'instancePosition', new THREE.InstancedBufferAttribute( new Float32Array( instancePositions ), 3 ) );
instancedGeometry.addAttribute( 'instanceQuaternion', new THREE.InstancedBufferAttribute( new Float32Array( instanceQuaternions ), 4 ) );
instancedGeometry.addAttribute( 'instanceScale', new THREE.InstancedBufferAttribute( new Float32Array( instanceScales ), 3 ) );
var mesh = new THREE.Mesh(instancedGeometry,material);
scene.add(mesh);
}
I am really not sure where I am making the mistake. Really appreciate the time you are taking to help with this.
Regards,