From 4580673839c9e3c9eb81135a73f63d8d4eeb4af5 Mon Sep 17 00:00:00 2001 From: Andrei Alexeyev Date: Thu, 18 Feb 2021 21:39:14 +0200 Subject: [PATCH] add a PBR sprite shader --- .../shader/interface/sprite.glslh | 20 +++++----- .../shader/interface/sprite_pbr.glslh | 27 +++++++++++++ resources/00-taisei.pkgdir/shader/meson.build | 2 + .../shader/sprite_pbr.frag.glsl | 38 +++++++++++++++++++ .../00-taisei.pkgdir/shader/sprite_pbr.prog | 1 + .../shader/sprite_pbr.vert.glsl | 24 ++++++++++++ src/renderer/common/sprite_batch.c | 2 + 7 files changed, 105 insertions(+), 9 deletions(-) create mode 100644 resources/00-taisei.pkgdir/shader/interface/sprite_pbr.glslh create mode 100644 resources/00-taisei.pkgdir/shader/sprite_pbr.frag.glsl create mode 100644 resources/00-taisei.pkgdir/shader/sprite_pbr.prog create mode 100644 resources/00-taisei.pkgdir/shader/sprite_pbr.vert.glsl diff --git a/resources/00-taisei.pkgdir/shader/interface/sprite.glslh b/resources/00-taisei.pkgdir/shader/interface/sprite.glslh index f8fa7a57..56d4478f 100644 --- a/resources/00-taisei.pkgdir/shader/interface/sprite.glslh +++ b/resources/00-taisei.pkgdir/shader/interface/sprite.glslh @@ -10,22 +10,24 @@ */ ATTRIBUTE(0) vec2 vertPos; ATTRIBUTE(1) vec2 vertTexCoord; +ATTRIBUTE(2) vec3 vertNormal; +ATTRIBUTE(3) vec4 vertTangent; /* * Per-instance attributes */ -ATTRIBUTE(2) mat4 spriteVMTransform; -// 3 -// 4 +ATTRIBUTE(4) mat4 spriteVMTransform; // 5 -ATTRIBUTE(6) mat4 spriteTexTransform; +// 6 // 7 -// 8 +ATTRIBUTE(8) mat4 spriteTexTransform; // 9 -ATTRIBUTE(10) vec4 spriteRGBA; -ATTRIBUTE(11) vec4 spriteTexRegion; -ATTRIBUTE(12) vec2 spriteDimensions; -ATTRIBUTE(13) vec4 spriteCustomParams; +// 10 +// 11 +ATTRIBUTE(12) vec4 spriteRGBA; +ATTRIBUTE(13) vec4 spriteTexRegion; +ATTRIBUTE(14) vec2 spriteDimensions; +ATTRIBUTE(15) vec4 spriteCustomParams; #endif #ifdef FRAG_STAGE diff --git a/resources/00-taisei.pkgdir/shader/interface/sprite_pbr.glslh b/resources/00-taisei.pkgdir/shader/interface/sprite_pbr.glslh new file mode 100644 index 00000000..14393e0e --- /dev/null +++ b/resources/00-taisei.pkgdir/shader/interface/sprite_pbr.glslh @@ -0,0 +1,27 @@ + +#ifndef I_SPRITE_PBR_H +#define I_SPRITE_PBR_H + +#include "sprite.glslh" +#include "../lib/pbr.glslh" + +#define tex_diffuse tex +#define tex_ambient tex_aux[0] +#define tex_normal tex_aux[1] +#define tex_roughness tex_aux[2] + +UNIFORM(1) mat4 camera_transform; +UNIFORM(2) int light_count; +UNIFORM(3) vec3 light_positions[PBR_MAX_LIGHTS]; +UNIFORM(9) vec3 light_colors[PBR_MAX_LIGHTS]; // layout-id also depends on PBR_MAX_LIGHTS + +VARYING(7) vec3 pos; +VARYING(8) vec3 normal; +VARYING(9) vec3 tangent; +VARYING(10) vec3 bitangent; +VARYING(11) PointLight point_lights[PBR_MAX_LIGHTS]; + +// customParams.rgb = ambient color +// customParams.a = metallicity + +#endif diff --git a/resources/00-taisei.pkgdir/shader/meson.build b/resources/00-taisei.pkgdir/shader/meson.build index c90ae63e..28405d7e 100644 --- a/resources/00-taisei.pkgdir/shader/meson.build +++ b/resources/00-taisei.pkgdir/shader/meson.build @@ -61,6 +61,8 @@ glsl_files = files( 'sprite_hakkero.vert.glsl', 'sprite_negative.frag.glsl', 'sprite_particle.frag.glsl', + 'sprite_pbr.frag.glsl', + 'sprite_pbr.vert.glsl', 'sprite_silhouette.frag.glsl', 'sprite_silhouette.vert.glsl', 'sprite_yinyang.frag.glsl', diff --git a/resources/00-taisei.pkgdir/shader/sprite_pbr.frag.glsl b/resources/00-taisei.pkgdir/shader/sprite_pbr.frag.glsl new file mode 100644 index 00000000..c8444c57 --- /dev/null +++ b/resources/00-taisei.pkgdir/shader/sprite_pbr.frag.glsl @@ -0,0 +1,38 @@ +#version 330 core + +#include "lib/render_context.glslh" +#include "interface/sprite_pbr.glslh" + +void main(void) { + vec4 roughness_sample = texture(tex_roughness, texCoord); + float alpha = roughness_sample.a; + + if(alpha < 0.3) { + discard; + } + + vec3 ambient = texture(tex_ambient, texCoord).rgb; + vec3 tbn_normal = sample_normalmap(tex_normal, texCoord); + mat3 tbn = mat3(normalize(tangent), normalize(bitangent), normalize(normal)); + + PBRParams p; + p.fragPos = pos; + p.albedo = color.rgb * texture(tex, texCoord).rgb; + p.roughness = roughness_sample.r; + p.metallic = customParams.a; + p.normal = normalize(tbn * tbn_normal); + + PBRState pbr = PBR(p); + + vec3 Lo = vec3(0.0); + for(int i = 0; i < light_count; ++i) { + Lo += PBR_PointLight(pbr, point_lights[i]); + } + + vec3 ambient_color = customParams.rgb; + vec3 color = ambient * ambient_color + Lo; + color = PBR_TonemapReinhard(color); + color = PBR_GammaCorrect(color); + + fragColor = vec4(color, 1) * alpha; +} diff --git a/resources/00-taisei.pkgdir/shader/sprite_pbr.prog b/resources/00-taisei.pkgdir/shader/sprite_pbr.prog new file mode 100644 index 00000000..ddbcc01c --- /dev/null +++ b/resources/00-taisei.pkgdir/shader/sprite_pbr.prog @@ -0,0 +1 @@ +objects = sprite_pbr.vert sprite_pbr.frag diff --git a/resources/00-taisei.pkgdir/shader/sprite_pbr.vert.glsl b/resources/00-taisei.pkgdir/shader/sprite_pbr.vert.glsl new file mode 100644 index 00000000..f931e3a9 --- /dev/null +++ b/resources/00-taisei.pkgdir/shader/sprite_pbr.vert.glsl @@ -0,0 +1,24 @@ +#version 330 + +#include "lib/render_context.glslh" +#include "interface/sprite_pbr.glslh" + +void main(void) { + pos = (spriteVMTransform * vec4(vertPos, 0.0, 1.0)).xyz; + normal = normalize(mat3(spriteVMTransform) * vertNormal); + tangent = normalize(mat3(spriteVMTransform) * vertTangent.xyz); + bitangent = normalize(mat3(spriteVMTransform) * cross(vertNormal.xyz, vertTangent.xyz) * vertTangent.w); + + gl_Position = r_projectionMatrix * vec4(pos, 1.0); + texCoord = uv_to_region(spriteTexRegion, vertTexCoord); + texCoordRaw = vertTexCoord; + texCoordOverlay = (spriteTexTransform * vec4(vertTexCoord, 0.0, 1.0)).xy; + texRegion = spriteTexRegion; + dimensions = spriteDimensions; + customParams = spriteCustomParams; + + for(int i = 0; i < light_count; ++i) { + point_lights[i].dir = (camera_transform * vec4(light_positions[i], 1.0)).xyz - pos; + point_lights[i].color = light_colors[i]; + } +} diff --git a/src/renderer/common/sprite_batch.c b/src/renderer/common/sprite_batch.c index 8f8c922f..6de80085 100644 --- a/src/renderer/common/sprite_batch.c +++ b/src/renderer/common/sprite_batch.c @@ -71,6 +71,8 @@ void _r_sprite_batch_init(void) { // Per-vertex attributes (for the static models buffer, bound at 0) { { 2, VA_FLOAT, VA_CONVERT_FLOAT, 0 }, sz_vert, VERTEX_OFS(position), 0 }, { { 2, VA_FLOAT, VA_CONVERT_FLOAT, 0 }, sz_vert, VERTEX_OFS(uv), 0 }, + { { 3, VA_FLOAT, VA_CONVERT_FLOAT, 0 }, sz_vert, VERTEX_OFS(normal), 0 }, + { { 4, VA_FLOAT, VA_CONVERT_FLOAT, 0 }, sz_vert, VERTEX_OFS(tangent), 0 }, // Per-instance attributes (for our own sprites buffer, bound at 1) { { 4, VA_FLOAT, VA_CONVERT_FLOAT, 1 }, sz_attr, INSTANCE_OFS(mv_transform[0]), 1 },