Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Add Shade shader to 2D circle object?

in Shaders Posts: 95

I suppose to make it work, I would need a circular mesh, correct? That sounds like a bunch of triangles just to get one smooth-looking circle. And if I want many of these small, shader-textured circles?

Once I have the right mesh, then just apply a shader I’ve created in Shade, right?

Anyone have a better way, or can provide sample code? Thanks!

Tagged:

Comments

  • dave1707dave1707 Mod
    edited March 8 Posts: 8,396

    @brianolive Not sure what you would do with this, but here’s a circle that’s created from a bunch of triangular meshes.

    displayMode(FULLSCREEN)
    
    function setup()
        tab={}
        m=mesh()
        a=100
        b=100
        for x=-a,a do
            y=math.sqrt((1-(x^2)/a^2)*b^2)
            table.insert(tab,vec2(x+WIDTH/2,y+HEIGHT/2))
        end  
        for x=a,-a,-1 do
            y=math.sqrt((1-(x^2)/a^2)*b^2)
            table.insert(tab,vec2(x+WIDTH/2,-y+HEIGHT/2))
        end 
        m.vertices=triangulate(tab)
        m:setColors(255,0,0)
    end
    
    function draw()
        background(40, 40, 50)
        m.draw(m)
    end
    
  • edited March 10 Posts: 489

    I'd use angles to make the mesh as it makes the vertices go round the circle evenly which is easier to work with for colours and textures. You can also reuse meshes so depending on what you intend to do, it might be enough to create one mesh and draw it many times.

    -- CircleMesh
    
    function setup()
    
        local v = {}
        local c = {}
        local n = 30
    
        local x,y = 1,0
    
        for k=1,n do
            table.insert(v,vec2(0,0))
            table.insert(v,vec2(x,y))
            table.insert(c,color(255,0))
            table.insert(c,hsl((k-1)/n,1,.5))
            x,y = math.cos(2*math.pi/n*k),math.sin(2*math.pi/n*k)
            table.insert(v,vec2(x,y))
            table.insert(c,hsl(k/n,1,.5))
        end
    
        m = mesh()
        m.vertices = v
        m.colors = c
        p = {}
        for k=1,100 do
            table.insert(p,{
                math.random(0,WIDTH), 
                math.random(0,HEIGHT), 
                math.random(20,60),
                math.random(20,60),
                math.random(1,360)
            })
        end
    end
    
    function draw()
        background(40,40,50)
        for k,v in ipairs(p) do
            pushMatrix()
            translate(v[1],v[2])
    
            rotate(v[5]+ElapsedTime*60)
            scale(v[3],v[4])
            rotate(-ElapsedTime*30)
            m:draw()
    
            popMatrix()
        end
    
    end
    
    
    function hsl(h,s,l,a)
            h = (h-math.floor(h))*6
            s = s or 1
            l = l or 1
            a = a or 255
            local c = (1-math.abs(2*l-1))*s*255
            local m = l*255 - c/2
            local x = c*(1 - math.abs(h%2 - 1))
            local r,g,b
            if h < 1 then
                r,g,b = c+m,x+m,m
            elseif h < 2 then
                r,g,b = x+m,c+m,m
            elseif h < 3 then
                r,g,b = m,c+m,x+m
            elseif h < 4 then
                r,g,b = m,x+m,c+m
            elseif h < 5 then
                r,g,b = x+m,m,c+m
            else
                r,g,b = c+m,m,x+m
            end
            return color(r,g,b,a)
        end
    
  • Posts: 95

    Thanks guys. I appreciate the sample code! From there, I believe assigning a shader from Shade is a one-line call, so I should be good to go.

  • Posts: 614

    @brianolive when you get this working, please post an example, might come in handy! thanks!

  • dave1707dave1707 Mod
    Posts: 8,396

    Here’s an example to put an image on a circle. You can change the step size to create different shapes, 90 for a square, 120 for a triangle, etc. Change the radius for different sizes. You can change the offset if you create a square or other shape to alter the starting orientation.

    @Simeon When this program starts, there is a slight delay before the program covers the full screen. The screen goes about 3/4 of the way to the left, pauses, and then goes all the way.

    displayMode(FULLSCREEN)
    
    function setup()  
        assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")        
        scene = craft.scene()
        v=scene.camera:add(OrbitViewer,vec3(0,0,0), 20, 0, 1000)
        img=readImage(asset.builtin.Cargo_Bot.Startup_Screen)
        v.rx,v.ry=-180,180
        offset=0
        step=1
        radius=5
        p1=vec3(0,0,0)
        s1=vec2(.5,.5)
        for a=0+offset,359+offset,step do
            x=math.cos(math.rad(a))
            y=math.sin(math.rad(a))
            p2=vec3(x*radius,0,y*radius)
            s2=vec2(x*.5+.5,y*.5+.5)
            x=math.cos(math.rad(a+step))
            y=math.sin(math.rad(a+step))
            p3=vec3(x*radius,0,y*radius)
            s3=vec2(x*.5+.5,y*.5+.5)
            createSlice(p1,p2,p3,s1,s2,s3) 
        end
    end
    
    function draw()
        update(DeltaTime)
        scene:draw() 
    end
    
    function update(dt)
        scene:update(dt)
    end
    
    function createSlice(p1,p2,p3,s1,s2,s3)
        local c=color(255, 255, 255, 255)
        local r=scene:entity()
        r.model = craft.model()
        r.model.positions={p1,p2,p3}
        r.model.indices={1,2,3,3,2,1}
        r.model.colors={c,c,c}
        r.model.uvs={s1,s2,s3}
        r.material = craft.material(asset.builtin.Materials.Basic)  
        r.material.map=img
    end
    
  • dave1707dave1707 Mod
    Posts: 8,396

    @Simeon I made a copy of my above program and tried to modify it to use one model like you did in my other program. I couldn’t get it to work. The difference between the two programs is the one you modified was made up of squares (two triangles) per model. This one uses one triangle per model. I’ll keep trying, but I wonder if one model doesn’t work here.

  • SimeonSimeon Admin Mod
    Posts: 5,364

    @dave1707 this appears to work for me

    displayMode(FULLSCREEN)
    
    function setup()  
        assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")        
        scene = craft.scene()
        v=scene.camera:add(OrbitViewer,vec3(0,0,0), 20, 0, 1000)
        img=readImage(asset.builtin.Cargo_Bot.Startup_Screen)
        v.rx,v.ry=-180,180
        offset=0
        step=1
        radius=5
        p1=vec3(0,0,0)
        s1=vec2(.5,.5)
    
        local vert = {}
        local ind = {}
        local col = {}
        local uv = {}
    
        for a=0+offset,359+offset,step do
            x=math.cos(math.rad(a))
            y=math.sin(math.rad(a))
            p2=vec3(x*radius,0,y*radius)
            s2=vec2(x*.5+.5,y*.5+.5)
            x=math.cos(math.rad(a+step))
            y=math.sin(math.rad(a+step))
            p3=vec3(x*radius,0,y*radius)
            s3=vec2(x*.5+.5,y*.5+.5)
            createSlice(p1,p2,p3,s1,s2,s3,vert,ind,col,uv) 
        end
    
        local r=scene:entity()
        r.model = craft.model()
        r.model.positions=vert
        r.model.indices=ind
        r.model.colors=col
        r.model.uvs=uv
        r.material = craft.material(asset.builtin.Materials.Basic)  
        r.material.map=img
    end
    
    function draw()
        update(DeltaTime)
        scene:draw() 
    end
    
    function update(dt)
        scene:update(dt)
    end
    
    function createSlice(p1,p2,p3,s1,s2,s3,vert,ind,col,uv)
        local c=color(255, 255, 255, 255)    
    
        local s = #vert
        vert[s+1] = p1
        vert[s+2] = p2
        vert[s+3] = p3
    
        col[s+1] = c
        col[s+2] = c
        col[s+3] = c
    
        local si = #ind
        ind[si+1] = s+1
        ind[si+2] = s+2
        ind[si+3] = s+3
        ind[si+4] = s+3
        ind[si+5] = s+2
        ind[si+6] = s+1
    
        uv[s+1] = s1
        uv[s+2] = s2
        uv[s+3] = s3
    end
    
    
  • dave1707dave1707 Mod
    edited March 13 Posts: 8,396

    @Simeon I'll have to compare your code to mine and see why yours works and mine doesn’t. The one difference is you pass the different tables to createSlice whereas my tables are global and I just update them in createSlice. I’ll have to cut the step size to 90 and print out your tables and compare my tables to yours to see if they’re different. Everything else is about the same.

    PS. I made your tables global and didn’t pass them to createSlice and yours still worked. I’ll have to compare dumps of the tables and see where I’m messing up.

  • dave1707dave1707 Mod
    Posts: 8,396

    @Simeon I found my problem. When I compared the tables from your change and my change, I saw that I was creating the indices table wrong. The code looked like how I wanted the table to be, but when I looked at the table, what I got wasn’t what I wanted. Thanks for your code.

Sign In or Register to comment.