Coder Social home page Coder Social logo

tezcatengine-tiny's Introduction

TezcatEngine-Tiny

引擎二周目进行中

示例 示例

Update

  • 正在重构资源加载和管理方式(Refactoring resoure loader and managers)
  • 可以加载和显示Shader数组对象了!(Can load and display Shader array objects in Editor!)
  • 约束回归!在所有Uniform对象里设置约束信息以显示在Editor中.(Constraint return! Sets Uniform objects constraint information in ShaderFile to display in Editor)
struct MatPBR_Test
{
    //Type(EditorName, Range)
    [Editor(Albedo, Color)]
    float3 albedo;
    [Editor(Metallic, Range(0, 1))]
    float metallic;
    [Editor(Roughness, Range(0, 1))]
    float roughness;
    [Editor(AO,Range(0, 1))]
    float ao;
};

依赖库版本(Libs Version)

  • C++20(v143)
  • Windows sdk 10.0.22000.0
  • IDE VS2022

To Do

Engine

  • Basic PBR
  • Octree
  • Commad Based Rendering
  • Basic GL Shader Parser
  • Basic ShadowMap
  • Basic Memory Manager
  • Basic Multi-Thread Engine
  • Basic Resource Manager
  • Camera Culling
  • Multi-Light Support
  • Model Load Support
  • Transparent Sort
  • Multi-Thread Rendering(Vulkan)

Editor

  • Basic Shader Editor
  • Basic Lighting Manager
  • Basic Memory Viewer
  • Basic Log Viewer
  • Basic Texture2D Viewer
  • Runtime Shader Rebuild
  • Basic Resource Explorer
  • Node Based Shader Editor

编辑器(Editor)

现在可以在菜单里面切换两个场景

Now you can switch scenes in the menu

着色器编辑器(Shader Editor)

双击资源管理器里的shader文件打开内置编辑器

Double-click the shader file in Explorer to open the built-in editor

场景总览(Scene Overview)

目前场景总览可以看到所有当前场景中的对象

Now Scene Overview can show all object in current scene, and you can select one of them

对象总览(Object Overview)

目前对象总览可以看到对象上绑定的组件的信息,还可以与其互动

Now Object Overview can show components bind in object when you selected, and you can change them values

热编译着色器(Runtime Rebuild Shader)

可以在运行时重新编译着色器

Now Editor can rebuild shader in runtime.

资源管理器(Resource Browse)

双击图片文件可以打开查看

Double Click image file to open viwer

可以拖拽图片给环境光照贴图

Try Drag image file to envlighting map widget

内存管理(Memory Management)

做了一套简单的基于引用计数的内存管理,还在调试中......

A simple reference counting based memory management, just still debugging......

创建游戏对象(Create GameObjects)

  • 创建相机 Create a Camera
