billboarding fixed

main
Dominik Madarász 2023-11-06 09:30:19 +01:00
parent 4d00cce39d
commit 62390a3e4b
7 changed files with 133 additions and 124 deletions

View File

@ -1,118 +1,24 @@
#include "v4k.h"
/*
float* billboard(mat44 modelview, bool billboard_x, bool billboard_y, bool billboard_z) {
if( billboard_x ) { modelview[0*4+0] = 1; modelview[0*4+1] = 0; modelview[0*4+2] = 0; }
if( billboard_y ) { modelview[1*4+0] = 0; modelview[1*4+1] = 1; modelview[1*4+2] = 0; }
if( billboard_z ) { modelview[2*4+0] = 0; modelview[2*4+1] = 0; modelview[2*4+2] = 1; }
return modelview;
}
*/
const char *billboard_name(bool billboard_x, bool billboard_y, bool billboard_z) {
// Spherical billboarding makes the object to always face the camera no matter the position of the camera on an imaginary sphere.
// Cylindrical billboarding makes the object to face the camera only when the camera looks at the right or at the left.
return
billboard_x && billboard_y && billboard_z ? "(spherical billboard)" : billboard_x && billboard_z ? "(cylindrical billboard)" : "";
}
const char *shader_projected_vs =
"#version 150\n"
"in vec3 att_position;\n"
"in vec2 att_uv;\n"
"out vec2 uv;\n"
"uniform mat4 u_projection;\n"
"uniform mat4 u_modelview;\n"
//"uniform mat4 u_billboard;\n"
"uniform float u_aspect;\n"
"void main() {\n"
" gl_Position = u_projection * u_modelview * vec4(att_position, 1.0f);\n"
" uv = vec2(att_uv.x, 1.0 - att_uv.y);\n"
"return;"
" // billboarding keeping scale (see: https://stackoverflow.com/questions/15937842/glsl-billboard-shader-keep-the-scaling)\n"
" vec2 scale = vec2( length(u_modelview[0]) / u_aspect, length(u_modelview[1]) );\n"
" vec4 billboard = u_modelview * vec4(vec3(0.0), 1.0);\n"
" gl_Position = u_projection * billboard + vec4(scale * att_position.xy, 0.0, 0.0);\n"
""
"}\n";
const char *shader_textured_fs =
"#version 150\n"
"in vec2 uv;\n"
"out vec4 out_color;\n"
"uniform sampler2D u_texture;\n"
"void main() {\n"
" out_color = texture(u_texture, uv);\n"
"}\n";
int main() {
// create the window
window_create( 0.5f, 0 );
window_color( RGB3(40,40,50) );
// enable some gl stuff. needed?
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
// compile shaders
GLuint program = // shader(shader_projected_vs, shader_textured_fs);
shader(shader_projected_vs, shader_textured_fs, "att_position,att_uv", "out_color", NULL );
// a test cube: 3POS + 2UV
GLfloat vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
typedef struct MyVertex {
vec3 pos;
vec2 texcoord;
} MyVertex;
GLuint indices[] = {
0,2,1,3,5,4,6,7,8,9,10,11,12,13,14,15,16,17,18,20,19,21,23,22,24,25,26,27,28,29,30,32,31,33,35,34
};
mesh_t cube = mesh();
mesh_update(&cube, "p3 t2", 0,36,vertices, 36,indices, 0);
mat44 cube_transform; id44(cube_transform);
model_t cube = model("Alien.fbx", 0);
// create (fps) camera
camera_t cam = camera();
@ -122,10 +28,6 @@ int main() {
if (input(KEY_ESC))
break;
// setup projection
mat44 proj;
perspective44(proj, 45, window_aspect(), 0.1f, 100.0f);
// fps camera
bool active = ui_hover() || ui_active() || gizmo_active() ? false : input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R);
window_cursor( !active );
@ -141,15 +43,9 @@ int main() {
static int billboard_x = 0; if( input_down(KEY_1) ) billboard_x ^= 1;
static int billboard_y = 0; if( input_down(KEY_2) ) billboard_y ^= 1;
static int billboard_z = 0; if( input_down(KEY_3) ) billboard_z ^= 1;
cube.billboard = (billboard_x << 2)|(billboard_y << 1)|(billboard_z << 0);
// draw cube
mat44 modelview; multiply44x2(modelview, cam.view, cube_transform);
shader_bind(program);
shader_mat44("u_projection", proj);
shader_mat44("u_modelview", billboard(modelview, billboard_x,billboard_y,billboard_z) );
shader_texture("u_texture", texture_checker());
mesh_render(&cube);
model_render(cube, cam.proj, cam.view, cube.pivot, 0);
window_title(va("billboard_x: %s, billboard_y: %s, billboard_z: %s %s", billboard_x ? "on":"off", billboard_y ? "on":"off", billboard_z ? "on":"off", billboard_name(billboard_x,billboard_y,billboard_z)));
}

View File

@ -5,7 +5,8 @@ uniform mat3x4 vsBoneMatrix[MAX_BONES];
uniform bool SKINNED = false;
uniform mat4 M; // RIM
uniform mat4 VP;
uniform mat4 P;
uniform int u_billboard;
#if 0
// Fetch blend channels from all attached blend deformers.
@ -110,15 +111,36 @@ void main() {
//@todo: tangents
}
// vec3 tangent = att_tangent.xyz;
// vec3 bitangent = cross(att_normal, att_tangent.xyz) * att_tangent.w;
// vec3 tangent = att_tangent.xyz;
// vec3 bitangent = cross(att_normal, att_tangent.xyz) * att_tangent.w;
mat4 modelView = view * att_instanced_matrix;
if(u_billboard > 0) {
float sx = length(vec3(modelView[0][0], modelView[1][0], modelView[2][0]));
float sy = length(vec3(modelView[0][1], modelView[1][1], modelView[2][1]));
float sz = length(vec3(modelView[0][2], modelView[1][2], modelView[2][2]));
v_normal_ws = normalize(vec3(model * vec4(v_normal, 0.))); // normal to world/model space
v_normal = normalize(v_normal);
v_position_ws = (att_instanced_matrix * vec4( objPos, 1.0 )).xyz;
v_position = att_position;
v_texcoord = att_texcoord;
v_color = att_color;
gl_Position = VP * att_instanced_matrix * vec4( objPos, 1.0 );
do_shadow();
if((u_billboard & 4) != 0) {
modelView[0][0] = sx;
modelView[0][1] = 0.0;
modelView[0][2] = 0.0;
}
if((u_billboard & 2) != 0) {
modelView[1][0] = 0.0;
modelView[1][1] = sy;
modelView[1][2] = 0.0;
}
if((u_billboard & 1) != 0) {
modelView[2][0] = 0.0;
modelView[2][1] = 0.0;
modelView[2][2] = sz;
}
}
v_normal_ws = normalize(vec3(model * vec4(v_normal, 0.))); // normal to world/model space
v_normal = normalize(v_normal);
v_position_ws = (att_instanced_matrix * vec4( objPos, 1.0 )).xyz;
v_position = att_position;
v_texcoord = att_texcoord;
v_color = att_color;
gl_Position = P * modelView * vec4( objPos, 1.0 );
do_shadow();
}

