render: finalize phong shader

main
Dominik Madarász 2023-09-23 22:00:22 +02:00
parent fff4880c4f
commit 9731ca611c
9 changed files with 60 additions and 18 deletions

View File

@ -42,6 +42,9 @@ int main() {
// create point light // create point light
light_t* l = scene_spawn_light(); light_t* l = scene_spawn_light();
light_type(l, LIGHT_SPOT); light_type(l, LIGHT_SPOT);
light_ambient(l, vec3(0.03,0.03,0.06));
light_specular(l, scale3(vec3(1,1.0,0.2), 2.5f));
light_power(l, 56.f);
while(window_swap() && !input(KEY_ESC)) { while(window_swap() && !input(KEY_ESC)) {
// draw environment // draw environment
@ -51,7 +54,7 @@ int main() {
// update video // update video
video_decode( v ); video_decode( v );
// update light position // update light data
light_teleport(l, cam.position); light_teleport(l, cam.position);
light_dir(l, cam.look); light_dir(l, cam.look);

View File

@ -41,6 +41,7 @@ struct light_t {
vec3 ambient; vec3 ambient;
vec3 pos; vec3 pos;
vec3 dir; vec3 dir;
float power;
float innerCone; float innerCone;
float outerCone; float outerCone;
@ -75,8 +76,7 @@ vec3 shading_phong(light_t l) {
float distance = length(toLight); float distance = length(toLight);
attenuation = 1.0 / (l.constant + l.linear * distance + l.quadratic * (distance * distance)); attenuation = 1.0 / (l.constant + l.linear * distance + l.quadratic * (distance * distance));
// Calculate spotlight effect float angle = dot(l.dir, -lightDir);
float angle = dot(l.dir, normalize(-lightDir));
if (angle > l.outerCone) { if (angle > l.outerCone) {
float intensity = (angle-l.outerCone)/(l.innerCone-l.outerCone); float intensity = (angle-l.outerCone)/(l.innerCone-l.outerCone);
attenuation *= clamp(intensity, 0.0, 1.0); attenuation *= clamp(intensity, 0.0, 1.0);
@ -85,10 +85,17 @@ vec3 shading_phong(light_t l) {
} }
} }
float diffuse = max(dot(v_normal, lightDir), 0.0); // fast-rejection for faraway vertices
if (attenuation <= 0.01) {
return vec3(0,0,0);
}
vec3 n = normalize(v_normal_ws);
float diffuse = max(dot(n, lightDir), 0.0);
vec3 halfVec = normalize(lightDir + u_cam_dir); vec3 halfVec = normalize(lightDir + u_cam_dir);
float specular = pow(max(dot(v_normal, halfVec), 0.0), 32); float specular = pow(max(dot(n, halfVec), 0.0), l.power);
return (attenuation*l.ambient + diffuse*attenuation*l.diffuse + specular*attenuation*l.specular); return (attenuation*l.ambient + diffuse*attenuation*l.diffuse + specular*attenuation*l.specular);
} }
@ -107,7 +114,7 @@ vec3 lighting() {
} }
void main() { void main() {
vec3 n = /*normalize*/(v_normal); vec3 n = normalize(v_normal_ws);
vec4 lit = vec4(1.0, 1.0, 1.0, 1.0); vec4 lit = vec4(1.0, 1.0, 1.0, 1.0);
// SH lighting // SH lighting

View File

@ -2706,6 +2706,7 @@ vec3 pos, dir;
struct { struct {
float constant, linear, quadratic; float constant, linear, quadratic;
} falloff; } falloff;
float specularPower;
float innerCone, outerCone; float innerCone, outerCone;
bool cached; bool cached;
} light_t; } light_t;
@ -2716,6 +2717,7 @@ bool cached;
void light_ambient(light_t* l, vec3 color); void light_ambient(light_t* l, vec3 color);
void light_teleport(light_t* l, vec3 pos); void light_teleport(light_t* l, vec3 pos);
void light_dir(light_t* l, vec3 dir); void light_dir(light_t* l, vec3 dir);
void light_power(light_t* l, float power);
void light_falloff(light_t* l, float constant, float linear, float quadratic); void light_falloff(light_t* l, float constant, float linear, float quadratic);
void light_cone(light_t* l, float innerCone, float outerCone); void light_cone(light_t* l, float innerCone, float outerCone);
void light_update(unsigned num_lights, light_t *lv); void light_update(unsigned num_lights, light_t *lv);

View File

@ -17177,6 +17177,7 @@ typedef struct light_t {
struct { struct {
float constant, linear, quadratic; float constant, linear, quadratic;
} falloff; } falloff;
float specularPower;
float innerCone, outerCone; float innerCone, outerCone;
//@todo: cookie, flare //@todo: cookie, flare
@ -17192,6 +17193,7 @@ API void light_specular(light_t* l, vec3 color);
API void light_ambient(light_t* l, vec3 color); API void light_ambient(light_t* l, vec3 color);
API void light_teleport(light_t* l, vec3 pos); API void light_teleport(light_t* l, vec3 pos);
API void light_dir(light_t* l, vec3 dir); API void light_dir(light_t* l, vec3 dir);
API void light_power(light_t* l, float power);
API void light_falloff(light_t* l, float constant, float linear, float quadratic); API void light_falloff(light_t* l, float constant, float linear, float quadratic);
API void light_cone(light_t* l, float innerCone, float outerCone); API void light_cone(light_t* l, float innerCone, float outerCone);
API void light_update(unsigned num_lights, light_t *lv); API void light_update(unsigned num_lights, light_t *lv);
@ -343307,21 +343309,21 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
glUniformMatrix4fv( loc, 1, GL_FALSE, vp); glUniformMatrix4fv( loc, 1, GL_FALSE, vp);
} }
if( (loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0 ) { if( (loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0 ) {
vec3 pos = vec3(view[3], view[6], view[9]); vec3 pos = vec3(view[12], view[13], view[14]);
glUniform3fv( loc, 1, &pos.x ); glUniform3fv( loc, 1, &pos.x );
} }
else else
if( (loc = glGetUniformLocation(shader, "cam_pos")) >= 0 ) { if( (loc = glGetUniformLocation(shader, "cam_pos")) >= 0 ) {
vec3 pos = vec3(view[3], view[6], view[9]); vec3 pos = vec3(view[12], view[13], view[14]);
glUniform3fv( loc, 1, &pos.x ); glUniform3fv( loc, 1, &pos.x );
} }
if( (loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0 ) { if( (loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0 ) {
vec3 dir = vec3(view[0], view[1], view[2]); vec3 dir = norm3(vec3(view[2], view[6], view[10]));
glUniform3fv( loc, 1, &dir.x ); glUniform3fv( loc, 1, &dir.x );
} }
else else
if( (loc = glGetUniformLocation(shader, "cam_dir")) >= 0 ) { if( (loc = glGetUniformLocation(shader, "cam_dir")) >= 0 ) {
vec3 dir = vec3(view[0], view[1], view[2]); vec3 dir = norm3(vec3(view[2], view[6], view[10]));
glUniform3fv( loc, 1, &dir.x ); glUniform3fv( loc, 1, &dir.x );
} }
#if 0 #if 0
@ -345235,6 +345237,7 @@ light_t light() {
l.falloff.constant = 1.0f; l.falloff.constant = 1.0f;
l.falloff.linear = 0.09f; l.falloff.linear = 0.09f;
l.falloff.quadratic = 0.0032f; l.falloff.quadratic = 0.0032f;
l.specularPower = 32.f;
l.innerCone = 0.9f; // 25 deg l.innerCone = 0.9f; // 25 deg
l.outerCone = 0.85f; // 31 deg l.outerCone = 0.85f; // 31 deg
@ -345271,6 +345274,11 @@ void light_dir(light_t* l, vec3 dir) {
l->dir = dir; l->dir = dir;
} }
void light_power(light_t* l, float power) {
l->cached = 0;
l->specularPower = power;
}
void light_falloff(light_t* l, float constant, float linear, float quadratic) { void light_falloff(light_t* l, float constant, float linear, float quadratic) {
l->cached = 0; l->cached = 0;
l->falloff.constant = constant; l->falloff.constant = constant;
@ -345279,6 +345287,7 @@ void light_falloff(light_t* l, float constant, float linear, float quadratic) {
} }
void light_cone(light_t* l, float innerCone, float outerCone) { void light_cone(light_t* l, float innerCone, float outerCone) {
l->cached = 0;
l->innerCone = acos(innerCone); l->innerCone = acos(innerCone);
l->outerCone = acos(outerCone); l->outerCone = acos(outerCone);
} }
@ -345294,6 +345303,7 @@ void light_update(unsigned num_lights, light_t *lv) {
shader_vec3(va("u_lights[%d].diffuse", i), lv[i].diffuse); shader_vec3(va("u_lights[%d].diffuse", i), lv[i].diffuse);
shader_vec3(va("u_lights[%d].specular", i), lv[i].specular); shader_vec3(va("u_lights[%d].specular", i), lv[i].specular);
shader_vec3(va("u_lights[%d].ambient", i), lv[i].ambient); shader_vec3(va("u_lights[%d].ambient", i), lv[i].ambient);
shader_float(va("u_lights[%d].power", i), lv[i].specularPower);
shader_float(va("u_lights[%d].constant", i), lv[i].falloff.constant); shader_float(va("u_lights[%d].constant", i), lv[i].falloff.constant);
shader_float(va("u_lights[%d].linear", i), lv[i].falloff.linear); shader_float(va("u_lights[%d].linear", i), lv[i].falloff.linear);
shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic); shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic);

View File

@ -3684,21 +3684,21 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
glUniformMatrix4fv( loc, 1, GL_FALSE, vp); glUniformMatrix4fv( loc, 1, GL_FALSE, vp);
} }
if( (loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0 ) { if( (loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0 ) {
vec3 pos = vec3(view[3], view[6], view[9]); vec3 pos = vec3(view[12], view[13], view[14]);
glUniform3fv( loc, 1, &pos.x ); glUniform3fv( loc, 1, &pos.x );
} }
else else
if( (loc = glGetUniformLocation(shader, "cam_pos")) >= 0 ) { if( (loc = glGetUniformLocation(shader, "cam_pos")) >= 0 ) {
vec3 pos = vec3(view[3], view[6], view[9]); vec3 pos = vec3(view[12], view[13], view[14]);
glUniform3fv( loc, 1, &pos.x ); glUniform3fv( loc, 1, &pos.x );
} }
if( (loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0 ) { if( (loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0 ) {
vec3 dir = vec3(view[0], view[1], view[2]); vec3 dir = norm3(vec3(view[2], view[6], view[10]));
glUniform3fv( loc, 1, &dir.x ); glUniform3fv( loc, 1, &dir.x );
} }
else else
if( (loc = glGetUniformLocation(shader, "cam_dir")) >= 0 ) { if( (loc = glGetUniformLocation(shader, "cam_dir")) >= 0 ) {
vec3 dir = vec3(view[0], view[1], view[2]); vec3 dir = norm3(vec3(view[2], view[6], view[10]));
glUniform3fv( loc, 1, &dir.x ); glUniform3fv( loc, 1, &dir.x );
} }
#if 0 #if 0

View File

@ -248,6 +248,7 @@ light_t light() {
l.falloff.constant = 1.0f; l.falloff.constant = 1.0f;
l.falloff.linear = 0.09f; l.falloff.linear = 0.09f;
l.falloff.quadratic = 0.0032f; l.falloff.quadratic = 0.0032f;
l.specularPower = 32.f;
l.innerCone = 0.9f; // 25 deg l.innerCone = 0.9f; // 25 deg
l.outerCone = 0.85f; // 31 deg l.outerCone = 0.85f; // 31 deg
@ -284,6 +285,11 @@ void light_dir(light_t* l, vec3 dir) {
l->dir = dir; l->dir = dir;
} }
void light_power(light_t* l, float power) {
l->cached = 0;
l->specularPower = power;
}
void light_falloff(light_t* l, float constant, float linear, float quadratic) { void light_falloff(light_t* l, float constant, float linear, float quadratic) {
l->cached = 0; l->cached = 0;
l->falloff.constant = constant; l->falloff.constant = constant;
@ -292,6 +298,7 @@ void light_falloff(light_t* l, float constant, float linear, float quadratic) {
} }
void light_cone(light_t* l, float innerCone, float outerCone) { void light_cone(light_t* l, float innerCone, float outerCone) {
l->cached = 0;
l->innerCone = acos(innerCone); l->innerCone = acos(innerCone);
l->outerCone = acos(outerCone); l->outerCone = acos(outerCone);
} }
@ -307,6 +314,7 @@ void light_update(unsigned num_lights, light_t *lv) {
shader_vec3(va("u_lights[%d].diffuse", i), lv[i].diffuse); shader_vec3(va("u_lights[%d].diffuse", i), lv[i].diffuse);
shader_vec3(va("u_lights[%d].specular", i), lv[i].specular); shader_vec3(va("u_lights[%d].specular", i), lv[i].specular);
shader_vec3(va("u_lights[%d].ambient", i), lv[i].ambient); shader_vec3(va("u_lights[%d].ambient", i), lv[i].ambient);
shader_float(va("u_lights[%d].power", i), lv[i].specularPower);
shader_float(va("u_lights[%d].constant", i), lv[i].falloff.constant); shader_float(va("u_lights[%d].constant", i), lv[i].falloff.constant);
shader_float(va("u_lights[%d].linear", i), lv[i].falloff.linear); shader_float(va("u_lights[%d].linear", i), lv[i].falloff.linear);
shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic); shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic);

View File

@ -71,6 +71,7 @@ typedef struct light_t {
struct { struct {
float constant, linear, quadratic; float constant, linear, quadratic;
} falloff; } falloff;
float specularPower;
float innerCone, outerCone; float innerCone, outerCone;
//@todo: cookie, flare //@todo: cookie, flare
@ -86,6 +87,7 @@ API void light_specular(light_t* l, vec3 color);
API void light_ambient(light_t* l, vec3 color); API void light_ambient(light_t* l, vec3 color);
API void light_teleport(light_t* l, vec3 pos); API void light_teleport(light_t* l, vec3 pos);
API void light_dir(light_t* l, vec3 dir); API void light_dir(light_t* l, vec3 dir);
API void light_power(light_t* l, float power);
API void light_falloff(light_t* l, float constant, float linear, float quadratic); API void light_falloff(light_t* l, float constant, float linear, float quadratic);
API void light_cone(light_t* l, float innerCone, float outerCone); API void light_cone(light_t* l, float innerCone, float outerCone);
API void light_update(unsigned num_lights, light_t *lv); API void light_update(unsigned num_lights, light_t *lv);

View File

@ -13948,21 +13948,21 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view,
glUniformMatrix4fv( loc, 1, GL_FALSE, vp); glUniformMatrix4fv( loc, 1, GL_FALSE, vp);
} }
if( (loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0 ) { if( (loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0 ) {
vec3 pos = vec3(view[3], view[6], view[9]); vec3 pos = vec3(view[12], view[13], view[14]);
glUniform3fv( loc, 1, &pos.x ); glUniform3fv( loc, 1, &pos.x );
} }
else else
if( (loc = glGetUniformLocation(shader, "cam_pos")) >= 0 ) { if( (loc = glGetUniformLocation(shader, "cam_pos")) >= 0 ) {
vec3 pos = vec3(view[3], view[6], view[9]); vec3 pos = vec3(view[12], view[13], view[14]);
glUniform3fv( loc, 1, &pos.x ); glUniform3fv( loc, 1, &pos.x );
} }
if( (loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0 ) { if( (loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0 ) {
vec3 dir = vec3(view[0], view[1], view[2]); vec3 dir = norm3(vec3(view[2], view[6], view[10]));
glUniform3fv( loc, 1, &dir.x ); glUniform3fv( loc, 1, &dir.x );
} }
else else
if( (loc = glGetUniformLocation(shader, "cam_dir")) >= 0 ) { if( (loc = glGetUniformLocation(shader, "cam_dir")) >= 0 ) {
vec3 dir = vec3(view[0], view[1], view[2]); vec3 dir = norm3(vec3(view[2], view[6], view[10]));
glUniform3fv( loc, 1, &dir.x ); glUniform3fv( loc, 1, &dir.x );
} }
#if 0 #if 0
@ -15876,6 +15876,7 @@ light_t light() {
l.falloff.constant = 1.0f; l.falloff.constant = 1.0f;
l.falloff.linear = 0.09f; l.falloff.linear = 0.09f;
l.falloff.quadratic = 0.0032f; l.falloff.quadratic = 0.0032f;
l.specularPower = 32.f;
l.innerCone = 0.9f; // 25 deg l.innerCone = 0.9f; // 25 deg
l.outerCone = 0.85f; // 31 deg l.outerCone = 0.85f; // 31 deg
@ -15912,6 +15913,11 @@ void light_dir(light_t* l, vec3 dir) {
l->dir = dir; l->dir = dir;
} }
void light_power(light_t* l, float power) {
l->cached = 0;
l->specularPower = power;
}
void light_falloff(light_t* l, float constant, float linear, float quadratic) { void light_falloff(light_t* l, float constant, float linear, float quadratic) {
l->cached = 0; l->cached = 0;
l->falloff.constant = constant; l->falloff.constant = constant;
@ -15920,6 +15926,7 @@ void light_falloff(light_t* l, float constant, float linear, float quadratic) {
} }
void light_cone(light_t* l, float innerCone, float outerCone) { void light_cone(light_t* l, float innerCone, float outerCone) {
l->cached = 0;
l->innerCone = acos(innerCone); l->innerCone = acos(innerCone);
l->outerCone = acos(outerCone); l->outerCone = acos(outerCone);
} }
@ -15935,6 +15942,7 @@ void light_update(unsigned num_lights, light_t *lv) {
shader_vec3(va("u_lights[%d].diffuse", i), lv[i].diffuse); shader_vec3(va("u_lights[%d].diffuse", i), lv[i].diffuse);
shader_vec3(va("u_lights[%d].specular", i), lv[i].specular); shader_vec3(va("u_lights[%d].specular", i), lv[i].specular);
shader_vec3(va("u_lights[%d].ambient", i), lv[i].ambient); shader_vec3(va("u_lights[%d].ambient", i), lv[i].ambient);
shader_float(va("u_lights[%d].power", i), lv[i].specularPower);
shader_float(va("u_lights[%d].constant", i), lv[i].falloff.constant); shader_float(va("u_lights[%d].constant", i), lv[i].falloff.constant);
shader_float(va("u_lights[%d].linear", i), lv[i].falloff.linear); shader_float(va("u_lights[%d].linear", i), lv[i].falloff.linear);
shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic); shader_float(va("u_lights[%d].quadratic", i), lv[i].falloff.quadratic);

View File

@ -3260,6 +3260,7 @@ typedef struct light_t {
struct { struct {
float constant, linear, quadratic; float constant, linear, quadratic;
} falloff; } falloff;
float specularPower;
float innerCone, outerCone; float innerCone, outerCone;
//@todo: cookie, flare //@todo: cookie, flare
@ -3275,6 +3276,7 @@ API void light_specular(light_t* l, vec3 color);
API void light_ambient(light_t* l, vec3 color); API void light_ambient(light_t* l, vec3 color);
API void light_teleport(light_t* l, vec3 pos); API void light_teleport(light_t* l, vec3 pos);
API void light_dir(light_t* l, vec3 dir); API void light_dir(light_t* l, vec3 dir);
API void light_power(light_t* l, float power);
API void light_falloff(light_t* l, float constant, float linear, float quadratic); API void light_falloff(light_t* l, float constant, float linear, float quadratic);
API void light_cone(light_t* l, float innerCone, float outerCone); API void light_cone(light_t* l, float innerCone, float outerCone);
API void light_update(unsigned num_lights, light_t *lv); API void light_update(unsigned num_lights, light_t *lv);