User posts sunnix
30 January 2018 19:50
can textures be saved also?
11 September 2017 12:59
Ok, thank you for this tip !
09 September 2017 00:46
Thank you Mikhail !
You've brought me on the right path. It just needs an "invert" node in addition to get the result I wanted. Nodes look like this in the end:

Thank you very much

Problem solved !
08 September 2017 17:56
Hi everybody,
I am trying to combine a webcan stream (canvas texture) and a transparent png (also canvas texture) in a same (node) material. But the PNG is geting transparent where it should remain opaque. I set webcam stream and the PNG also in 2 separate materials on separate object to compare the transparency. And it looks as I would like.

Here a screenshot to compare

Here the setup my nodes material combining webcam stream canvas texture with transparent PNG canvas texture

Here my Blend and js html css files in a zip

I think I have to better set the nodes to get the same effect as when the materials are applied on separated objects. But I don't know how.

Any clues ?

Thank you in advance !
30 August 2017 14:37
Great, it works !!
Thank you very much, Will
30 August 2017 14:18
Oh ! Very cool !
Thank you for your tip, Will. I'll correct this and look if it fixes the trouble.
Thanks again
29 August 2017 14:44
Hi everybody,

I am trying to make this app working.

The webcam script is allready working (thanks to the blend4web snippet) but when I add the script for pasting text in the text bubble it doesn't work completly. The text canvas texture of text bubble doesn't load.
I've launched the text bubble script independently and it works. But when I paste it with the webcam script together then it doesn't work anymore.
I've tried to fix it but as I am a javascript noob I can't realy figure out where the trouble comes from.

Any Ideas would be very welcome
Thank very much

Here attached in zip (blend file and js/css/html files if needed):

js script looks like this:
 "use strict";