View File

@ -354025,6 +354025,13 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
vec3 dir = norm3(vec3(view[2], view[6], view[10]));
glUniform3fv( loc, 1, &dir.x );
}
if( (loc = glGetUniformLocation(shader, "billboard")) >= 0 ) {
glUniform1i( loc, m.billboard );
}
else
if( (loc = glGetUniformLocation(shader, "u_billboard")) >= 0 ) {
glUniform1i( loc, m.billboard );
}
#if 0
// @todo: mat44 projview (useful?)
#endif
@ -354469,6 +354476,7 @@ model_t model_from_mem(const void *mem, int len, int flags) {
"att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor",
va("SHADING_PHONG,%s", (flags&MODEL_RIMLIGHT)?"RIM":""));
// }
// ASSERT(shaderprog > 0);
iqm_t *q = CALLOC(1, sizeof(iqm_t));
m.program = shaderprog;

View File

@ -3947,6 +3947,13 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
vec3 dir = norm3(vec3(view[2], view[6], view[10]));
glUniform3fv( loc, 1, &dir.x );
}
if( (loc = glGetUniformLocation(shader, "billboard")) >= 0 ) {
glUniform1i( loc, m.billboard );
}
else
if( (loc = glGetUniformLocation(shader, "u_billboard")) >= 0 ) {
glUniform1i( loc, m.billboard );
}
#if 0
// @todo: mat44 projview (useful?)
#endif
@ -4391,6 +4398,7 @@ model_t model_from_mem(const void *mem, int len, int flags) {
"att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor",
va("SHADING_PHONG,%s", (flags&MODEL_RIMLIGHT)?"RIM":""));
// }
// ASSERT(shaderprog > 0);
iqm_t *q = CALLOC(1, sizeof(iqm_t));
m.program = shaderprog;

