Draw Mesh Instanced Example.

This commit is contained in:
jussi
2022-12-09 16:02:28 +02:00
parent 973d902a16
commit e1a85f898e
11 changed files with 282 additions and 16 deletions

View File

@@ -1,3 +1,6 @@
-- Forked from raylib-lua example by TSnake41
-- https://github.com/TSnake41/raylib-lua/blob/master/examples/textures_bunnymark.lua
local MAX_BUNNIES = 100000
-- This is the maximum amount of elements (quads) per batch
@@ -39,8 +42,6 @@ function Bunny:update()
end
end
-- Init
function init()
RL_SetWindowState( FLAG_VSYNC_HINT )
RL_SetWindowSize( { screenWidth, screenHeight } )
@@ -50,8 +51,6 @@ function init()
texSize = RL_GetTextureSize( texBunny )
end
-- Update
function process( delta )
if RL_IsMouseButtonDown( 0 ) then
-- Create more bunnies
@@ -59,7 +58,7 @@ function process( delta )
if #bunnies < MAX_BUNNIES then
local speed = { math.random( -250, 250 ) / 60, math.random( -250, 250 ) / 60 }
local color = { math.random( 50, 240 ), math.random( 80, 240 ), math.random( 100, 240 ), 255 }
table.insert( bunnies, Bunny:new( RL_GetMousePosition(), speed, color) )
table.insert( bunnies, Bunny:new( RL_GetMousePosition(), speed, color ) )
end
end
end
@@ -69,8 +68,6 @@ function process( delta )
end
end
-- Draw
function draw()
RL_ClearBackground( RAYWHITE )

View File

@@ -0,0 +1,112 @@
--[[
This example is translated from "raylib [shaders] example - Mesh instancing"
-- https://github.com/raysan5/raylib/blob/master/examples/shaders/shaders_mesh_instancing.c
Contributed by @seanpringle
Reviewed by Max (@moliad) and Ramon Santamaria (@raysan5)
Modified by Jussi Viitala (@nullstare) for ReiLua style.
]]
local MAX_INSTANCES = 10000
local cube
local transforms = {}
local camera
local shader
local matInstances
local matDefault
function init()
local monitor = 0
local mPos = RL_GetMonitorPosition( monitor )
local mSize = RL_GetMonitorSize( monitor )
local winSize = RL_GetWindowSize()
-- local winSize = { 1920, 1080 }
RL_SetWindowState( FLAG_WINDOW_RESIZABLE )
RL_SetWindowSize( winSize )
RL_SetWindowPosition( { mPos[1] + mSize[1] / 2 - winSize[1] / 2, mPos[2] + mSize[2] / 2 - winSize[2] / 2 } )
RL_SetWindowTitle( "Instancing" )
RL_SetWindowState( FLAG_VSYNC_HINT )
-- Define the camera to look into our 3d world
camera = RL_CreateCamera3D()
RL_SetCamera3DPosition( camera, { -125.0, 125.0, -125.0 } )
RL_SetCamera3DTarget( camera, { 0, 0, 0 } )
RL_SetCamera3DUp( camera, { 0, 1, 0 } )
RL_SetCamera3DFovy( camera, 45 )
RL_SetCameraMode( camera, CAMERA_ORBITAL )
-- Define mesh to be instanced
cube = RL_GenMeshCube( { 1, 1, 1 } )
-- Translate and rotate cubes randomly
for i = 1, MAX_INSTANCES do
local translation = RL_MatrixTranslate( { math.random( -50, 50 ), math.random( -50, 50 ), math.random( -50, 50 ) } )
local axis = RL_Vector3Normalize( { math.random( 0, 360 ), math.random( 0, 360 ), math.random( 0, 360 ) } )
local angle = math.rad( math.random( 0, 10 ) )
local rotation = RL_MatrixRotate( axis, angle )
table.insert( transforms, RL_MatrixMultiply( rotation, translation ) )
end
-- Load lighting shader
shader = RL_LoadShader( RL_GetBasePath().."../resources/shaders/glsl330/lighting_instancing.vs",
RL_GetBasePath().."../resources/shaders/glsl330/lighting.fs" )
-- Get shader locations
local mvpLoc = RL_GetShaderLocation( shader, "mvp" )
local viewPosLoc = RL_GetShaderLocation( shader, "viewPos" )
local instanceTransformLoc = RL_GetShaderLocationAttrib( shader, "instanceTransform" )
RL_SetShaderLocationIndex( shader, SHADER_LOC_MATRIX_MVP, mvpLoc )
RL_SetShaderLocationIndex( shader, SHADER_LOC_VECTOR_VIEW, viewPosLoc )
RL_SetShaderLocationIndex( shader, SHADER_LOC_MATRIX_MODEL, instanceTransformLoc )
-- Set shader value: ambient light level
local ambientLoc = RL_GetShaderLocation( shader, "ambient" )
RL_SetShaderValue( shader, ambientLoc, { 0.2, 0.2, 0.2, 0.1 }, SHADER_UNIFORM_VEC4 )
-- Create one light
RL_CreateLight( LIGHT_DIRECTIONAL, { 50.0, 50.0, 0.0 }, RL_Vector3Zero(), WHITE, shader )
-- NOTE: We are assigning the intancing shader to material.shader
-- to be used on mesh drawing with DrawMeshInstanced()
matInstances = RL_LoadMaterialDefault()
RL_SetMaterialShader( matInstances, shader )
RL_SetMaterialColor( matInstances, MATERIAL_MAP_DIFFUSE, RED )
-- Load default material (using raylib intenral default shader) for non-instanced mesh drawing
-- WARNING: Default shader enables vertex color attribute BUT GenMeshCube() does not generate vertex colors, so,
-- when drawing the color attribute is disabled and a default color value is provided as input for thevertex attribute
matDefault = RL_LoadMaterialDefault()
RL_SetMaterialColor( matDefault, MATERIAL_MAP_DIFFUSE, BLUE )
end
function process( delta )
RL_UpdateCamera3D( camera )
-- Update the light shader with the camera view position
local loc = RL_GetShaderLocationIndex( shader, SHADER_LOC_VECTOR_VIEW )
RL_SetShaderValue( shader, loc, RL_GetCamera3DPosition( camera ), SHADER_UNIFORM_VEC3 )
end
function draw()
RL_ClearBackground( DARKBLUE )
RL_BeginMode3D( camera )
-- Draw cube mesh with default material (BLUE)
RL_DrawMesh( cube, matDefault, RL_MatrixTranslate( { -10.0, 0.0, 0.0 } ) )
-- Draw meshes instanced using material containing instancing shader (RED + lighting),
-- transforms[] for the instances should be provided, they are dynamically
-- updated in GPU every frame, so we can animate the different mesh instances
RL_DrawMeshInstanced( cube, matInstances, transforms, MAX_INSTANCES )
-- Draw cube mesh with default material (BLUE)
RL_DrawMesh( cube, matDefault, RL_MatrixTranslate( { 10.0, 0.0, 0.0 } ) )
RL_EndMode3D()
RL_DrawFPS( { 10, 10 } )
end