b4w.register("beSomething", function(exports, require) {

var m_app     = require("app");
var m_cfg     = require("config");
var m_data    = require("data");
var m_ver     = require("version");
var m_tex     = require("textures");
var m_scn     = require("scenes");
var m_cont    = require("container");
var m_version = require("version");
var m_scrn = require("screenshooter");
var m_main    = require("main");
var m_sfx     = require("sfx");

var DEBUG = (m_version.type() === "DEBUG");

var TIME_DELAY = 1000 / 24;
var WAITING_DELAY = 1000;

var _cam_waiting_handle = null;

exports.init = function() {
        canvas_container_id: "main_canvas_container",
        callback: init_cb,
        physics_enabled: false,
        background_color: [1, 1, 1, 1],
        alpha: true,
        autoresize: true,
        assets_dds_available: !DEBUG,
        assets_min50_available: !DEBUG,
        console_verbose: true

function init_cb(canvas_elem, success) {

    if (!success) {
        console.log("b4w init failure");


// LOAD function: Start
function load() {
    m_data.load("beSomething.json", load_cb);
// LOAD function: End

// LOAD_CD function: Start
function load_cb(data_id, success) {

    if (!success) {
        console.log("b4w load failure");

    var error_cap = m_scn.get_object_by_name("noArgument");

/////SCREENSHOT: Start/////    
//Take a screenshot of the 3D scene by clicking the screenshot button
	document.getElementById("btnScreenshot").addEventListener("mouseover", btnScreenshotOver);
	function btnScreenshotOver() { = "solid";
	document.getElementById("btnScreenshot").addEventListener("mouseout", btnScreenshotOut);
	function btnScreenshotOut() { = "none";
	document.getElementById("btnScreenshot").addEventListener("click", takeScreenshot);
	function takeScreenshot() {
/////SCREENSHOT: End///// 
/////WEBCAM: Start/////    
    if (Boolean(get_user_media()))

// GET_USER_MEDIA function: Start   
function get_user_media() {
    if (Boolean(navigator.getUserMedia))
        return navigator.getUserMedia.bind(navigator);
    else if (Boolean(navigator.webkitGetUserMedia))
        return navigator.webkitGetUserMedia.bind(navigator);
    else if (Boolean(navigator.mozGetUserMedia))
        return navigator.mozGetUserMedia.bind(navigator);
    else if (Boolean(navigator.msGetUserMedia))
        return navigator.msGetUserMedia.bind(navigator);
        return null;
// GET_USER_MEDIA function: End

// START_VIDEO function: Start 
function start_video() {

    if (_cam_waiting_handle)

    var user_media = get_user_media();
    var media_stream_constraint = {
        video: { width: 1280, height: 720 }
    var success_cb = function(local_media_stream) {
        //var video = document.createElement("video");  -->  not compatible with control screen option
		var video = document.querySelector("#videoElement");
        video.setAttribute("autoplay", "true");
        video.src = window.URL.createObjectURL(local_media_stream);
        var error_cap = m_scn.get_object_by_name("noArgument");

        var obj3D = m_scn.get_object_by_name("face");
        var contextObj3D = m_tex.get_canvas_ctx(obj3D, "texture_canvas");
        var update_canvas = function() {
            contextObj3D.drawImage(video, 0, 0, video.videoWidth, video.videoHeight,
                    0, 0, contextObj3D.canvas.width, contextObj3D.canvas.height);
            m_tex.update_canvas_ctx(obj3D, "texture_canvas");
            setTimeout(function() {update_canvas()}, TIME_DELAY);

        video.onloadedmetadata = function(e) {
    var fail_cb = function() {
        var error_cap = m_scn.get_object_by_name("noArgument");
        _cam_waiting_handle = setTimeout(start_video, WAITING_DELAY);

    user_media(media_stream_constraint, success_cb, fail_cb);
// START_VIDEO function: End
/////WEBCAM: End/////

/////TEXT INPUT: Start/////
    // TEXTINPUT function: Start
    function textInput() {
    var face_text = m_scenes.get_object_by_name("face_text");
    var ctx_imageText = m_tex.get_canvas_ctx(face_text, "skinnings_text");
    var Enter = document.getElementById("Enter");

    if (ctx_imageText) {
        var img = new Image();
        img.src = "Text.jpg";
        /* this function load the image that been find at the end of the path */
        img.onload = function() {
        ctx_imageText.drawImage(img, 0, 0, ctx_imageText.canvas.width, 
        m_tex.update_canvas_ctx(face_text, "skinnings_text");

/* link the button "Enter" to the function "writeTexte" */
Enter.addEventListener('click', writeText); 

/* this function load the Erase function and after the Write function*/     
function writeText(){

/* this function clear the texture canvas (text and image to) before it will be written on it*/ 
function Erase() {
ctx_imageText.clearRect(0, 0, ctx_imageText.canvas.width, ctx_imageText.canvas.height);
/* this function display the text from the textarea and redisplay the image*/
function Write(){           
            var text = document.getElementById("myText").value;
            var img = new Image();
            img.src = "Text.jpg";
            img.onload = function() {
            ctx_imageText.drawImage(img, 0, 0, ctx_imageText.canvas.width,
            ctx_imageText.fillStyle = "rgba(255,0,0,255)";
            ctx_imageText.font = "250px Arial";
            ctx_imageText.fillText(text, 300, 300);
            m_tex.update_canvas_ctx(face_text, "skinnings_text");

    // TEXTINPUT function: End
/////TEXT INPUT: End///// 

// LOAD_CD function: End 

html script looks like this:
 <!DOCTYPE html>



<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">

<link rel="stylesheet" href="beSomething.css" type="text/css">

<script type="text/javascript" src="b4w.min.js"></script>
<script type="text/javascript" src="beSomething.js"></script>


<!-- CONTROL SCREEN: Start -->
<div id="controlScreen" style="z-index:1;" align="center">
<video autoplay="true" id="videoElement">   
<!-- CONTROL SCREEN: End -->

<!-- POSITION FACE: Start -->
<div id="controlScreen" style="z-index:4;" align="center"><img src="target.png" style="position:relative; height:100%; width:100%; z-index:5;">
<!-- POSITION FACE: End -->    

<!-- 3D VIEWER: Start --> 
<div id="main_canvas_container" style="z-index:0;"></div>
<!-- 3D VIEWER: End --> 
<div style="position:absolute; left:-3px; bottom:90px; width:135px; z-index:4;">
<div id="btnScreenshot" class="Button" style="position:absolute; width:30px; height:30px; right:59px; background-color:#F00" align="center"> <img src="screenshot.png" style="position:relative; top:2px; width:24px; height:24px; z-index:3;"> </div>
<h id="text-menu" style="top:34px;">take a<br> screenshot!</h>

<!-- TEXT AREA: Start -->    
<div style="position:absolute; left:150px; bottom:90px; width:135px; z-index:3;">
<!-- <input type="text" id="myText" value="Some text..."> -->
<textarea spellcheck="false" id = "myText" rows="1">hello world</textarea>
<button id="Enter">enter</button>
<!-- TEXT AREA: End -->  

13 December 2016 17:36
Hi bjk,
Thank you very much for your help !
I'll download the last version to make it. Thanks again
12 December 2016 14:12
Hi bjk,
great, thank you very much for your attachment.
I've downloaded it on my windows7 desktop, opened it and run the script "blad1". I became the first 3 nodes diplayed in the nodes blender aera but at this point (line 26 in the script) the console displays an error : KeyError: 'bpy_prop_collection[key]: key "vd" not found'
(see screenshot attached)
I use Blender 2.76b and Blend4Web 16.02 SDK. could it be the reason of this trouble ?
Or should I copy your blend file in a specific folder before opening it ?

Thank you for your advice
06 December 2016 18:04
Reply to post of user bjk
Thank you Konstantin!

After searching I was able to create a small tree (as a start):

import bpy

scene = bpy.context.scene

scene.render.engine = 'BLEND4WEB'
scene.b4w_use_logic_editor = True
bpy.ops.node.new_node_tree(type='B4WLogicNodeTreeType', name="B4WLogicNodeTree")
scene.b4w_active_logic_node_tree = "B4WLogicNodeTree"

ntree =['B4WLogicNodeTree']

e_point ='B4W_logic_node')
e_point.type = 'ENTRYPOINT'

regstore ='B4W_logic_node')
regstore.type = 'REGSTORE'
regstore.floats['inp1'].float = 2 [s]regstore.param_number1 = 1[/s]
regstore.location = 160, 100

sw_select ='B4W_logic_node')
sw_select.type = 'SWITCH_SELECT'
sw_select.location = 400, 100

move_to ='B4W_logic_node')
move_to.type = 'MOVE_TO'
move_to.location = 650, 100

reroute1 ="NodeReroute")
reroute1.location = 600, -100

reroute2 ="NodeReroute")
reroute2.location = 380, -100[0], regstore.inputs[0])[0], sw_select.inputs[0])[0], move_to.inputs[0])[2], reroute1.inputs[0])[0], reroute2.inputs[0])[0], sw_select.inputs[0])

This is okay, I believe, but how do I select an object (the default cube) in Switch_Select and how do I add a new socket?

By the way, I watched the conference video. Congratulations!

Hi bjk,
I would like also add a new logic nodes.
Where do you add this code (above in the quote) ? Do you inject it in the "" file or do you create an extra file for it ?

And where should this code be added:
bpy.ops.node.b4w_logic_add_dyn_jump_sock('INVOKE_DEFAULT', node_tree="B4WLogicNodeTree", node="B4WLogicNode", sock="Jump_Dummy_Output_Socket")

Thank you !