//gameobject will auto load into current scene
auto go = GameObject::create("World1_Camera");
//attach a Camera component
auto camera = go->addComponent<Camera>(true);
camera->setPerspective(60.0f, 0.1f, 2000.0f);
//set culling layer, other layers will not render
camera->setCullLayer(0);
//attach a Transform component
go->addComponent<Transform>();
go->getTransform()->setPosition(glm::vec3(0.0f, 0.0f, 0.0f));
go->getTransform()->setParent(controller_go->getTransform());
  • 创建天空盒 Create a Skybox

    把资源管理器里面的一张方形天空盒直接拖到光照管理器中,记得把相机的ClearOption勾上Skybox

    Drag a png/jpg/hdr image in resource browser to lighting manager window And check camera`s clear option to render skybox

  • 创建一个游戏物体 Create a GameObject

auto wife = GameObject::create("Wife");
wife->addComponent<Transform>();
wife->getTransform()->setPosition(glm::vec3(-960.0f, 0.0f, 0.0f));
wife->getTransform()->setRotation(glm::vec3(0.0f, 90.0f, 0.0f));
wife->getTransform()->setScale(glm::vec3(1920.0f / 2, 1080.0f / 2, 1.0f));
wife->getTransform()->setParent(transform);

//add a MeshRenderer
auto mr2 = wife->addComponent<MeshRenderer>();
mr2->setMesh("Square");

auto wife_material2 = Material::create("Unlit/Texture");
mr2->setMaterial(wife_material2);

auto shader = wife_material2->getShader();

auto my_tex2d_color_index = shader->getUniformIndex("myTexColor2D");
auto tex = Resource::loadOnly<Texture2D>("Image/wife.jpg");
wife_material2->setUniform<UniformTex2D>(my_tex2d_color_index, tex);
  • Load A Model
auto model = Resource::load<Model>("Model/Cerberus_LP.fbx");
model->generate();
  • 创建一个帧缓冲 Create a FrameBuffer
//create a framebuffer named "FB_Viewport" and save in manager
auto frame_buffer = FrameBufferMgr::getInstance()->create("FB_Viewport");

//create a texture2D named "RB_Viewport" and save in manager
Texture2D* tex2d = TextureMgr::getInstance()->create2D("RB_Viewport");
tex2d->setData(Engine::getScreenWidth(), Engine::getScreenHeight()
    , TextureInfo(
        //Buffer Type(FrameBuffer Component)
        TextureAttachPosition::ColorComponent
        //Internal Format
        , TextureChannel::RGBA
        //Format
        , TextureChannel::RGBA
        //Data Type
        , DataType::UByte));

//create a render2D named "DS_Viewport" and save in manager
TextureRender2D* render2d = TextureMgr::getInstance()->createRender2D("DS_Viewport");
render2d->setData(Engine::getScreenWidth(), Engine::getScreenHeight()
    , TextureInfo(TextureAttachPosition::DepthComponent
        , TextureChannel::Depth
        , TextureChannel::Depth
        , DataType::UByte));

//attach textures into framebuffer
frame_buffer->addAttachment(tex2d);
frame_buffer->addAttachment(render2d);
//generate framebuffer
//in multi-thread mode, this method just make a CMD and send it to render-thread
frame_buffer->generate();

//let camera render objects to this framebuffer
camera->setFrameBuffer(frame_buffer);

//also you can find this framebuffer like
fb = FrameBufferMgr::getInstance()->find("FB_World1");

//set nullptr will switch render to mainframe
camera->setFrameBuffer(nullptr);
  • 创建一张贴图(Create a Texture)
//create a texture named "Shadow" and save in manager
mShadwowTexutre = TextureMgr::getInstance()->create2D("Shadow");
mShadwowTexutre->setData(width, height
    , TextureInfo(TextureType::Texture2D
        , TextureAttachPosition::DepthComponent
        , TextureFilter::Nearest
        , TextureFilter::Nearest
        , TextureWrap::Clamp_To_Border
        , TextureWrap::Clamp_To_Border
        , TextureChannel::Depth
        , TextureChannel::Depth
        , DataType::Float32));
mShadwowTexutre->generate();

具体使用方法请看Example.

Please check the Example project to get more infos.

资源管理 Resouce Manage

注意! .exe文件必须和资源文件夹处于同一目录下

Attention! The .exe file must be in the same directory as the resource folder

  1. 继承并实现MyEngineIniter

    Inherit and implement the MyEngineIniter class

    class MyEngineIniter : public EngineIniter
    {
    public:
        MyEngineIniter();
    
        void prepareEngine(Engine* engine) override;
        void prepareResource(Engine* engine) override;
        void prepareGame(Engine* engine) override;
        void initYourShaderParam() override;
    };

    prepareEngine,prepareResource,prepareGame三个方法会按此顺序依次执行

    prepareEngine,prepareResource,prepareGameare invoked in this order

  2. 设置自己的资源文件夹名称,程序名称,屏幕大小

    Set your ResourceFolder Name, ProgramName, ScreenSize

    void MyEngineIniter::prepareEngine(Engine* engine)
    {
        EngineIniter::prepareEngine(engine);
        MyEvent::get()->init(MyEventID::Count);
    
        engine->setEnableMultiThread();
    
        mResourceFolderName = "Resource";
        mGameName = u8"YesIndeed,玩上老头环了!!!!!";
        mWindowWidth = 1920;
        mWindowHeight = 1080;
        mEnableVsync = true;
        this->setGLVersion(3, 3);
    }
  3. 加载资源文件

    Load resource files

    void MyEngineIniter::prepareResource(Engine* engine)
    {
        EngineIniter::prepareResource(engine);
        //设置图片文件夹名称自动加载所有图片文件
        //注意,不同文件夹下面的图片文件也不能重名
        //Set ImageFolder to auto load all images
        //Note that the image files under different folders also must not have the same name
        TextureMgr::getInstance()->loadResource("/Image");
    }
  4. 准备场景

    Prepare Scene

    void MyEngineIniter::prepareGame(Engine* engine)
    {
        EngineIniter::prepareGame(engine);
        ShaderMgr::getInstance()->loadShaderFiles(FileTool::getRootRelativeResDir() + "/Shaders/Tutorial");
    
        auto main_window = new MyMainWindow();
        main_window->open(Graphics::getInstance()->mGUI);
        main_window->init();
    
        SceneMgr::getInstance()->prepareScene(MyMainScene::create("MainScene"));
        SceneMgr::getInstance()->prepareScene(Tutorial01::create("Tutorial01"));
    }

材质结构 Material

目前Shader构建器可以自动解析出所有Uniform变量.

ShaderBuilder can auto scan all GLSL Uniform value except array type.

Tiny的全局变量如下

Tiny Current Global Uniform Values

ShaderName Type Useage
TINY_MatrixP float4x4 P
TINY_MatrixV float4x4 V
TINY_MatrixM float4x4 M
TINY_MatrixVP float4x4 VP
TINY_MatrixMVP float4x4 MVP
TINY_MatrixN float3x3 Model Normal Matrix
TINY_MatrixLightVP float4x4 Light VP Matrix
TINY_CameraWorldPosition float3 Camera World Position
TINY_CameraNearFar float2 Camera NearFar
TINY_Resolution float2 Screen Resolution
TINY_TexSkybox texCube Skybox Texture
TINY_TexDepth tex2D Depth Texture
TINY_TexIrradiance texCube Irradiance Texture
TINY_TexPrefilter texCube Prefilter Texture
TINY_TexBRDFLUT tex2D BRDFLUT Texture
ShaderName Type Useage
TINY_LitDir.direction float3
TINY_LitDir.ambient float3
TINY_LitDir.diffuse float3
TINY_LitDir.specular float3
ShaderName Type Useage
TINY_LitPoint.position float3
TINY_LitPoint.ambient float3
TINY_LitPoint.diffuse float3
TINY_LitPoint.specular float3
TINY_LitPoint.config float3

目前内建材质变量类型有(后续会慢慢添加)

Current Buildin Material Values

TinyType CommonType
UniformI[1-4] int[1-4]
UniformF[1-4] float[1-4]
UniformMat[3-4] glm::mat[3-4]
UniformTex2D Texture2D
UniformTexCube TextureCube

给一个object添加一个材质之后一定要记得添加材质对应的参数,贴图,数值等等

notice! add uniform value to your material for the gameobject.

auto plane_material = Material::create("Standard/Std1");
mr->setMaterial(plane_material);

auto shader = plane_material->getShader();
//use shader to find custom uniform`s index
auto index_diffuse = shader->getUniformIndex("myTexDiffuse2D");
auto index_specular = shader->getUniformIndex("myTexSpecular2D");
auto index_shininess = shader->getUniformIndex("myShininess");

