g3n / engine

Go 3D Game Engine (http://g3n.rocks)
https://discord.gg/NfaeVr8zDg
BSD 2-Clause "Simplified" License
2.79k stars 295 forks source link

postprocessing idea #212

Closed uzudil closed 2 years ago

uzudil commented 3 years ago

Hello,

This is a cleaned up version of a previous PR idea: for my project, I'd like to use an old-schooly-pixelated effect by rendering into a texture via an opengl framebuffer. Please let me know if you're planning something like this, or if this PR could be improved in any way.

Here is the example code using the effect:

package main

import (
    "time"

    "github.com/g3n/engine/app"
    "github.com/g3n/engine/camera"
    "github.com/g3n/engine/core"
    "github.com/g3n/engine/geometry"
    "github.com/g3n/engine/gls"
    "github.com/g3n/engine/graphic"
    "github.com/g3n/engine/gui"
    "github.com/g3n/engine/light"
    "github.com/g3n/engine/material"
    "github.com/g3n/engine/math32"
    "github.com/g3n/engine/renderer"
    "github.com/g3n/engine/util/helper"
    "github.com/g3n/engine/window"
)

const (
    Width              = 160
    Height             = 100
    screenShaderVertex = `
        #version 330 core
        layout (location = 0) in vec3 aPos;
        layout (location = 1) in vec3 aColor;
        layout (location = 2) in vec2 aTexCoords;

        out vec2 TexCoords;

        void main()
        {
            gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); 
            TexCoords = aTexCoords;
        } 
    ` + "\x00"

    screenShaderFrag = `
        #version 330 core
        out vec4 FragColor;

        in vec2 TexCoords;

        uniform sampler2D screenTexture;

        void main()
        { 
            if(int(gl_FragCoord.y) % 2 == 0) {
                FragColor = texture(screenTexture, TexCoords);
            } else {
                FragColor = vec4(vec3(0), 1.0);
            }
        }   
    ` + "\x00"
)

func main() {

    // Create application and scene
    a := app.App()
    scene := core.NewNode()

    // Set the scene to be managed by the gui manager
    gui.Manager().Set(scene)

    // Create perspective camera
    cam := camera.New(1)
    cam.SetPosition(0, 0, 3)
    scene.Add(cam)

    // Set up orbit control for the camera
    camera.NewOrbitControl(cam)

    // Set up callback to update viewport and camera aspect ratio when the window is resized
    onResize := func(evname string, ev interface{}) {
        // Get framebuffer size and update viewport accordingly
        width, height := a.GetSize()
        a.Gls().Viewport(0, 0, int32(width), int32(height))
        // Update the camera's aspect ratio
        cam.SetAspect(float32(width) / float32(height))
    }
    a.Subscribe(window.OnWindowSize, onResize)
    onResize("", nil)

    // Create a blue box and add it to the scene
    geom := geometry.NewBox(1, 1, 1)
    mat := material.NewStandard(math32.NewColor("DarkBlue"))
    mesh := graphic.NewMesh(geom, mat)
    scene.Add(mesh)

    // Create and add lights to the scene
    scene.Add(light.NewAmbient(&math32.Color{1.0, 1.0, 1.0}, 0.8))
    pointLight := light.NewPoint(&math32.Color{1, 1, 1}, 5.0)
    pointLight.SetPosition(1, 0, 2)
    scene.Add(pointLight)

    // Create and add an axis helper to the scene
    scene.Add(helper.NewAxes(0.5))

    // Set background color to gray
    a.Gls().ClearColor(0.5, 0.5, 0.5, 1.0)

    pp := a.Renderer().CreatePostprocessor(Width, Height, screenShaderVertex, screenShaderFrag)

    // Run the application
    a.Run(func(renderer *renderer.Renderer, deltaTime time.Duration) {
        fbwidth, fbheight := a.IWindow.GetFramebufferSize()
        pp.Render(fbwidth, fbheight, func() {
            a.Gls().Clear(gls.DEPTH_BUFFER_BIT | gls.STENCIL_BUFFER_BIT | gls.COLOR_BUFFER_BIT)
            renderer.Render(scene, cam)
        })
    })
}

Thanks!

danaugrs commented 2 years ago

Thanks @uzudil! If you (or anyone) can fix the conflicts and put the postprocessor in a separate file I'll merge this.

uzudil commented 2 years ago

Great thanks, I'll take a look at this today.

--Gabor

On Thu, Nov 4, 2021, 5:45 AM Daniel Salvadori @.***> wrote:

Thanks @uzudil https://github.com/uzudil! If you (or anyone) can fix the conflicts and put the postprocessor in a separate file I'll merge this.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/g3n/engine/pull/212#issuecomment-960838671, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEFIU3JILRH5DJQ73OT6KLUKJ557ANCNFSM4U6QPTKA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

uzudil commented 2 years ago

Done. Please let me know if there are other changes you'd like me to make. Thanks!

uzudil commented 2 years ago

Actually, let me see if I can change the contribution to the correct user in the above merges... Please don't merge this yet.

uzudil commented 2 years ago

Ok ready to merge now. Thanks again!

danaugrs commented 2 years ago

Awesome, thanks!