I get an error:
THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry
THREE.ShaderMaterial: 'attributes' is not a property of this material.
and i'm trying to figure out what is going on.
I used to make a buffer geometry with some attributes. I never really figured out why this was needed, but i did notice i need to "type" it of sorts, to get three to hook it up with the shader.
{
attributes: {
aSomeAttribute:{
type: 'v3',
value:null
}
}
}
i'm trying to figure out what material.prototype.setValues( parameter ) does. From what i see it takes the parameters passed to the material ({vertexShader:...,uniforms:...}) and goes bonkers when it encounters attributes.
You can now apply custom attributes only on geometries inheriting from THREE.BufferGeometry for example if it's a sphere use THREE.SphereBufferGeometry instead of THREE.SphereGeometry. Then create your array of attributes and add it to the geometry thanks to THREE.BufferGeometry. After that you will be able to use your attribute in your shader. You can find an example here.
Related
I am trying to implement new custom features to the MeshStandardMaterial, in particular I would like to add the possibility to add two normal map that use different UV sets. Then I will combine them inside the fragment shader.
So far I have "doubled" meshstandardmaterial and make WebGLProgram insert keyword like "Use NormalMap2". The next step would be to mess around with actual glsl code.
Is there some way to print fragment shader or some how look what has been passed to it?
The easiest way to debug my code was to use webGL inspector, it shows me what texture has been passed to the shader and also it shows me all shader code
I am developing an augmented reality project using Three.js and aruco-js. I made my code so that all my 3D Objects are added to the scene (empty) at the beginning but the data gets initially loaded on marker detection.
Now I want to create an interface for changing the objects appearance, starting with the possibility of scaling an object.
So I created an updateObject() function to set the new values like this:
function updateObject(object, rotation, translation)
{
...
...
...
// first method
object.scale.x = 200;
object.scale.y = 200;
object.scale.z = 200;
// second attempt
object.scale.set(300, 300, 300);
};
I tried both of the methods shown above to set the scale of my object but it has no effect to the rendered images I get. The interesting thing is that the values of the objects in my scene3d DOM object are the values I set in my function. But why doesn't it have any impact on the output?
I'm not very familiar with 3d programming in WebGL or Three.js, so if you could give me any hint where the problem might has it's origin I would really appreciate an answer.
FIX:
I took a closer look to the 3D objects I was loading and discovered that they have a children called "mesh" inside another children. By trying to change the scale of only the mesh I found out that it works this way. But I think it looks very ugly:
scene3d.children[visibleModels[0][0]+3].children[0].children[0].scale.set(2, 2, 2);
//visibleModels is a list of the markers/models that should be loaded
This is only a test for one single object to change but at least I found a way to solve this. Is this an ordinary way to change the scale of objects? If you have a better solution or anything to add feel free to contribute.
You could also try to scale the object by changing its matrix using the THREE.Matrix4.makeScale method instead:
object.matrix.makeScale( xScale, yScale, zScale );
Or the even simpler THREE.Matrix4.scale method:
object.matrix.scale( scale );
I'm working with the three.js editor where I parse an object from JSON format. As usual it first parses the materials and geometries, then I create meshes from it. While parsing materials I also load textures. The issue now is that I have to call...
object.geometry.uvsNeedUpdate = true;
object.geometry.buffersNeedUpdate = true;
... after the image for the texture completely loaded - but why?! The geometry never changed before, neither did its uvs or anything like it. It's still the plain old geometry, yet I always get a GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 2 when trying to render. It only works with this "hack" although the geometry is always the same.
In my opinion it should also work perfectly when I update the uvs after object creation (or not at all). I didn't find anything in the three.js editor code that would update the geometry or its faceVertexUvs.
I know it's a bit of an abstract problem, I'm mainly looking for some hints or insights why this hack might be necessary.
Thanks!
Three.js "guesses" whether uvs are needed according to your used textures in bufferGuessUVType. If you want to preallocate uv buffers you can either init a map attribute with an empty THREE.Texture, update the geometry after the map was assigned, etc.
I was reading on ThreeJS custom attributes and got confused about how to set them up.
So i've seen that we add an attribute to the geometry attribute list and then the same to the ShaderMaterial attributes list ?
My question is how to add custom attributes in 3js ?
The new version (r67) features RawShaderMaterial which allows full control of attributes/shaders. Here's an example:
http://threejs.org/examples/webgl_buffergeometry_rawshader.html
If you want something less "raw" but still performant, here's an example using BufferGeometry and ShaderMaterial:
http://threejs.org/examples/webgl_buffergeometry_custom_attributes_particles.html
And, if you want to use Geometry here's an example of that too:
http://threejs.org/examples/webgl_custom_attributes.html
I would like to extend the default lambert material shader of three.js.
I basically would like to add some custom code at the end of the default fragment shader so the last line will apply my color transformations.
It's there any simple way to do that? Or should I rewrite a completely new one adding the default code on it?
I've created a custom ShaderMaterial using the predefined blocks from the default materials.