auto tex_diff = Resource::loadOnly<Texture2D>("Image/stone_wall_diff.jpg");
auto tex_spec = Resource::loadOnly<Texture2D>("Image/stone_wall_ao.jpg");

//set value by using uniform index
plane_material->setUniform<UniformTex2D>(index_diffuse, tex_diff);
//or use your uniform`s name
//plane_material->setUniform<UniformTex2D>("myTexDiffuse2D", tex_diff);
plane_material->setUniform<UniformTex2D>(index_specular, tex_spec);
plane_material->setUniform<UniformF1>(index_shininess, 64.0f);

着色器 Shader

现在着色器构建器采用组合头文件的方式来自动生成着色器文件

ShaderBuilder now combine header files to automatically generate a shader file

void EngineIniter::prepareResource(Engine* engine)
{
    ShaderMgr::getInstance()->loadShaderFiles(FileTool::getRootRelativeResDir() + "/Shaders/Standard");
    ShaderMgr::getInstance()->loadShaderFiles(FileTool::getRootRelativeResDir() + "/Shaders/Unlit");
    ShaderMgr::getInstance()->loadShaderFiles(FileTool::getRootRelativeResDir() + "/Shaders/Utility");

    this->createSomeMode();
}

你可以在Include文件夹中建立一些通用头文件,避免在各个着色器文件中重复书写

