我正在使用JavaScript编写第一步并使用Three.js进行编码。
我正在学习如何使用着色器,而且我有一周时间没有使用顶点动画。
这是我的顶点着色器:
uniform float fresnelBias;
uniform float amplitude;
uniform float fresnelScale;
uniform float fresnelPower;
attribute float displacement;
varying float vReflectionFactor;
varying vec3 vReflect;
void main() {
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );
vec3 I = worldPosition.xyz - cameraPosition;
vReflect = reflect( I, worldNormal );
vReflectionFactor = fresnelBias + fresnelScale * pow( 1.0 + dot( normalize( I ), worldNormal ), fresnelPower );
gl_Position = projectionMatrix * mvPosition;
}
这个是片段着色器:
uniform vec3 color;
uniform samplerCube envMap;
varying vec3 vReflect;
varying float vReflectionFactor;
void main() {
vec4 envColor = textureCube( envMap, vec3( -vReflect.x, vReflect.yz ) );
gl_FragColor = vec4(mix(color, envColor.xyz, vec3(clamp( vReflectionFactor, 0.0, 1.0 ))), 1.0);
}
然后我向我的属性声明了一个变量,向我的制服宣布了另一个变量,将它分配给几何体,但是当我加载网站时,我什么都没看到。 JavaScript控制台告诉我,在这一行uniforms.amplitude.value = Math.sin(frame);
中没有定义制服。
你有一些推荐吗?你知道我能做些什么吗?
我在这里提供完整的代码,希望它可以提供帮助:
<script id="vertexShader" type="x-shader/x-vertex">
uniform float fresnelBias;
uniform float amplitude;
uniform float fresnelScale;
uniform float fresnelPower;
attribute float displacement;
varying float vReflectionFactor;
varying vec3 vReflect;
void main() {
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );
vec3 I = worldPosition.xyz - cameraPosition;
vReflect = reflect( I, worldNormal );
vReflectionFactor = fresnelBias + fresnelScale * pow( 1.0 + dot( normalize( I ), worldNormal ), fresnelPower );
gl_Position = projectionMatrix * mvPosition;
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
uniform vec3 color;
uniform samplerCube envMap;
varying vec3 vReflect;
varying float vReflectionFactor;
void main() {
vec4 envColor = textureCube( envMap, vec3( -vReflect.x, vReflect.yz ) );
gl_FragColor = vec4(mix(color, envColor.xyz, vec3(clamp( vReflectionFactor, 0.0, 1.0 ))), 1.0);
}
</script>
<script>
var camera, scene, renderer;
var mesh, material, controls, sky;
init();
animate();
function init(){
renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setClearColor(0xfffff, 0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 400;
//controls = new THREE.TrackballControls( camera );
scene = new THREE.Scene();
var numberOfImages = 46, images = [];
for (var i = 1; i <= numberOfImages; i++) {
images.push('sources/instagram2/image' + i + ".jpg");
}
var urls = images.sort(function(){return .6 - Math.random()}).slice(0,6);
var textureCube = THREE.ImageUtils.loadTextureCube( urls );
// Skybox
var skyshader = THREE.ShaderLib[ "cube" ];
skyshader.uniforms[ "tCube" ].value = textureCube;
var skymaterial = new THREE.ShaderMaterial( {
fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
uniforms: skyshader.uniforms,
depthWrite: false,
side: THREE.BackSide
} );
sky = new THREE.Mesh( new THREE.BoxGeometry( 1500, 1500, 1500 ), skymaterial );
sky.visible = false;
scene.add( sky );
var attributes = {
displacement: {
type: 'f', // a float
value: [] // an empty array
}
};
var uniforms = {
color: {
type: "c",
value: new THREE.Color(0x000000),
},
envMap: {
type: "t",
value: textureCube
},
fresnelBias: {
type: "f",
value: 0.1
},
fresnelScale: {
type: "f",
value: 1.0
},
fresnelPower: {
type: 'f',
value: 2.0
},
amplitude: {
type: 'f',
value: 0
}
};
var vertexShader = document.getElementById('vertexShader').text;
var fragmentShader = document.getElementById('fragmentShader').text;
material = new THREE.ShaderMaterial(
{
uniforms : uniforms,
vertexShader : vertexShader,
fragmentShader : fragmentShader,
});
var loader = new THREE.BinaryLoader();
loader.load( "sources/obj/mmlogo/mm_logo.js", function ( geometry ) {
mesh = new THREE.Mesh(geometry, material);
mesh.scale.set( 300, 300, 300 );
var vertices = mesh.geometry.vertices;
var values = attributes.displacement.value
for(var v = 0; v < vertices.length; v++) {
values.push(Math.random() * 10);
}
scene.add(mesh);
} );
var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
var frame = 0;
function animate() {
uniforms.amplitude.value = Math.sin(frame);
frame += 0.01;
requestAnimationFrame(animate);
//controls.update();
//mesh.rotation.x += 0.005;
//mesh.rotation.y += 0.005;
renderer.render(scene, camera);
stats.update();
}
更新
我在全局范围内添加了uniforms变量,现在控制台没有显示任何问题,但我看不到顶点动画:
<script id="vertexShader" type="x-shader/x-vertex">
uniform float fresnelBias;
uniform float amplitude;
uniform float fresnelScale;
uniform float fresnelPower;
attribute float displacement;
varying float vReflectionFactor;
varying vec3 vReflect;
void main() {
vec3 newPosition = position + normal * vec3(displacement * amplitude);
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
vec3 worldNormal = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );
vec3 I = worldPosition.xyz - cameraPosition;
vReflect = reflect( I, worldNormal );
vReflectionFactor = fresnelBias + fresnelScale * pow( 1.0 + dot( normalize( I ), worldNormal ), fresnelPower );
gl_Position = projectionMatrix * mvPosition;
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
uniform vec3 color;
uniform samplerCube envMap;
varying vec3 vReflect;
varying float vReflectionFactor;
void main() {
vec4 envColor = textureCube( envMap, vec3( -vReflect.x, vReflect.yz ) );
gl_FragColor = vec4(mix(color, envColor.xyz, vec3(clamp( vReflectionFactor, 0.0, 1.0 ))), 1.0);
}
</script>
<script>
var camera, scene, renderer;
var mesh, material, controls, sky;
renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setClearColor(0xfffff, 0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 400;
scene = new THREE.Scene();
var numberOfImages = 46, images = [];
for (var i = 1; i <= numberOfImages; i++) {
images.push('sources/instagram2/image' + i + ".jpg");
}
var urls = images.sort(function(){return .6 - Math.random()}).slice(0,6);
var textureCube = THREE.ImageUtils.loadTextureCube( urls );
var skyshader = THREE.ShaderLib[ "cube" ];
skyshader.uniforms[ "tCube" ].value = textureCube;
var skymaterial = new THREE.ShaderMaterial( {
fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
uniforms: skyshader.uniforms,
depthWrite: false,
side: THREE.BackSide
} );
sky = new THREE.Mesh( new THREE.BoxGeometry( 1500, 1500, 1500 ), skymaterial );
sky.visible = false;
scene.add( sky );
var attributes = {
displacement: {
type: 'f',
value: []
}
};
var uniforms = {
color: {
type: "c",
value: new THREE.Color(0x000000),
},
envMap: {
type: "t",
value: textureCube
},
fresnelBias: {
type: "f",
value: 0.1
},
fresnelScale: {
type: "f",
value: 1.0
},
fresnelPower: {
type: 'f',
value: 2.0
},
amplitude: {
type: 'f',
value: 0
}
};
var vertexShader = document.getElementById('vertexShader').text;
var fragmentShader = document.getElementById('fragmentShader').text;
material = new THREE.ShaderMaterial(
{
uniforms : uniforms,
vertexShader : vertexShader,
fragmentShader : fragmentShader,
});
var loader = new THREE.BinaryLoader();
loader.load( "sources/obj/mmlogo/mm_logo.js", function ( geometry ) {
mesh = new THREE.Mesh(geometry, material);
mesh.scale.set( 100, 100, 100 );
var vertices = mesh.geometry.vertices;
var values = attributes.displacement.value
for(var v = 0; v < vertices.length; v++) {
values.push(Math.random() * 30);
}
scene.add(mesh);
} );
var light = new THREE.AmbientLight( 0x404040 );
scene.add( light );
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
var frame = 0;
function animate() {
uniforms.amplitude.value = Math.sin(frame);
frame += 0.1;
requestAnimationFrame(animate);
//controls.update();
//mesh.rotation.x += 0.005;
//mesh.rotation.y += 0.005;
renderer.render(scene, camera);
}
animate();
</script>
你有什么结果吗?
答案 0 :(得分:0)
您已在uniforms
函数中定义了init()
变量,因此它的范围在该函数范围内,无法在animate()
函数中访问。
将uniforms
变量添加到全局范围,您应该没问题。