View File

@@ -45,7 +45,7 @@ Gui = {
padding = 2,
spacing = 4,
scrollbarWidth = 8,
scrollAmount = 10,
scrollAmount = 20,
heldCallback = nil,

View File

@@ -0,0 +1,82 @@
#version 330
// Input vertex attributes (from vertex shader)
in vec3 fragPosition;
in vec2 fragTexCoord;
//in vec4 fragColor;
in vec3 fragNormal;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
// NOTE: Add here your custom variables
#define MAX_LIGHTS 4
#define LIGHT_DIRECTIONAL 0
#define LIGHT_POINT 1
struct MaterialProperty {
vec3 color;
int useSampler;
sampler2D sampler;
};
struct Light {
int enabled;
int type;
vec3 position;
vec3 target;
vec4 color;
};
// Input lighting values
uniform Light lights[MAX_LIGHTS];
uniform vec4 ambient;
uniform vec3 viewPos;
void main()
{
// Texel color fetching from texture sampler
vec4 texelColor = texture(texture0, fragTexCoord);
vec3 lightDot = vec3(0.0);
vec3 normal = normalize(fragNormal);
vec3 viewD = normalize(viewPos - fragPosition);
vec3 specular = vec3(0.0);
// NOTE: Implement here your fragment shader code
for (int i = 0; i < MAX_LIGHTS; i++)
{
if (lights[i].enabled == 1)
{
vec3 light = vec3(0.0);
if (lights[i].type == LIGHT_DIRECTIONAL)
{
light = -normalize(lights[i].target - lights[i].position);
}
if (lights[i].type == LIGHT_POINT)
{
light = normalize(lights[i].position - fragPosition);
}
float NdotL = max(dot(normal, light), 0.0);
lightDot += lights[i].color.rgb*NdotL;
float specCo = 0.0;
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewD, reflect(-(light), normal))), 16.0); // 16 refers to shine
specular += specCo;
}
}
finalColor = (texelColor*((colDiffuse + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
finalColor += texelColor*(ambient/10.0)*colDiffuse;
// Gamma correction
finalColor = pow(finalColor, vec4(1.0/2.2));
}

View File

@@ -0,0 +1,36 @@
#version 330
// Input vertex attributes
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec3 vertexNormal;
//in vec4 vertexColor; // Not required
in mat4 instanceTransform;
// Input uniform values
uniform mat4 mvp;
uniform mat4 matNormal;
// Output vertex attributes (to fragment shader)
out vec3 fragPosition;
out vec2 fragTexCoord;
out vec4 fragColor;
out vec3 fragNormal;
// NOTE: Add here your custom variables
void main()
{
// Compute MVP for current instance
mat4 mvpi = mvp*instanceTransform;
// Send vertex attributes to fragment shader
fragPosition = vec3(mvpi*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord;
//fragColor = vertexColor;
fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
// Calculate final vertex position
gl_Position = mvpi*vec4(vertexPosition, 1.0);
}