You can create generic header files in the Include folder to avoid duplicating each shader file

头文件支持重复包含

Header files support repetitive inclusion

着色器文件支持//和/**/两种注释

The shader file supports both // and /**/

file tiny_vs.tyin 
//base
uniform float4x4 TINY_MatrixP;
uniform float4x4 TINY_MatrixV;
uniform float4x4 TINY_MatrixM;
uniform float4x4 TINY_MatrixMV;
uniform float4x4 TINY_MatrixVP;
uniform float4x4 TINY_MatrixMVP;
uniform float3x3 TINY_MatrixN;

//light
uniform float4x4 TINY_MatrixLightVP;

file any shader you need
#TINY_VS_BEGIN
{
    #include "../Include/tiny_vs.tyin"
    ..........
}

管线位置 Pipeline Position

"Background"    Forward::Background
"Opaque"        Forward::Geometry
"Alpha"         Forward::AlphaTest
"OpaqueLast"    Forward::OpaqueLast
"Transparent"   Forward::Transparent
"Overlay"       Forward::Overlay

混合 Blend

混合参数 BlendFunc

"0"         ZERO
"1"         ONE
"Src"       SRC_COLOR
"1-Src"     ONE_MINUS_SRC_COLOR
"Tar"       DST_COLOR
"1-Tar"     ONE_MINUS_DST_COLOR
"SrcA"      SRC_ALPHA
"1-SrcA"    ONE_MINUS_SRC_ALPHA
"TarA"      DST_ALPHA
"1-TarA"    ONE_MINUS_DST_ALPHA
"Const"     CONSTANT_COLOR
"1-Const"   ONE_MINUS_CONSTANT_COLOR
"ConstA"    CONSTANT_ALPHA
"1-ConstA"  ONE_MINUS_CONSTANT_ALPHA

启用混合 EnableBlend

bool Blend = true;
str BlendSrc = 1;
str BlendTar = 1-TarA;

关闭混合 DisableBlend

bool Blend = false;

表面剔除 Cullface

剔除参数 Cullface

"Off"       Disable
"Front"     FRONT
"Back"      BACK
"All"       FRONT_AND_BACK

启用剔除 EnableCullface

str CullFace = Back;

关闭剔除

str CullFace = Off;

深度测试 DepthTest

测试参数

"Off"               Off
"Always"            Always
"Never"             Never
"Less"              Less
"LessEqual"         LessEqual
"Greater"           Greater
"GreaterEqual"      GreaterEqual
"Equal"             Equal
"NotEqual"          NotEqual

启用 Enable

str DepthTest = Less;

关闭 Disable

str DepthTest = Off;

深度写入 ZWrite

只有在深度测试启用时才有用 Only work when DepthTest is Enabled

启用 Enable

bool ZWrite = true;

关闭 Disable

bool ZWrite = false;

默认值 DefaultValue

除了[int Version]为必须值,其他值均为拥有默认值的可选参数

The[int Version] should be setted.The other params You can set as your wish.

#TINY_HEAD_BEGIN
{
    str Name = Standard/Std1;
}
#TINY_HEAD_END