View File

@ -20111,6 +20111,13 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
vec3 dir = norm3(vec3(view[2], view[6], view[10]));
glUniform3fv( loc, 1, &dir.x );
}
if( (loc = glGetUniformLocation(shader, "billboard")) >= 0 ) {
glUniform1i( loc, m.billboard );
}
else
if( (loc = glGetUniformLocation(shader, "u_billboard")) >= 0 ) {
glUniform1i( loc, m.billboard );
}
#if 0
// @todo: mat44 projview (useful?)
#endif
@ -20555,6 +20562,7 @@ model_t model_from_mem(const void *mem, int len, int flags) {
"att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor",
va("SHADING_PHONG,%s", (flags&MODEL_RIMLIGHT)?"RIM":""));
// }
// ASSERT(shaderprog > 0);
iqm_t *q = CALLOC(1, sizeof(iqm_t));
m.program = shaderprog;

View File

@ -0,0 +1,67 @@
local syntax = require "core.syntax"
syntax.add {
files = { "%.fx$", "%.glsl$", "%.fs$", "%.vs$", "%.gs$" },
comment = "//",
patterns = {
{ pattern = "//.-\n", type = "comment" },
{ pattern = { "/%*", "%*/" }, type = "comment" },
{ pattern = { "#", "[^\\]\n" }, type = "comment" },
{ pattern = { '"', '"', '\\' }, type = "string" },
{ pattern = { "'", "'", '\\' }, type = "string" },
{ pattern = "-?0x%x+", type = "number" },
{ pattern = "-?%d+[%d%.eE]*f?", type = "number" },
{ pattern = "-?%.?%d+f?", type = "number" },
{ pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" },
{ pattern = "[%a_][%w_]*%f[(]", type = "function" },
{ pattern = "[%a_][%w_]*", type = "symbol" },
},
symbols = {
["if"] = "keyword",
["then"] = "keyword",
["else"] = "keyword",
["elseif"] = "keyword",
["do"] = "keyword",
["while"] = "keyword",
["for"] = "keyword",
["break"] = "keyword",
["continue"] = "keyword",
["return"] = "keyword",
["goto"] = "keyword",
["struct"] = "keyword",
["union"] = "keyword",
["typedef"] = "keyword",
["enum"] = "keyword",
["extern"] = "keyword",
["static"] = "keyword",
["volatile"] = "keyword",
["const"] = "keyword",
["inline"] = "keyword",
["switch"] = "keyword",
["case"] = "keyword",
["default"] = "keyword",
["auto"] = "keyword",
["const"] = "keyword",
["void"] = "keyword",
["uniform"] = "keyword",
["in"] = "keyword",
["out"] = "keyword",
["inout"] = "keyword",
["int"] = "keyword2",
["short"] = "keyword2",
["long"] = "keyword2",
["float"] = "keyword2",
["double"] = "keyword2",
["char"] = "keyword2",
["unsigned"] = "keyword2",
["bool"] = "keyword2",
["vec2"] = "keyword2",
["vec3"] = "keyword2",
["vec4"] = "keyword2",
["sampler2D"]= "keyword2",
["true"] = "literal",
["false"] = "literal",
["NULL"] = "literal",
},
}

View File

@ -576,7 +576,7 @@ void editor_frame( void (*game)(unsigned, float, double) ) {
game(editor.frame, editor.dt, editor.t);
// timing
editor.dt = clampf(window_delta(), 0, 1/60.f) * !window_has_pause() * editor.slomo;
editor.dt = window_delta() /*clampf(window_delta(), 0, 1/60.f)*/ * !window_has_pause() * editor.slomo;
editor.t += editor.dt;
editor.frame += !window_has_pause();
editor.frame += !editor.frame;