Этот вопрос довольно широк.
Допустим, вы делаете что-то вроде этого:
var myRenderer = new THREE.WebGLRenderer();
var myScene = new THREE.Scene();
var myTexture = new THREE.Texture();
var myColor = new THREE.Color();
var myMaterial = new THREE.MeshBasicMaterial({color:myColor, map:myTexture});
var myColoredAndTexturedCube = new THREE.Mesh(new THREE.CubeGeometry(), myMaterial);
var myCamera = new THREE.Camera();
если вы телеграфировать все это, вы получите куб текста на экране компьютера, и если вы поставляете цвет и текстуру, он будет отображаться как (текстуры тонированное цветом).
Многое происходит под капотом. Three.js выдает инструкции для gpu через API WebGL. Это очень низкие вызовы, такие как «взять этот кусок памяти и подготовить его для рисования», «подготовить этот шейдер для обработки этого блока памяти», чтобы установить режим смешивания для этого вызова ».
Я не понимаю, делает gl_FragColor устанавливает цвет для всего объекта или его рисуется в какой-то порядок, где я мог манипулировать cordinates в затенении, так что он получает цветные randomply, например?
Если да, то как он узнает, какую форму и порядок окраски?
Вы должны немного прочитать о конвейере рендеринга, возможно, вы сначала не поймете все это, но это может определенно прояснить некоторые вещи.
gl_FragColor устанавливает цвет для пикселя в буфере (может быть ваш экран, может быть внеэкранной текстурой). Да, он устанавливает цвет для «всего объекта», но весь этот объект может быть облаком частиц (который можно интерпретировать как количество объектов). У вас может быть сетка из 10x10 кубов, каждая из которых по-разному окрашена, но все же визуализируется одним призывом рисования (один объект).
Так возвращаясь к вашему shder:
//you dont see this, but three injects this for you, try intentionally adding a mistake to your shader, when your debugger complains, youll see the entire shader and these lines in it
uniform mat4 projectionMatrix; //one mat4 shared across all vertices/pixels
uniform mat4 modelViewMatrix; //one mat4 shared across all vertices/pixels
attribute vec3 position; //actual vertex, this value is different in each vertex
//try adding this
varying vec2 vUv;
void main()
{
vUv = uv; //uv, just like position, is another attribute that gets created for you automatically, this way we are sending it to the pixel shader through the varying vec2 vUv.
//this is the transformation
//projection matrix is what transforms space into perspective (vanishing points, things get smaller as they get further away from the camera)
//modelViewMatrix are actually two matrices, viewMatrix, which is also part of the camera (how is this camera rotated and moved compared to the rest of the world)
//finally the modelMatrix - how big is the object, where it stands, and how it's rotated
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position , 1.0); //will do the same thing
}
Каждый материал вы делаете с тремя, имеет эту часть шейдера. Этого недостаточно для освещения, например, потому что у него нет нормалей.
Попробуйте этот фрагмент шейдера:
varying vec2 vUv; //coming in from the vertex shader
void main(){
gl_FragColor = vec4(vUv , 0.0 , 1.0);
}
Или еще лучше, давайте покажем мировое положение объекта в цвете:
вершинные шейдеры:
varying vec3 vertexWorldPosition;
void main(){
vec4 worldPosition = modelMatrix * vec4(position , 1.0); //compute the world position, remember it,
//model matrix is mat4 that transforms the object from object space to world space, vec4(vec3 , 1.0) creates a point rather than a direction in "homogeneous coordinates"
//since we only need this to be vec4 for transformations and working with mat4, we save the vec3 portion of it to the varying variable
vertexWorldPosition = worldPosition.xyz; // we don't need .w
//do the rest of the transformation - what is this world space seen from the camera's point of view,
gl_Position = viewMatrix * worldPosition;
//we used gl_Position to write the previous result, we could have used a new vec4 cameraSpace (or eyeSpace, or viewSpace) but we can also write to gl_Position
gl_Position = projectionMatrix * gl_Position; //apply perspective distortion
}
пиксельный шейдер:
varying vec3 vertexWorldPosition; //this comes in from the vertex shader
void main(){
gl_FragColor = vec4(vertexWorldPosition , 1.0);
}
, если вы создаете сферу в 0,0,0 и не перемещаете ее, половина будет черной, а другая будет окрашена. В зависимости от масштаба он может быть белым. Допустим, что радиус равен 100, вы получите градиент от 0 до 1, а остальные будут белыми (или r, g, b, зажатыми до 1.0). Тогда попробуйте что-то вроде этого
gl_FragColor = vec4(vec3(sin(vertexWorldPosition.x)), 1.0);
Я не эксперт, так что я обыкновение даже пытаться объяснить то немногое, что я знаю, но [мои эксперименты] (http://blog.2pha.com/experimenting-threejs-shaders и-shadermaterial) могут помочь вам. – 2pha
Кроме того, [Этот плейлист] (https://www.youtube.com/playlist?list=PLW3Zl3wyJwWMpFSRpeMmSBGDShbkiV1Cq) на youtube мне очень помог – 2pha
@ 2pha, большое спасибо, ваши эксперименты легко следовать! – user3578847