gpt4 book ai didi

三.js - 将顶点颜色传递给片段着色器

转载 作者:行者123 更新时间:2023-12-04 09:47:57 25 4
gpt4 key购买 nike

我在three.js 中搜索了从简单到复杂的着色器示例,但似乎找不到将顶点保持的颜色传递给片段着色器的简单示例。我做了一个简单的例子,其中顶点着色器只将顶点留在原处,但也通过“vColor”变化将“颜色”统一(我想我在某处看到但尚未使用)传递给片段着色器,然后在片段着色器中,我只是想返回相同的颜色。浏览器将三角形呈现为黑色,我猜颜色是空的。我知道这很简单,但我自己无法弄清楚,而且我无法弄清楚 ShaderMaterial 将什么传递给我可以在那里使用的着色器。有人可以解释一下吗?

这是代码:

<script id="vertexShader" type="x-shader/x-vertex">
uniform vec3 color;

varying vec3 vColor;

void main(){
vColor = color;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>

<script id="fragmentShader" type="x-shader/x-fragment">
varying vec3 vColor;

void main(){
gl_FragColor = vec4( vColor.rgb, 1.0 );
}
</script>
<script>
var container,
camera,
controls,
scene,
renderer,
model;

init();
animate();

function init() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.y = 150;
camera.position.z = 500;

scene = new THREE.Scene();

var geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(-120, -200, 0),
new THREE.Vector3(120, -200, 0));

geometry.faces.push(new THREE.Face3(0, 1, 2));

geometry.faces[0].vertexColors[0] = new THREE.Color("rgb(255,0,0)");
geometry.faces[0].vertexColors[1] = new THREE.Color("rgb(0,255,0)");
geometry.faces[0].vertexColors[2] = new THREE.Color("rgb(0,0,255)");

var materialShader = new THREE.ShaderMaterial({
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent
});

var materialBasic = new THREE.LineBasicMaterial({
vertexColors: THREE.VertexColors,
linewidth: 1
});

var model = new THREE.Mesh(geometry, materialShader);
model.position.y = 150;
scene.add(model);

renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xf0f0f0);
renderer.setSize(window.innerWidth, window.innerHeight);

container = document.createElement('div');
document.body.appendChild(container);
container.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize, false);
}

function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();

renderer.setSize(window.innerWidth, window.innerHeight);
}

function animate() {
requestAnimationFrame(animate);
render();
}

function render() {
renderer.render(scene, camera);
}

</script>

请注意,我有两种类型的 Material 用于测试 - 用于着色器的 materialShader 和作为可以正常工作的控制 Material 的 materialBasic。我没有足够的声誉来发布图片,但如果堆栈溢出保留上传的图片,你应该在这里看到渲染的例子: http://i.stack.imgur.com/tjdSt.png

最佳答案

我通过使用变量解决了这个问题。我犯的第一个错误是认为顶点着色器代码中的颜色(uniform vec3 color;)是统一的,但实际上它是 属性 .其次,我不必定义它,它已经定义了,我在接收顶点着色器的堆栈跟踪时发现了这一点,并且在那里我弄清楚了最终着色器 GLSL 代码是如何构建的:

1: precision highp float;
2: precision highp int;
3:
4: #define VERTEX_TEXTURES
5:
6:
7: #define MAX_DIR_LIGHTS 0
8: #define MAX_POINT_LIGHTS 0
9: #define MAX_SPOT_LIGHTS 0
10: #define MAX_HEMI_LIGHTS 0
11: #define MAX_SHADOWS 0
12: #define MAX_BONES 58
13:
//a lot of blank space was printed in here, i skipped the lines
33:
34: uniform mat4 modelMatrix;
35: uniform mat4 modelViewMatrix;
36: uniform mat4 projectionMatrix;
37: uniform mat4 viewMatrix;
38: uniform mat3 normalMatrix;
39: uniform vec3 cameraPosition;
40: attribute vec3 position;
41: attribute vec3 normal;
42: attribute vec2 uv;
43: attribute vec2 uv2;
44: #ifdef USE_COLOR
45: attribute vec3 color;
46: #endif
47: #ifdef USE_MORPHTARGETS
48: attribute vec3 morphTarget0;
49: attribute vec3 morphTarget1;
50: attribute vec3 morphTarget2;
51: attribute vec3 morphTarget3;
52: #ifdef USE_MORPHNORMALS
53: attribute vec3 morphNormal0;
54: attribute vec3 morphNormal1;
55: attribute vec3 morphNormal2;
56: attribute vec3 morphNormal3;
57: #else
58: attribute vec3 morphTarget4;
59: attribute vec3 morphTarget5;
60: attribute vec3 morphTarget6;
61: attribute vec3 morphTarget7;
62: #endif
63: #endif
64: #ifdef USE_SKINNING
65: attribute vec4 skinIndex;
66: attribute vec4 skinWeight;
67: #endif
68:
69:
70:
71: varying vec3 vColor;
72:
73: void main(){
74: vColor = color;
75: gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
76: }
77:

这意味着我不必定义颜色属性。此外,这可以在 Three.js 文件中看到,但它是一个连接字符串,因此很难阅读。

我需要做的最后一件事是在 ShaderMaterial 中定义 vertexColors: THREE.VertexColors,就像在 LineBasicMaterial 中一样,我偶然发现了这一点(以“让我们看看会发生什么”的方式)。

这是最终有效的代码:
<script id="vertexShader" type="x-shader/x-vertex">


varying vec3 vColor;

void main(){
vColor = color;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>

<script id="fragmentShader" type="x-shader/x-fragment">
varying vec3 vColor;

void main(){
gl_FragColor = vec4( vColor.rgb, 1.0 );
}
</script>
<script>
var container,
camera,
controls,
scene,
renderer,
model;

init();
animate();

function init() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.y = 150;
camera.position.z = 500;

scene = new THREE.Scene();

var geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(-120, -200, 0),
new THREE.Vector3(120, -200, 0));

geometry.faces.push(new THREE.Face3(0, 1, 2));

geometry.faces[0].vertexColors[0] = new THREE.Color("rgb(255,0,0)");
geometry.faces[0].vertexColors[1] = new THREE.Color("rgb(0,255,0)");
geometry.faces[0].vertexColors[2] = new THREE.Color("rgb(0,0,255)");

var materialShader = new THREE.ShaderMaterial({
vertexShader: document.getElementById('vertexShader').textContent,
vertexColors: THREE.VertexColors,
fragmentShader: document.getElementById('fragmentShader').textContent
});

var materialBasic = new THREE.LineBasicMaterial({
vertexColors: THREE.VertexColors,
linewidth: 1
});

var model = new THREE.Mesh(geometry, materialShader);
model.position.y = 150;
scene.add(model);

renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xf0f0f0);
renderer.setSize(window.innerWidth, window.innerHeight);

container = document.createElement('div');
document.body.appendChild(container);
container.appendChild(renderer.domElement);
window.addEventListener('resize', onWindowResize, false);
}

function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();

renderer.setSize(window.innerWidth, window.innerHeight);
}

function animate() {
requestAnimationFrame(animate);
render();
}

function render() {
renderer.render(scene, camera);
}

</script>

我希望这会帮助其他人理解着色器中的变量。干杯。

关于三.js - 将顶点颜色传递给片段着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25740054/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com