I'm new in computer graphics. I'm building a local web application to highlight the effects of shaders on meshes. I have problems with the application of the bumbp mapping shader which causes my mesh to disappear from the scene.At the moment, i can make only simple shaders work inside my application. I would like to see my mesh with a Bumbp effect. this is what I did:
Vertex shader code:
<script type="application/vertexShader" id="vertexBumbpShaderCode">
precision highp float;
attribute vec3 vert_pos;
attribute vec3 vert_tang;
attribute vec3 vert_bitang;
attribute vec2 vert_uv;
uniform mat4 model_mtx;
uniform mat4 norm_mtx;
uniform mat4 proj_mtx;
varying vec2 frag_uv;
varying vec3 ts_light_pos; // Tangent space values
varying vec3 ts_view_pos; //
varying vec3 ts_frag_pos; //
mat3 transposes(in mat3 inMatrix)
{
vec3 i0 = inMatrix[0];
vec3 i1 = inMatrix[1];
vec3 i2 = inMatrix[2];
mat3 outMatrix = mat3(
vec3(i0.x, i1.x, i2.x),
vec3(i0.y, i1.y, i2.y),
vec3(i0.z, i1.z, i2.z)
);
return outMatrix;
}
void main(void)
{
gl_Position = proj_mtx * vec4(vert_pos, 1.0);
ts_frag_pos = vec3(model_mtx * vec4(vert_pos, 1.0));
vec3 vert_norm = cross(vert_bitang, vert_tang);
vec3 t = normalize(mat3(norm_mtx) * vert_tang);
vec3 b = normalize(mat3(norm_mtx) * vert_bitang);
vec3 n = normalize(mat3(norm_mtx) * vert_norm);
mat3 tbn = transposes(mat3(t, b, n));
vec3 light_pos = vec3(1, 2, 0);
ts_light_pos = tbn * light_pos;
// Our camera is always at the origin
ts_view_pos = tbn * vec3(0, 0, 0);
ts_frag_pos = tbn * ts_frag_pos;
frag_uv = vert_uv;
}
</script>
Fragment shader code:
<script type="application/fragmentShader" id="fragmentBumbpShaderCode" >
precision highp float;
uniform sampler2D tex_norm;
uniform sampler2D tex_diffuse;
uniform sampler2D tex_depth;
/*
The type is controlled by the radio buttons below the canvas.
0 = No bump mapping
1 = Normal mapping
2 = Parallax mapping
3 = Steep parallax mapping
4 = Parallax occlusion mapping
*/
uniform int type;
uniform int show_tex;
uniform float depth_scale;
uniform float num_layers;
varying vec2 frag_uv;
varying vec3 ts_light_pos;
varying vec3 ts_view_pos;
varying vec3 ts_frag_pos;
vec2 parallax_uv(vec2 uv, vec3 view_dir)
{
if (type == 2) {
// Parallax mapping
float depth = texture2D(tex_depth, uv).r;
vec2 p = view_dir.xy * (depth * depth_scale) / view_dir.z;
return uv - p;
} else {
float layer_depth = 1.0 / num_layers;
float cur_layer_depth = 0.0;
vec2 delta_uv = view_dir.xy * depth_scale / (view_dir.z * num_layers);
vec2 cur_uv = uv;
float depth_from_tex = texture2D(tex_depth, cur_uv).r;
for (int i = 0; i < 32; i++) {
cur_layer_depth += layer_depth;
cur_uv -= delta_uv;
depth_from_tex = texture2D(tex_depth, cur_uv).r;
if (depth_from_tex < cur_layer_depth) {
break;
}
}
if (type == 3) {
// Steep parallax mapping
return cur_uv;
} else {
// Parallax occlusion mapping
vec2 prev_uv = cur_uv + delta_uv;
float next = depth_from_tex - cur_layer_depth;
float prev = texture2D(tex_depth, prev_uv).r - cur_layer_depth
+ layer_depth;
float weight = next / (next - prev);
return mix(cur_uv, prev_uv, weight);
}
}
}
void main(void)
{
vec3 light_dir = normalize(ts_light_pos - ts_frag_pos);
vec3 view_dir = normalize(ts_view_pos - ts_frag_pos);
// Only perturb the texture coordinates if a parallax technique is selected
vec2 uv = (type < 2) ? frag_uv : parallax_uv(frag_uv, view_dir);
vec3 albedo = texture2D(tex_diffuse, uv).rgb;
if (show_tex == 0) { albedo = vec3(1,1,1); }
vec3 ambient = 0.3 * albedo;
if (type == 0) {
// No bump mapping
vec3 norm = vec3(0,0,1);
float diffuse = max(dot(light_dir, norm), 0.0);
gl_FragColor = vec4(diffuse * albedo + ambient, 1.0);
} else {
// Normal mapping
vec3 norm = normalize(texture2D(tex_norm, uv).rgb * 2.0 - 1.0);
float diffuse = max(dot(light_dir, norm), 0.0);
gl_FragColor = vec4(diffuse * albedo + ambient, 1.0);
}
}
</script>
Javascript Code using Babylonjs:
"use strict";
document.addEventListener("DOMContentLoaded", startGame, false);
function startGame(){
var rubikBox;
var sphere;
var currentMesh;
if (BABYLON.Engine.isSupported()) {
var canvas = document.getElementById("renderCanvas");
var engine = new BABYLON.Engine(canvas, false);
var scene = new BABYLON.Scene(engine);
var camera = new BABYLON.ArcRotateCamera("Camera", 0, Math.PI / 2, 10, BABYLON.Vector3.Zero(), scene);
// camera.setPosition(new BABYLON.Vector3(60, 50, 100));
camera.attachControl(canvas, true);
camera.lowerBetaLimit = 0.1;
camera.upperBetaLimit = (Math.PI / 2) * 0.99;
camera.lowerRadiusLimit = 100;
// Creating light
var light = new BABYLON.PointLight("light", new BABYLON.Vector3(0, 1, 0), scene);
light.diffuse = new BABYLON.Color3(1, 0, 0);
light.specular = new BABYLON.Color3(0, 1, 0);
//rubikBox = new BABYLON.Mesh.CreateBox("red", 20, scene);
sphere = new BABYLON.Mesh.CreateSphere("Sphere", 100, 40, scene);
currentMesh = 'earth';
// Creating sphere
sphere.position.z = 1;
var amigaMaterial = new BABYLON.ShaderMaterial("amiga", scene, {
vertexElement: "vertexShaderCode",
fragmentElement: "fragmentShaderCode",
},
{
attributes: ["position", "uv"],
uniforms: ["worldViewProjection"]
});
amigaMaterial.setTexture("textureSampler", new BABYLON.Texture("earthmap1k.jpg", scene));
amigaMaterial.setFloat("time", 0);
amigaMaterial.setVector3("cameraPosition", BABYLON.Vector3.Zero());
amigaMaterial.backFaceCulling = false;
sphere.material = amigaMaterial;
engine.runRenderLoop(function () {
sphere.rotation.y += 0.005;
scene.render();
});
document.getElementById("Bumbp").addEventListener("click", BumbpShader, false);
function BumbpShader() {
var BumbpMaterial = new BABYLON.ShaderMaterial("amiga", scene, {
vertexElement: "vertexBumbpShaderCode",
fragmentElement: "fragmentBumbpShaderCode",
},
{
attributes: ["position", "uv"],
uniforms: ["worldViewProjection"]
});
switch(currentMesh){
case "cube":
BumbpMaterial.setTexture("textureSampler", new BABYLON.Texture("cubik.jpg", scene));
BumbpMaterial.setFloat("time", 0);
BumbpMaterial.setVector3("cameraPosition", BABYLON.Vector3.Zero());
BumbpMaterial.backFaceCulling = false;
rubikBox.material = BumbpMaterial;
break;
case "earth":
BumbpMaterial.setTexture("textureSampler", new BABYLON.Texture("earthmap1k.jpg", scene));
BumbpMaterial.setFloat("time", 0);
BumbpMaterial.setVector3("cameraPosition", BABYLON.Vector3.Zero());
BumbpMaterial.backFaceCulling = false;
sphere.material = BumbpMaterial;
break;
}
scene.render();
return;
}
}
I have minimized the affected lines, I add, saying that the chrome console does not give me any kind of error.
At first glance it looks like you are missing to declare all your uniforms in the ShaderMaterial constructor