How to apply a glowing texture?

I know it’s not even very challenging (in theory) to apply a glowing texture to a model in craft, but I don’t think there’s a default glowing texture**, and I don’t know how to make one…

…does anybody have a glowing material handy?

I think I can actually work out how to apply it once I have it.

** @Simeon maybe worth including in the builtin?

@UberGoober if you take a look at the “AR Face” demo project you’ll see that you can use the bloom effect, along with emissive materials, to make things glow in Craft

This is the scene setup:

    -- Setup lighting
    self.scene.ambientColor = color(63, 63, 63, 255)
    self.sunLight = self.scene.sun:get(craft.light)
    self.sunLight.intensity = 0.7
    self.scene.sun.rotation = quat.eulerAngles(80, 0, 0)

    -- Setup bloom post processing effect
    self.cameraComponent = self.scene.camera:get(craft.camera)
    self.cameraComponent.hdr = true
    self.cameraComponent.colorTextureEnabled = true
    self.bloom = craft.bloomEffect()
    self.cameraComponent:addPostEffect(self.bloom)
    self.bloom.threshold = 1.5
    self.bloom.intensity = 1.2
    self.bloom.softThreshold = 0.4
    self.bloom.iterations = 8

Then when you switch to the “Glowing Eyes” material it simply uses the basic material but multiplies the diffuse colour by the intensity, which causes it to exceed 1.0 in RGB. This triggers the bloom effect

            name = "Glowing Eyes",
            material = craft.material(asset.builtin.Materials.Basic),
            setup = function(face, material)
                face.entity.material = face.blankMaterial
                face.leftEye.material = material
                face.rightEye.material = material

                -- Combine color and intensity for HDR effects
                Intensity = 5
                parameter.color("Color", color(255, 50, 0, 0), function(c)
                    local d = vec3(Color.r/255, Color.g/255, Color.b/255) * Intensity
                    material.diffuse = d
                end)

                parameter.number("Intensity", 0.0, 100, 5, function(i)
                    local d = vec3(Color.r/255, Color.g/255, Color.b/255) * Intensity
                    material.diffuse = d
                end)
            end

Thanks @Simeon!

I got it working in my project and it’s just what I wanted, except maybe I didn’t want the right thing.

I’ve got a bunch of models the player can select between, and I want to use the glow to indicate the currently selected model.

So one thing is that can’t see how to turn it off. I tried the obvious entity.material = nil, and I tried entity:remove(craft.material), but those both caused errors.

How should I switch the glow between models?

post the code please? i’d like to learn from it. thanks!

@RonJeffries i’m unclear what code you want to see.

There’s the code posted by @Simeon up there, which is, you know, up there, and then there’s my code, which is basically the same code just not as good.

And then there is my attempt to remove the glow effect, which just plain doesn’t work; I am happy to post any of these if you want, I’m just not sure there’s much to learn from it…

@UberGoober I think what code @RonJeffries wants is a small working example showing the bloom effect and not have to try to figure out how to code everything.

right. i had the impression you had something small. no big deal, i’m just curious.

@dave1707 @RonJeffries oh, gotcha. Thanks for clearing that up dave. In reality this is part of a big other thing but I think I can work up the ol’ spinning blocks to suit this purpose. Hold on a sec…

Okay this is a good demonstration, in all its buggy glory.

The toggle is supposed to switch the glow between the two blocks.

Wait that one was way too buggy. We just want the right bugs, right? Try this one.

…or a version using the blocky dude models

@UberGoober I stripped your code down to the bare minimum and allowed the bloom to be turned on and off by touching the screen.

viewer.mode=FULLSCREEN

function setup()    
    scene = craft.scene()
    scene.camera.position=vec3(0,0,-4)
    
    cameraComponent = scene.camera:get(craft.camera)
    cameraComponent.hdr = true
    cameraComponent.colorTextureEnabled = true

    bloom = craft.bloomEffect()
    cameraComponent:addPostEffect(bloom)
    bloom.threshold = 4
    bloom.intensity = 1.2
    bloom.softThreshold = 0.4
    bloom.iterations = 8
        
    createBloom(false)
end

function createBloom(glow)
    if ground then
        ground:destroy()
    end
    ground = scene:entity()
    ground.model = craft.model.cube(vec3(1,1,1))
    ground.material = craft.material(asset.builtin.Materials.Specular)
    ground.material.map = readImage(asset.builtin.Surfaces.Desert_Cliff_Roughness)
    ground.position = vec3(0,0,0)
    if glow then
        material = craft.material(asset.builtin.Materials.Basic)
        material.diffuse = vec3(2.5,1.5,4)
        ground.material = material
    end
end

function update(dt)
    scene:update(dt)
end

function draw()
    update(DeltaTime)
    scene:draw()
end

function touched(t)
    if t.state==BEGAN then
        gl=not gl
        createBloom(gl)
    end
end

cool. is any of that documented somewhere?
thanks!

@dave1707 it’s a smart trick but you aren’t actually turning off the glow, right?

You’re completely destroying the entity each time and rebuilding it from scratch either with or without a glow, I think.

