I’m writing custom shaders and trying to get the matrices into shaders. It works just fine for worldViewProjection
but not for view
. As far as I can tell, all the values of view
are just 0.0
.
But according to the Building Shaders With Babylon.js article, I read it that all the uniform matrices would be set by Babylon.js:
BABYLON.ShaderMaterial
can also handle the following matrices for you:
world
,view
,projection
,worldView
,worldViewProjection
.No need for math anymore. For instance, each time you execute
sphere.rotation.y += 0.05
, theworld
matrix of the sphere will be generated for you and transmitted to the GPU.
In the following, I post a minimal example of the problematic source code. It only produces the correct result if line #59 is commented-in, i.e., this one:
planeMaterial.setMatrix("view", camera.getViewMatrix());
but if it is commented-out, the plane is just black, which is not what I would expect.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="../style.css">
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
<script src="https://cdn.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
<title>Custom Shaders... view not working</title>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<script type="text/javascript">
const canvas = document.getElementById('renderCanvas');
var engine = new BABYLON.Engine(canvas, true, {preserveDrawingBuffer: true, stencil: true});
var scene = new BABYLON.Scene(engine);
var camera = addCameraToScene();
var ground = BABYLON.Mesh.CreateGround('ground1', 10, 10, 100, scene, false);
BABYLON.Effect.ShadersStore["customVertexShader"] = `
precision highp float;
attribute vec3 position;
uniform mat4 world;
uniform mat4 view;
uniform mat4 worldViewProjection;
varying vec3 vColor;
void main() {
vec4 p = vec4(position, 1.);
gl_Position = worldViewProjection * p;
vColor = mat3(view) * position.xyz;
}
`;
BABYLON.Effect.ShadersStore["customFragmentShader"] = `
precision highp float;
varying vec3 vColor;
void main() {
gl_FragColor = vec4(vColor ,1.);
}
`;
const shaderMaterial = new BABYLON.ShaderMaterial("custom", scene, "./custom", {
attributes: ["position"],
uniforms: ["view", "worldViewProjection"]
});
var planeMaterial = new BABYLON.ShaderMaterial('custom', scene, 'custom', { });
ground.material = planeMaterial;
// run the render loop
engine.runRenderLoop(function(){
planeMaterial.diffuseColor = new BABYLON.Color3(1, 0, 0, 1);
// planeMaterial.setMatrix("view", camera.getViewMatrix());
scene.render();
});
// the canvas/window resize event handler
window.addEventListener('resize', function(){
engine.resize();
});
// ----------------------------------------------------------------------
// --- vvv -------------------- FUNCTIONS ----------------------- vvv ---
function addCameraToScene() {
// Create an arcball camera, let it focus on (0,0,0), position it at a distance of 10, at rotation of PI/3:
var camera = new BABYLON.ArcRotateCamera('camera1', 0, 1.047, 10, new BABYLON.Vector3(0, 0, 0), scene);
// Target the camera to scene origin:
camera.setTarget(BABYLON.Vector3.Zero());
// Attach the camera to the canvas:
camera.attachControl(canvas, false);
camera.lowerBetaLimit = 0.2; // Almost peak
camera.upperBetaLimit = 1.5; // Almost straight down to xz-plane
camera.lowerRadiusLimit = 3; // Not tooo close
camera.minZ = 1.0;
return camera;
}
</script>
</body>
</html>