#TINY_PASS_BEGIN
{
    #TINY_CFG_BEGIN
    {
        str Name = Standard/Std1;
        int Version = 330;
        int OrderID = 50;
        str Queue = Opaque;
        str DepthTest = Less;
        bool ZWrite = true;
        str CullFace = Back;
        str LightMode = Forward;
    }
    #TINY_CFG_END

    #TINY_VA_BEGIN
    {
        inout TINY_VS2FS
        {
            float4 color;
            float2 uv;
            float3 normal;
            float3 worldPosition;
            float4 lightPosition;
        };
    }
    #TINY_VA_END

    #TINY_VS_BEGIN
    {
        #include "../Include/tiny_vs.tyin"

        layout (location = 0) in float3 aPos;
        layout (location = 1) in float3 aNormal;
        layout (location = 2) in float2 aUV;
        layout (location = 3) in float4 aColor;

        out float4 myColor;
        out float2 myUV;
        out float3 myNormal;
        out float3 myWorldPosition;
        out float4 myLightPosition;

        out VS2FS
        {
            float4 color;
            float2 uv;
            float3 normal;
            float3 worldPosition;
            float4 lightPosition;
        } TINY_VS2FS;

        void main()
        {
            float4 position =  float4(aPos, 1.0);
            gl_Position = TINY_MatrixP * TINY_MatrixV * TINY_MatrixM * position;

            myColor = aColor;
            myUV = aUV;
            myNormal = TINY_MatrixN * aNormal;
            myWorldPosition = float3(TINY_MatrixM * position);
            myLightPosition = TINY_MatrixLightVP * float4(myWorldPosition, 1.0f);
        }
    }
    #TINY_VS_END

    #TINY_FS_BEGIN
    {
        #include "../Include/tiny_fs.tyin"

        in float4 myColor;
        in float2 myUV;
        in float3 myNormal;
        in float3 myWorldPosition;
        in float4 myLightPosition;

        in VS2FS
        {
            float4 color;
            float2 uv;
            float3 normal;
            float3 worldPosition;
            float4 lightPosition;
        } TINY_VS2FS;
        
        out float4 myFinalColor;

        uniform tex2D myTexDiffuse2D;
        uniform tex2D myTexSpecular2D;
        uniform float myShininess;

        float4 reflection(float3 I)
        {
            //float3 I = normalize(myWorldPosition - TINY_CameraWorldPosition);
            float3 R = reflect(I, normalize(myNormal));
            return float4(texture(TINY_TexSkybox, R).rgb, 1.0);
        }

        float4 refraction(float3 I)
        {
            float ratio = 1.00 / 1.52;
            //float3 I = normalize(myWorldPosition - TINY_CameraWorldPosition);
            float3 R = refract(I, normalize(myNormal), ratio);
            return float4(texture(TINY_TexSkybox, R).rgb, 1.0);
        }

        float3 calcDirectionLight(LightDirection lit, float3 viewDir, float3 normal)
        {
            float3 light_dir = normalize(-lit.direction);
            float3 half_dir = normalize(viewDir + light_dir); 

            float NdL = dot(normal, light_dir);
            float NdH = dot(normal, half_dir);

            float diff = max(NdL, 0.0);
            float spec = pow(max(NdH, 0.0), myShininess);

            float3 ambient = lit.ambient * texture(myTexDiffuse2D, myUV).rgb;
            float3 diffuse = lit.diffuse * diff * texture(myTexDiffuse2D, myUV).rgb;
            float3 specular = lit.specular * spec * texture(myTexSpecular2D, myUV).rrr;

            // shadow
            float shadow = calcShadow(myLightPosition, normal, light_dir, TINY_TexDepth);
            float3 lighting = (ambient + (1.0 - shadow) * (diffuse + specular));

            return lighting;
        }

        void main()
        {
            float3 normal = normalize(myNormal);
            float3 view_dir = normalize(TINY_CameraWorldPosition - myWorldPosition);
            myFinalColor = float4(calcDirectionLight(TINY_LitDir, view_dir, normal), 1.0f);
        }
    }
    #TINY_FS_END
}
#TINY_PASS_END

tezcatengine-tiny's People

Contributors

tzkt623 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.