I think that’s an elegant solution when you strip it all down to the extent that you did, especially because your program has only one entity, but I don’t think it makes sense in the program I’ll be actually be using it in, which needs to keep track of potentially 50+ entities, and needs to be able to turn glows on and off of each of them at will.

Plus, if there’s no way to turn off a glow without destroying the entity it’s attached to, that’s just, well, weird.

You can just assign a new material. Or even just adjust the settings of an existing material

E.g., you can do:

ground.material.diffuse = <new diffuse color>

If the diffuse colour is intense enough (> 1.0) and bloom is set, then it will glow.

viewer.mode=FULLSCREEN

function setup()
    scene = craft.scene()
    scene.camera.position=vec3(0,0,-4)
    
    cameraComponent = scene.camera:get(craft.camera)
    cameraComponent.hdr = true
    cameraComponent.colorTextureEnabled = true
    
    bloom = craft.bloomEffect()
    cameraComponent:addPostEffect(bloom)
    bloom.threshold = 4
    bloom.intensity = 1.2
    bloom.softThreshold = 0.4
    bloom.iterations = 8
    
    material = craft.material(asset.builtin.Materials.Specular)
    material.map = readImage(asset.builtin.Surfaces.Desert_Cliff_Roughness)
    
    bloomMaterial = craft.material(asset.builtin.Materials.Basic)
    bloomMaterial.diffuse = vec3(2.5,1.5,4)
    
    createGround()
end

function createGround()
    if ground then
        ground:destroy()
    end
    ground = scene:entity()
    ground.model = craft.model.cube(vec3(1,1,1))

    ground.position = vec3(0,0,0)
    
    ground.material = material
end

function update(dt)
    scene:update(dt)
end

function draw()
    update(DeltaTime)
    scene:draw()
end

function touched(t)
    if t.state==BEGAN then
        gl=not gl
        if gl then
            ground.material = bloomMaterial
        else
            ground.material = material
        end
    end
end

Okay but @Simeon, in your code you’re still destroying the entity each time. (Edit: @dave1707 corrected me that you’re actually not, sorry about that)

Attached is a project showing my results when I don’t destroy the entity each time. I can’t get the model’s original skin back.

Also attached are two screenshots to better describe what I’m after.

The first image is from my actual project, where I somehow managed to get the glowing effect happening on the original model without obscuring its skin. I can’t understand how I did this because when I paste the same code into this demo project it doesn’t produce the same results. This is the code from my actual project:


    material = craft.material(asset.builtin.Materials.Basic)
    newEntity.material = material
    material.blendMode = ADDITIVE
    -- Combine color and intensity for HDR effects
    Intensity = 1.5
    local   effectColor = vec3(200/255, 90/255, 30/255) * Intensity
    newEntity.material.diffuse = effectColor
    local effectIntensity = vec3(100/255, 90/255, 130/255) * Intensity
    newEntity.material.diffuse = effectIntensity

The second image is the effect I’d like to achieve, from the project I pasted below, except that I need the figure’s skin to be visible in the center, at least a little, instead of just pure white.

In other words the ideal effect is to have the same skin-visibility as the figure from the first picture (or thereabouts) with the same corona as the second.

Ok I figured out how my existing project achieved that effect and you’re gonna laugh.

Maybe. Well, I did.

It turns out I actually had two copies of the entity overlapping, without knowing it.

So in the attached version of this project I’ve duplicated that trick.

This version actually looks close to what I need.

Of course, just like deleting the entity each time isn’t a scalable solution for a project with tons of entities, making a new copy of the entity each time won’t scale either.

@UberGoober He’s not destroying the entity each time. CreateGround gets called once and ground is nil so the ground:destroy never gets called. Here’s the code with unused code removed. I like examples of things I’ve never used to be as small as possible so I’m not looking at unnecessary code.

viewer.mode=FULLSCREEN

function setup()
    scene = craft.scene()
    scene.camera.position=vec3(0,0,-4)
    
    cameraComponent = scene.camera:get(craft.camera)
    cameraComponent.hdr = true
    cameraComponent.colorTextureEnabled = true
    
    bloom = craft.bloomEffect()
    cameraComponent:addPostEffect(bloom)
    bloom.threshold = 4
    bloom.intensity = 1.2
    bloom.softThreshold = 0.4
    bloom.iterations = 8
    
    material = craft.material(asset.builtin.Materials.Specular)
    material.map = readImage(asset.builtin.Surfaces.Desert_Cliff_Roughness)
    
    bloomMaterial = craft.material(asset.builtin.Materials.Basic)
    bloomMaterial.diffuse = vec3(2.5,1.5,4)
    
    ground = scene:entity()
    ground.model = craft.model.cube(vec3(1,1,1))
    ground.position = vec3(0,0,0)    
    ground.material = material
end

function update(dt)
    scene:update(dt)
end

function draw()
    update(DeltaTime)
    scene:draw()
end

function touched(t)
    if t.state==BEGAN then
        gl=not gl
        if gl then
            ground.material = bloomMaterial
        else
            ground.material = material
        end
    end
end

again, is this stuff written up anywhere?

@RonJeffries +1