Merge branch 'raysan5:master' into pure

This commit is contained in:
Colleague Riley 2025-01-11 18:57:01 -05:00 • committed by GitHub
commit 6b23824289
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
58 changed files with 691 additions and 391 deletions

View file

@ -50,7 +50,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [raylib-matte](https://github.com/jcorks/raylib-matte) | 4.6-dev | [Matte](https://github.com/jcorks/matte) | **???** | | [raylib-matte](https://github.com/jcorks/raylib-matte) | 4.6-dev | [Matte](https://github.com/jcorks/matte) | **???** |
| [Raylib.nelua](https://github.com/AuzFox/Raylib.nelua) | **5.0** | [nelua](https://nelua.io) | Zlib | | [Raylib.nelua](https://github.com/AuzFox/Raylib.nelua) | **5.0** | [nelua](https://nelua.io) | Zlib |
| [raylib-bindings](https://github.com/vaiorabbit/raylib-bindings) | 5.6-dev | [Ruby](https://www.ruby-lang.org/en) | Zlib | | [raylib-bindings](https://github.com/vaiorabbit/raylib-bindings) | 5.6-dev | [Ruby](https://www.ruby-lang.org/en) | Zlib |
| [naylib](https://github.com/planetis-m/naylib) | **5.1-dev** | [Nim](https://nim-lang.org) | MIT | | [naylib](https://github.com/planetis-m/naylib) | **5.6-dev** | [Nim](https://nim-lang.org) | MIT |
| [node-raylib](https://github.com/RobLoach/node-raylib) | 4.5 | [Node.js](https://nodejs.org/en) | Zlib | | [node-raylib](https://github.com/RobLoach/node-raylib) | 4.5 | [Node.js](https://nodejs.org/en) | Zlib |
| [raylib-odin](https://github.com/odin-lang/Odin/tree/master/vendor/raylib) | **5.5** | [Odin](https://odin-lang.org) | BSD-3Clause | | [raylib-odin](https://github.com/odin-lang/Odin/tree/master/vendor/raylib) | **5.5** | [Odin](https://odin-lang.org) | BSD-3Clause |
| [raylib_odin_bindings](https://github.com/Deathbat2190/raylib_odin_bindings) | 4.0-dev | [Odin](https://odin-lang.org) | MIT | | [raylib_odin_bindings](https://github.com/Deathbat2190/raylib_odin_bindings) | 4.0-dev | [Odin](https://odin-lang.org) | MIT |
@ -69,6 +69,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
| [raylibr](https://github.com/jeroenjanssens/raylibr) | 4.0 | [R](https://www.r-project.org) | MIT | | [raylibr](https://github.com/jeroenjanssens/raylibr) | 4.0 | [R](https://www.r-project.org) | MIT |
| [raylib-ffi](https://github.com/ewpratten/raylib-ffi) | 5.5 | [Rust](https://www.rust-lang.org) | GPLv3 | | [raylib-ffi](https://github.com/ewpratten/raylib-ffi) | 5.5 | [Rust](https://www.rust-lang.org) | GPLv3 |
| [raylib-rs](https://github.com/raylib-rs/raylib-rs) | **5.5** | [Rust](https://www.rust-lang.org) | Zlib | | [raylib-rs](https://github.com/raylib-rs/raylib-rs) | **5.5** | [Rust](https://www.rust-lang.org) | Zlib |
| [raylib-ruby](https://github.com/wilsonsilva/raylib-ruby) | 4.5 | [Ruby](https://www.ruby-lang.org) | Zlib |
| [Relib](https://github.com/RedCubeDev-ByteSpace/Relib) | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | **???** | | [Relib](https://github.com/RedCubeDev-ByteSpace/Relib) | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | **???** |
| [racket-raylib](https://github.com/eutro/racket-raylib) | 4.0 | [Racket](https://racket-lang.org) | MIT/Apache-2.0 | | [racket-raylib](https://github.com/eutro/racket-raylib) | 4.0 | [Racket](https://racket-lang.org) | MIT/Apache-2.0 |
| [raylib-swift](https://github.com/STREGAsGate/Raylib) | 4.0 | [Swift](https://swift.org) | MIT | | [raylib-swift](https://github.com/STREGAsGate/Raylib) | 4.0 | [Swift](https://swift.org) | MIT |

View file

@ -1,4 +1,4 @@
Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
This software is provided "as-is", without any express or implied warranty. In no event This software is provided "as-is", without any express or implied warranty. In no event
will the authors be held liable for any damages arising from the use of this software. will the authors be held liable for any damages arising from the use of this software.

View file

@ -13,9 +13,9 @@ comptime {
fn setDesktopPlatform(raylib: *std.Build.Step.Compile, platform: PlatformBackend) void { fn setDesktopPlatform(raylib: *std.Build.Step.Compile, platform: PlatformBackend) void {
switch (platform) { switch (platform) {
.glfw => raylib.defineCMacro("PLATFORM_DESKTOP_GLFW", null), .glfw => raylib.root_module.addCMacro("PLATFORM_DESKTOP_GLFW", ""),
.rgfw => raylib.defineCMacro("PLATFORM_DESKTOP_RGFW", null), .rgfw => raylib.root_module.addCMacro("PLATFORM_DESKTOP_RGFW", ""),
.sdl => raylib.defineCMacro("PLATFORM_DESKTOP_SDL", null), .sdl => raylib.root_module.addCMacro("PLATFORM_DESKTOP_SDL", ""),
else => {}, else => {},
} }
} }
@ -173,7 +173,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
} }
if (options.opengl_version != .auto) { if (options.opengl_version != .auto) {
raylib.defineCMacro(options.opengl_version.toCMacroStr(), null); raylib.root_module.addCMacro(options.opengl_version.toCMacroStr(), "");
} }
raylib.addIncludePath(b.path("src/platforms")); raylib.addIncludePath(b.path("src/platforms"));
@ -191,7 +191,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
try c_source_files.append("src/rglfw.c"); try c_source_files.append("src/rglfw.c");
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) { if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
raylib.defineCMacro("_GLFW_X11", null); raylib.root_module.addCMacro("_GLFW_X11", "");
raylib.linkSystemLibrary("GLX"); raylib.linkSystemLibrary("GLX");
raylib.linkSystemLibrary("X11"); raylib.linkSystemLibrary("X11");
raylib.linkSystemLibrary("Xcursor"); raylib.linkSystemLibrary("Xcursor");
@ -211,7 +211,7 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
, .{}); , .{});
@panic("`wayland-scanner` not found"); @panic("`wayland-scanner` not found");
}; };
raylib.defineCMacro("_GLFW_WAYLAND", null); raylib.root_module.addCMacro("_GLFW_WAYLAND", "");
raylib.linkSystemLibrary("EGL"); raylib.linkSystemLibrary("EGL");
raylib.linkSystemLibrary("wayland-client"); raylib.linkSystemLibrary("wayland-client");
raylib.linkSystemLibrary("xkbcommon"); raylib.linkSystemLibrary("xkbcommon");
@ -230,16 +230,16 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
} else { } else {
if (options.opengl_version == .auto) { if (options.opengl_version == .auto) {
raylib.linkSystemLibrary("GLESv2"); raylib.linkSystemLibrary("GLESv2");
raylib.defineCMacro("GRAPHICS_API_OPENGL_ES2", null); raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES2", "");
} }
raylib.linkSystemLibrary("EGL"); raylib.linkSystemLibrary("EGL");
raylib.linkSystemLibrary("gbm"); raylib.linkSystemLibrary("gbm");
raylib.linkSystemLibrary2("libdrm", .{ .use_pkg_config = .force }); raylib.linkSystemLibrary2("libdrm", .{ .use_pkg_config = .force });
raylib.defineCMacro("PLATFORM_DRM", null); raylib.root_module.addCMacro("PLATFORM_DRM", "");
raylib.defineCMacro("EGL_NO_X11", null); raylib.root_module.addCMacro("EGL_NO_X11", "");
raylib.defineCMacro("DEFAULT_BATCH_BUFFER_ELEMENT", "2048"); raylib.root_module.addCMacro("DEFAULT_BATCH_BUFFER_ELEMENT", "");
} }
}, },
.freebsd, .openbsd, .netbsd, .dragonfly => { .freebsd, .openbsd, .netbsd, .dragonfly => {
@ -290,9 +290,9 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
raylib.addIncludePath(dep.path("upstream/emscripten/cache/sysroot/include")); raylib.addIncludePath(dep.path("upstream/emscripten/cache/sysroot/include"));
} }
raylib.defineCMacro("PLATFORM_WEB", null); raylib.root_module.addCMacro("PLATFORM_WEB", "");
if (options.opengl_version == .auto) { if (options.opengl_version == .auto) {
raylib.defineCMacro("GRAPHICS_API_OPENGL_ES2", null); raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES2", "");
} }
}, },
else => { else => {

View file

@ -5,8 +5,8 @@
.dependencies = .{ .dependencies = .{
.xcode_frameworks = .{ .xcode_frameworks = .{
.url = "git+https://github.com/hexops/xcode-frameworks#a6bf82e032d4d9923ad5c222d466710fcc05f249", .url = "git+https://github.com/hexops/xcode-frameworks#9a45f3ac977fd25dff77e58c6de1870b6808c4a7",
.hash = "12208da4dfcd9b53fb367375fb612ec73f38e53015f1ce6ae6d6e8437a637078e170", .hash = "122098b9174895f9708bc824b0f9e550c401892c40a900006459acf2cbf78acd99bb",
.lazy = true, .lazy = true,
}, },
.emsdk = .{ .emsdk = .{

View file

@ -69,6 +69,14 @@ elseif (${PLATFORM} MATCHES "Android")
set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON)
list(APPEND raylib_sources ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c) list(APPEND raylib_sources ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
include_directories(${ANDROID_NDK}/sources/android/native_app_glue) include_directories(${ANDROID_NDK}/sources/android/native_app_glue)
# NOTE: We remove '-Wl,--no-undefined' (set by default) as it conflicts with '-Wl,-undefined,dynamic_lookup' needed
# for compiling with the missing 'void main(void)' declaration in `android_main()`.
# We also remove other unnecessary or problematic flags.
string(REPLACE "-Wl,--no-undefined -Qunused-arguments" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
string(REPLACE "-static-libstdc++" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -u ANativeActivity_onCreate -Wl,-undefined,dynamic_lookup") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -u ANativeActivity_onCreate -Wl,-undefined,dynamic_lookup")
find_library(OPENGL_LIBRARY OpenGL) find_library(OPENGL_LIBRARY OpenGL)

View file

@ -124,7 +124,21 @@ endif ()
# The rlgl_standalone example only targets desktop, without shared libraries. # The rlgl_standalone example only targets desktop, without shared libraries.
if (BUILD_SHARED_LIBS OR NOT ${PLATFORM} MATCHES "Desktop") if (BUILD_SHARED_LIBS OR NOT ${PLATFORM} MATCHES "Desktop")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c) list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
endif()
# The audio examples fail to link if raylib is built without raudio
if (NOT SUPPORT_MODULE_RAUDIO)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio/audio_mixed_processor.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio/audio_module_playing.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio/audio_music_stream.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio/audio_raw_stream.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio/audio_sound_loading.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio/audio_sound_multi.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/audio/audio_stream_effects.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/embedded_files_loading.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/textures/textures_sprite_button.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/textures/textures_sprite_explosion.c)
endif() endif()
include_directories(BEFORE SYSTEM others/external/include) include_directories(BEFORE SYSTEM others/external/include)

View file

@ -30,7 +30,7 @@
# > PLATFORM_ANDROID: # > PLATFORM_ANDROID:
# - Android (ARM, ARM64) # - Android (ARM, ARM64)
# #
# Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) # Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
# #
# This software is provided "as-is", without any express or implied warranty. In no event # This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software. # will the authors be held liable for any damages arising from the use of this software.

View file

@ -2,7 +2,7 @@
# #
# raylib makefile for Android project (APK building) # raylib makefile for Android project (APK building)
# #
# Copyright (c) 2017-2024 Ramon Santamaria (@raysan5) # Copyright (c) 2017-2025 Ramon Santamaria (@raysan5)
# #
# This software is provided "as-is", without any express or implied warranty. In no event # This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software. # will the authors be held liable for any damages arising from the use of this software.

View file

@ -2,7 +2,7 @@
# #
# raylib makefile for Web platform # raylib makefile for Web platform
# #
# Copyright (c) 2013-2024 Ramon Santamaria (@raysan5) # Copyright (c) 2013-2025 Ramon Santamaria (@raysan5)
# #
# This software is provided "as-is", without any express or implied warranty. In no event # This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software. # will the authors be held liable for any damages arising from the use of this software.

View file

@ -46,7 +46,7 @@ fn add_module(comptime module: []const u8, b: *std.Build, target: std.Build.Reso
exe.linkSystemLibrary("gdi32"); exe.linkSystemLibrary("gdi32");
exe.linkSystemLibrary("opengl32"); exe.linkSystemLibrary("opengl32");
exe.defineCMacro("PLATFORM_DESKTOP", null); exe.root_module.addCMacro("PLATFORM_DESKTOP", "");
}, },
.linux => { .linux => {
exe.linkSystemLibrary("GL"); exe.linkSystemLibrary("GL");
@ -55,7 +55,7 @@ fn add_module(comptime module: []const u8, b: *std.Build, target: std.Build.Reso
exe.linkSystemLibrary("m"); exe.linkSystemLibrary("m");
exe.linkSystemLibrary("X11"); exe.linkSystemLibrary("X11");
exe.defineCMacro("PLATFORM_DESKTOP", null); exe.root_module.addCMacro("PLATFORM_DESKTOP", "");
}, },
.macos => { .macos => {
exe.linkFramework("Foundation"); exe.linkFramework("Foundation");
@ -65,7 +65,7 @@ fn add_module(comptime module: []const u8, b: *std.Build, target: std.Build.Reso
exe.linkFramework("CoreVideo"); exe.linkFramework("CoreVideo");
exe.linkFramework("IOKit"); exe.linkFramework("IOKit");
exe.defineCMacro("PLATFORM_DESKTOP", null); exe.root_module.addCMacro("PLATFORM_DESKTOP", "");
}, },
else => { else => {
@panic("Unsupported OS"); @panic("Unsupported OS");

View file

@ -63,7 +63,7 @@ int main(void)
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// If anyone moves this frame, how far will they move based on the time since the last frame // If anyone moves this frame, how far will they move based on the time since the last frame
// this moves thigns at 10 world units per second, regardless of the actual FPS // this moves things at 10 world units per second, regardless of the actual FPS
float offsetThisFrame = 10.0f*GetFrameTime(); float offsetThisFrame = 10.0f*GetFrameTime();
// Move Player1 forward and backwards (no turning) // Move Player1 forward and backwards (no turning)
@ -171,4 +171,4 @@ int main(void)
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;
} }

View file

@ -13,7 +13,7 @@ BEGIN
VALUE "FileDescription", "raylib example" VALUE "FileDescription", "raylib example"
VALUE "FileVersion", "1.0" VALUE "FileVersion", "1.0"
VALUE "InternalName", "raylib-example" VALUE "InternalName", "raylib-example"
VALUE "LegalCopyright", "(c) 2024 raylib technologies (@raylibtech)" VALUE "LegalCopyright", "(c) 2025 raylib technologies (@raylibtech)"
//VALUE "OriginalFilename", "raylib_app.exe" //VALUE "OriginalFilename", "raylib_app.exe"
VALUE "ProductName", "raylib-example" VALUE "ProductName", "raylib-example"
VALUE "ProductVersion", "1.0" VALUE "ProductVersion", "1.0"

View file

@ -6,16 +6,19 @@
in vec3 vertexPosition; in vec3 vertexPosition;
in vec2 vertexTexCoord; in vec2 vertexTexCoord;
in vec4 vertexColor; in vec4 vertexColor;
in vec3 vertexNormal;
in vec4 vertexBoneIds; in vec4 vertexBoneIds;
in vec4 vertexBoneWeights; in vec4 vertexBoneWeights;
// Input uniform values // Input uniform values
uniform mat4 mvp; uniform mat4 mvp;
uniform mat4 matNormal;
uniform mat4 boneMatrices[MAX_BONE_NUM]; uniform mat4 boneMatrices[MAX_BONE_NUM];
// Output vertex attributes (to fragment shader) // Output vertex attributes (to fragment shader)
out vec2 fragTexCoord; out vec2 fragTexCoord;
out vec4 fragColor; out vec4 fragColor;
out vec3 fragNormal;
void main() void main()
{ {
@ -29,9 +32,18 @@ void main()
vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexPosition, 1.0)) + vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexPosition, 1.0)) + vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexPosition, 1.0)) +
vertexBoneWeights.w*(boneMatrices[boneIndex3]*vec4(vertexPosition, 1.0)); vertexBoneWeights.w*(boneMatrices[boneIndex3]*vec4(vertexPosition, 1.0));
vec4 skinnedNormal =
vertexBoneWeights.x*(boneMatrices[boneIndex0]*vec4(vertexNormal, 0.0)) +
vertexBoneWeights.y*(boneMatrices[boneIndex1]*vec4(vertexNormal, 0.0)) +
vertexBoneWeights.z*(boneMatrices[boneIndex2]*vec4(vertexNormal, 0.0)) +
vertexBoneWeights.w*(boneMatrices[boneIndex3]*vec4(vertexNormal, 0.0));
skinnedNormal.w = 0.0;
fragTexCoord = vertexTexCoord; fragTexCoord = vertexTexCoord;
fragColor = vertexColor; fragColor = vertexColor;
fragNormal = normalize(vec3(matNormal*skinnedNormal));
gl_Position = mvp*skinnedPosition; gl_Position = mvp*skinnedPosition;
} }

View file

@ -54,102 +54,108 @@ uniform vec3 viewPos;
uniform vec3 ambientColor; uniform vec3 ambientColor;
uniform float ambient; uniform float ambient;
// refl in range 0 to 1 // Reflectivity in range 0.0 to 1.0
// returns base reflectivity to 1 // NOTE: Reflectivity is increased when surface view at larger angle
// incrase reflectivity when surface view at larger angle vec3 SchlickFresnel(float hDotV,vec3 refl)
vec3 schlickFresnel(float hDotV,vec3 refl)
{ {
return refl + (1.0 - refl) * pow(1.0 - hDotV,5.0); return refl + (1.0 - refl)*pow(1.0 - hDotV, 5.0);
} }
float ggxDistribution(float nDotH,float roughness) float GgxDistribution(float nDotH,float roughness)
{ {
float a = roughness * roughness * roughness * roughness; float a = roughness*roughness*roughness*roughness;
float d = nDotH * nDotH * (a - 1.0) + 1.0; float d = nDotH*nDotH*(a - 1.0) + 1.0;
d = PI * d * d; d = PI*d*d;
return a / max(d,0.0000001); return (a/max(d,0.0000001));
} }
float geomSmith(float nDotV,float nDotL,float roughness) float GeomSmith(float nDotV,float nDotL,float roughness)
{ {
float r = roughness + 1.0; float r = roughness + 1.0;
float k = r * r / 8.0; float k = r*r/8.0;
float ik = 1.0 - k; float ik = 1.0 - k;
float ggx1 = nDotV / (nDotV * ik + k); float ggx1 = nDotV/(nDotV*ik + k);
float ggx2 = nDotL / (nDotL * ik + k); float ggx2 = nDotL/(nDotL*ik + k);
return ggx1 * ggx2; return ggx1*ggx2;
} }
vec3 pbr(){ vec3 ComputePBR()
vec3 albedo = texture2D(albedoMap,vec2(fragTexCoord.x*tiling.x+offset.x,fragTexCoord.y*tiling.y+offset.y)).rgb; {
albedo = vec3(albedoColor.x*albedo.x,albedoColor.y*albedo.y,albedoColor.z*albedo.z); vec3 albedo = texture2D(albedoMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb;
float metallic = clamp(metallicValue,0.0,1.0); albedo = vec3(albedoColor.x*albedo.x, albedoColor.y*albedo.y, albedoColor.z*albedo.z);
float roughness = clamp(roughnessValue,0.0,1.0);
float ao = clamp(aoValue,0.0,1.0); float metallic = clamp(metallicValue, 0.0, 1.0);
if(useTexMRA == 1) { float roughness = clamp(roughnessValue, 0.0, 1.0);
vec4 mra = texture2D(mraMap, vec2(fragTexCoord.x * tiling.x + offset.x, fragTexCoord.y * tiling.y + offset.y)); float ao = clamp(aoValue, 0.0, 1.0);
metallic = clamp(mra.r+metallicValue,0.04,1.0);
roughness = clamp(mra.g+roughnessValue,0.04,1.0); if (useTexMRA == 1)
ao = (mra.b+aoValue)*0.5; {
} vec4 mra = texture2D(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y));
metallic = clamp(mra.r + metallicValue, 0.04, 1.0);
roughness = clamp(mra.g + roughnessValue, 0.04, 1.0);
ao = (mra.b + aoValue)*0.5;
}
vec3 N = normalize(fragNormal);
if (useTexNormal == 1)
{
N = texture2D(normalMap, vec2(fragTexCoord.x*tiling.x + offset.y, fragTexCoord.y*tiling.y + offset.y)).rgb;
N = normalize(N*2.0 - 1.0);
N = normalize(N*TBN);
}
vec3 V = normalize(viewPos - fragPosition);
vec3 N = normalize(fragNormal); vec3 emissive = vec3(0);
if(useTexNormal == 1) { emissive = (texture2D(emissiveMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb).g*emissiveColor.rgb*emissivePower*float(useTexEmissive);
N = texture2D(normalMap, vec2(fragTexCoord.x * tiling.x + offset.y, fragTexCoord.y * tiling.y + offset.y)).rgb;
N = normalize(N * 2.0 - 1.0); // return N;//vec3(metallic,metallic,metallic);
N = normalize(N * TBN); // If dia-electric use base reflectivity of 0.04 otherwise ut is a metal use albedo as base reflectivity
} vec3 baseRefl = mix(vec3(0.04), albedo.rgb, metallic);
vec3 lightAccum = vec3(0.0); // Acumulate lighting lum
for (int i = 0; i < 4; i++)
{
vec3 L = normalize(lights[i].position - fragPosition); // Compute light vector
vec3 H = normalize(V + L); // Compute halfway bisecting vector
float dist = length(lights[i].position - fragPosition); // Compute distance to light
float attenuation = 1.0/(dist*dist*0.23); // Compute attenuation
vec3 radiance = lights[i].color.rgb*lights[i].intensity*attenuation; // Compute input radiance, light energy comming in
// Cook-Torrance BRDF distribution function
float nDotV = max(dot(N,V), 0.0000001);
float nDotL = max(dot(N,L), 0.0000001);
float hDotV = max(dot(H,V), 0.0);
float nDotH = max(dot(N,H), 0.0);
float D = GgxDistribution(nDotH, roughness); // Larger the more micro-facets aligned to H
float G = GeomSmith(nDotV, nDotL, roughness); // Smaller the more micro-facets shadow
vec3 F = SchlickFresnel(hDotV, baseRefl); // Fresnel proportion of specular reflectance
vec3 spec = (D*G*F)/(4.0*nDotV*nDotL);
vec3 V = normalize(viewPos - fragPosition); // Difuse and spec light can't be above 1.0
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
vec3 kD = vec3(1.0) - F;
vec3 e = vec3(0); // Mult kD by the inverse of metallnes, only non-metals should have diffuse light
e = (texture2D(emissiveMap, vec2(fragTexCoord.x*tiling.x+offset.x, fragTexCoord.y*tiling.y+offset.y)).rgb).g * emissiveColor.rgb*emissivePower * float(useTexEmissive); kD *= 1.0 - metallic;
lightAccum += ((kD*albedo.rgb/PI + spec)*radiance*nDotL)*float(lights[i].enabled); // Angle of light has impact on result
//return N;//vec3(metallic,metallic,metallic); }
//if dia-electric use base reflectivity of 0.04 otherwise ut is a metal use albedo as base reflectivity
vec3 baseRefl = mix(vec3(0.04),albedo.rgb,metallic); vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5;
vec3 Lo = vec3(0.0); // acumulate lighting lum
return (ambientFinal + lightAccum*ao + emissive);
for(int i=0;i<4;++i){
vec3 L = normalize(lights[i].position - fragPosition); // calc light vector
vec3 H = normalize(V + L); // calc halfway bisecting vector
float dist = length(lights[i].position - fragPosition); // calc distance to light
float attenuation = 1.0 / (dist * dist * 0.23); // calc attenuation
vec3 radiance = lights[i].color.rgb * lights[i].intensity * attenuation; // calc input radiance,light energy comming in
//Cook-Torrance BRDF distribution function
float nDotV = max(dot(N,V),0.0000001);
float nDotL = max(dot(N,L),0.0000001);
float hDotV = max(dot(H,V),0.0);
float nDotH = max(dot(N,H),0.0);
float D = ggxDistribution(nDotH,roughness); // larger the more micro-facets aligned to H
float G = geomSmith(nDotV,nDotL,roughness); // smaller the more micro-facets shadow
vec3 F = schlickFresnel(hDotV, baseRefl); // fresnel proportion of specular reflectance
vec3 spec = (D * G * F) / (4.0 * nDotV * nDotL);
// difuse and spec light can't be above 1.0
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
vec3 kD = vec3(1.0) - F;
//mult kD by the inverse of metallnes , only non-metals should have diffuse light
kD *= 1.0 - metallic;
Lo += ((kD * albedo.rgb / PI + spec) * radiance * nDotL)*float(lights[i].enabled); // angle of light has impact on result
}
vec3 ambient_final = (ambientColor + albedo)* ambient * 0.5;
return ambient_final+Lo*ao+e;
} }
void main() void main()
{ {
vec3 color = pbr(); vec3 color = ComputePBR();
//HDR tonemapping
color = pow(color,color + vec3(1.0));
//gamma correction
color = pow(color,vec3(1.0/2.2));
gl_FragColor = vec4(color,1.0); // HDR tonemapping
color = pow(color, color + vec3(1.0));
// Gamma correction
color = pow(color, vec3(1.0/2.2));
gl_FragColor = vec4(color,1.0);
} }

View file

@ -26,17 +26,17 @@ const float normalOffset = 0.1;
// https://github.com/glslify/glsl-inverse // https://github.com/glslify/glsl-inverse
mat3 inverse(mat3 m) mat3 inverse(mat3 m)
{ {
float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2]; float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2]; float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2]; float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
float b01 = a22*a11 - a12*a21; float b01 = a22*a11 - a12*a21;
float b11 = -a22*a10 + a12*a20; float b11 = -a22*a10 + a12*a20;
float b21 = a21*a10 - a11*a20; float b21 = a21*a10 - a11*a20;
float det = a00*b01 + a01*b11 + a02*b21; float det = a00*b01 + a01*b11 + a02*b21;
return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11), return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11),
b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10), b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10),
b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det; b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det;
} }
@ -44,24 +44,23 @@ mat3 inverse(mat3 m)
// https://github.com/glslify/glsl-transpose // https://github.com/glslify/glsl-transpose
mat3 transpose(mat3 m) mat3 transpose(mat3 m)
{ {
return mat3(m[0][0], m[1][0], m[2][0], return mat3(m[0][0], m[1][0], m[2][0],
m[0][1], m[1][1], m[2][1], m[0][1], m[1][1], m[2][1],
m[0][2], m[1][2], m[2][2]); m[0][2], m[1][2], m[2][2]);
} }
void main() void main()
{ {
// Compute binormal from vertex normal and tangent
// calc binormal from vertex normal and tangent
vec3 vertexBinormal = cross(vertexNormal, vertexTangent); vec3 vertexBinormal = cross(vertexNormal, vertexTangent);
// calc fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
// calc fragment position based on model transformations
// Compute fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
// Compute fragment position based on model transformations
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0)); fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord*2.0; fragTexCoord = vertexTexCoord*2.0;
fragNormal = normalize(normalMatrix*vertexNormal); fragNormal = normalize(normalMatrix*vertexNormal);
vec3 fragTangent = normalize(normalMatrix*vertexTangent); vec3 fragTangent = normalize(normalMatrix*vertexTangent);
fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal); fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal);
@ -71,5 +70,5 @@ void main()
TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal)); TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal));
// Calculate final vertex position // Calculate final vertex position
gl_Position = mvp * vec4(vertexPosition, 1.0); gl_Position = mvp*vec4(vertexPosition, 1.0);
} }

View file

@ -22,7 +22,6 @@ varying vec3 fragNormal;
varying vec4 shadowPos; varying vec4 shadowPos;
varying mat3 TBN; varying mat3 TBN;
// Input uniform values // Input uniform values
uniform int numOfLights; uniform int numOfLights;
uniform sampler2D albedoMap; uniform sampler2D albedoMap;
@ -53,102 +52,108 @@ uniform vec3 viewPos;
uniform vec3 ambientColor; uniform vec3 ambientColor;
uniform float ambient; uniform float ambient;
// refl in range 0 to 1 // Reflectivity in range 0.0 to 1.0
// returns base reflectivity to 1 // NOTE: Reflectivity is increased when surface view at larger angle
// incrase reflectivity when surface view at larger angle vec3 SchlickFresnel(float hDotV,vec3 refl)
vec3 schlickFresnel(float hDotV,vec3 refl)
{ {
return refl + (1.0 - refl) * pow(1.0 - hDotV,5.0); return refl + (1.0 - refl)*pow(1.0 - hDotV, 5.0);
} }
float ggxDistribution(float nDotH,float roughness) float GgxDistribution(float nDotH,float roughness)
{ {
float a = roughness * roughness * roughness * roughness; float a = roughness*roughness*roughness*roughness;
float d = nDotH * nDotH * (a - 1.0) + 1.0; float d = nDotH*nDotH*(a - 1.0) + 1.0;
d = PI * d * d; d = PI*d*d;
return a / max(d,0.0000001); return (a/max(d,0.0000001));
} }
float geomSmith(float nDotV,float nDotL,float roughness) float GeomSmith(float nDotV,float nDotL,float roughness)
{ {
float r = roughness + 1.0; float r = roughness + 1.0;
float k = r * r / 8.0; float k = r*r/8.0;
float ik = 1.0 - k; float ik = 1.0 - k;
float ggx1 = nDotV / (nDotV * ik + k); float ggx1 = nDotV/(nDotV*ik + k);
float ggx2 = nDotL / (nDotL * ik + k); float ggx2 = nDotL/(nDotL*ik + k);
return ggx1 * ggx2; return ggx1*ggx2;
} }
vec3 pbr(){ vec3 ComputePBR()
vec3 albedo = texture2D(albedoMap,vec2(fragTexCoord.x*tiling.x+offset.x,fragTexCoord.y*tiling.y+offset.y)).rgb; {
albedo = vec3(albedoColor.x*albedo.x,albedoColor.y*albedo.y,albedoColor.z*albedo.z); vec3 albedo = texture2D(albedoMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb;
float metallic = clamp(metallicValue,0.0,1.0); albedo = vec3(albedoColor.x*albedo.x, albedoColor.y*albedo.y, albedoColor.z*albedo.z);
float roughness = clamp(roughnessValue,0.0,1.0);
float ao = clamp(aoValue,0.0,1.0); float metallic = clamp(metallicValue, 0.0, 1.0);
if(useTexMRA == 1) { float roughness = clamp(roughnessValue, 0.0, 1.0);
vec4 mra = texture2D(mraMap, vec2(fragTexCoord.x * tiling.x + offset.x, fragTexCoord.y * tiling.y + offset.y)); float ao = clamp(aoValue, 0.0, 1.0);
metallic = clamp(mra.r+metallicValue,0.04,1.0);
roughness = clamp(mra.g+roughnessValue,0.04,1.0); if (useTexMRA == 1)
ao = (mra.b+aoValue)*0.5; {
} vec4 mra = texture2D(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y));
metallic = clamp(mra.r + metallicValue, 0.04, 1.0);
roughness = clamp(mra.g + roughnessValue, 0.04, 1.0);
ao = (mra.b + aoValue)*0.5;
}
vec3 N = normalize(fragNormal);
if (useTexNormal == 1)
{
N = texture2D(normalMap, vec2(fragTexCoord.x*tiling.x + offset.y, fragTexCoord.y*tiling.y + offset.y)).rgb;
N = normalize(N*2.0 - 1.0);
N = normalize(N*TBN);
}
vec3 V = normalize(viewPos - fragPosition);
vec3 N = normalize(fragNormal); vec3 emissive = vec3(0);
if(useTexNormal == 1) { emissive = (texture2D(emissiveMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb).g*emissiveColor.rgb*emissivePower*float(useTexEmissive);
N = texture2D(normalMap, vec2(fragTexCoord.x * tiling.x + offset.y, fragTexCoord.y * tiling.y + offset.y)).rgb;
N = normalize(N * 2.0 - 1.0); // return N;//vec3(metallic,metallic,metallic);
N = normalize(N * TBN); // If dia-electric use base reflectivity of 0.04 otherwise ut is a metal use albedo as base reflectivity
} vec3 baseRefl = mix(vec3(0.04), albedo.rgb, metallic);
vec3 lightAccum = vec3(0.0); // Acumulate lighting lum
for (int i = 0; i < 4; i++)
{
vec3 L = normalize(lights[i].position - fragPosition); // Compute light vector
vec3 H = normalize(V + L); // Compute halfway bisecting vector
float dist = length(lights[i].position - fragPosition); // Compute distance to light
float attenuation = 1.0/(dist*dist*0.23); // Compute attenuation
vec3 radiance = lights[i].color.rgb*lights[i].intensity*attenuation; // Compute input radiance, light energy comming in
// Cook-Torrance BRDF distribution function
float nDotV = max(dot(N,V), 0.0000001);
float nDotL = max(dot(N,L), 0.0000001);
float hDotV = max(dot(H,V), 0.0);
float nDotH = max(dot(N,H), 0.0);
float D = GgxDistribution(nDotH, roughness); // Larger the more micro-facets aligned to H
float G = GeomSmith(nDotV, nDotL, roughness); // Smaller the more micro-facets shadow
vec3 F = SchlickFresnel(hDotV, baseRefl); // Fresnel proportion of specular reflectance
vec3 spec = (D*G*F)/(4.0*nDotV*nDotL);
vec3 V = normalize(viewPos - fragPosition); // Difuse and spec light can't be above 1.0
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
vec3 kD = vec3(1.0) - F;
vec3 e = vec3(0); // Mult kD by the inverse of metallnes, only non-metals should have diffuse light
e = (texture2D(emissiveMap, vec2(fragTexCoord.x*tiling.x+offset.x, fragTexCoord.y*tiling.y+offset.y)).rgb).g * emissiveColor.rgb*emissivePower * float(useTexEmissive); kD *= 1.0 - metallic;
lightAccum += ((kD*albedo.rgb/PI + spec)*radiance*nDotL)*float(lights[i].enabled); // Angle of light has impact on result
//return N;//vec3(metallic,metallic,metallic); }
//if dia-electric use base reflectivity of 0.04 otherwise ut is a metal use albedo as base reflectivity
vec3 baseRefl = mix(vec3(0.04),albedo.rgb,metallic); vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5;
vec3 Lo = vec3(0.0); // acumulate lighting lum
return (ambientFinal + lightAccum*ao + emissive);
for(int i=0;i<numOfLights;++i){
vec3 L = normalize(lights[i].position - fragPosition); // calc light vector
vec3 H = normalize(V + L); // calc halfway bisecting vector
float dist = length(lights[i].position - fragPosition); // calc distance to light
float attenuation = 1.0 / (dist * dist * 0.23); // calc attenuation
vec3 radiance = lights[i].color.rgb * lights[i].intensity * attenuation; // calc input radiance,light energy comming in
//Cook-Torrance BRDF distribution function
float nDotV = max(dot(N,V),0.0000001);
float nDotL = max(dot(N,L),0.0000001);
float hDotV = max(dot(H,V),0.0);
float nDotH = max(dot(N,H),0.0);
float D = ggxDistribution(nDotH,roughness); // larger the more micro-facets aligned to H
float G = geomSmith(nDotV,nDotL,roughness); // smaller the more micro-facets shadow
vec3 F = schlickFresnel(hDotV, baseRefl); // fresnel proportion of specular reflectance
vec3 spec = (D * G * F) / (4.0 * nDotV * nDotL);
// difuse and spec light can't be above 1.0
// kD = 1.0 - kS diffuse component is equal 1.0 - spec comonent
vec3 kD = vec3(1.0) - F;
//mult kD by the inverse of metallnes , only non-metals should have diffuse light
kD *= 1.0 - metallic;
Lo += ((kD * albedo.rgb / PI + spec) * radiance * nDotL)*float(lights[i].enabled); // angle of light has impact on result
}
vec3 ambient_final = (ambientColor + albedo)* ambient * 0.5;
return ambient_final+Lo*ao+e;
} }
void main() void main()
{ {
vec3 color = pbr(); vec3 color = ComputePBR();
//HDR tonemapping
color = pow(color,color + vec3(1.0));
//gamma correction
color = pow(color,vec3(1.0/2.2));
gl_FragColor = vec4(color,1.0); // HDR tonemapping
color = pow(color, color + vec3(1.0));
// Gamma correction
color = pow(color, vec3(1.0/2.2));
gl_FragColor = vec4(color,1.0);
} }

View file

@ -1,11 +1,11 @@
#version 120 #version 120
// Input vertex attributes // Input vertex attributes
attribute vec3 vertexPosition; attribute vec3 vertexPosition;
attribute vec2 vertexTexCoord; attribute vec2 vertexTexCoord;
attribute vec3 vertexNormal; attribute vec3 vertexNormal;
attribute vec3 vertexTangent; attribute vec3 vertexTangent;
attribute vec4 vertexColor; attribute vec4 vertexColor;
// Input uniform values // Input uniform values
uniform mat4 mvp; uniform mat4 mvp;
@ -26,17 +26,17 @@ const float normalOffset = 0.1;
// https://github.com/glslify/glsl-inverse // https://github.com/glslify/glsl-inverse
mat3 inverse(mat3 m) mat3 inverse(mat3 m)
{ {
float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2]; float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2]; float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2]; float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
float b01 = a22*a11 - a12*a21; float b01 = a22*a11 - a12*a21;
float b11 = -a22*a10 + a12*a20; float b11 = -a22*a10 + a12*a20;
float b21 = a21*a10 - a11*a20; float b21 = a21*a10 - a11*a20;
float det = a00*b01 + a01*b11 + a02*b21; float det = a00*b01 + a01*b11 + a02*b21;
return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11), return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11),
b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10), b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10),
b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det; b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det;
} }
@ -44,24 +44,23 @@ mat3 inverse(mat3 m)
// https://github.com/glslify/glsl-transpose // https://github.com/glslify/glsl-transpose
mat3 transpose(mat3 m) mat3 transpose(mat3 m)
{ {
return mat3(m[0][0], m[1][0], m[2][0], return mat3(m[0][0], m[1][0], m[2][0],
m[0][1], m[1][1], m[2][1], m[0][1], m[1][1], m[2][1],
m[0][2], m[1][2], m[2][2]); m[0][2], m[1][2], m[2][2]);
} }
void main() void main()
{ {
// Compute binormal from vertex normal and tangent
// calc binormal from vertex normal and tangent
vec3 vertexBinormal = cross(vertexNormal, vertexTangent); vec3 vertexBinormal = cross(vertexNormal, vertexTangent);
// calc fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
// calc fragment position based on model transformations
// Compute fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
// Compute fragment position based on model transformations
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0)); fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord*2.0; fragTexCoord = vertexTexCoord*2.0;
fragNormal = normalize(normalMatrix*vertexNormal); fragNormal = normalize(normalMatrix*vertexNormal);
vec3 fragTangent = normalize(normalMatrix*vertexTangent); vec3 fragTangent = normalize(normalMatrix*vertexTangent);
fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal); fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal);
@ -71,5 +70,5 @@ void main()
TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal)); TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal));
// Calculate final vertex position // Calculate final vertex position
gl_Position = mvp * vec4(vertexPosition, 1.0); gl_Position = mvp*vec4(vertexPosition, 1.0);
} }

View file

@ -64,16 +64,16 @@ vec3 SchlickFresnel(float hDotV,vec3 refl)
float GgxDistribution(float nDotH,float roughness) float GgxDistribution(float nDotH,float roughness)
{ {
float a = roughness * roughness * roughness * roughness; float a = roughness*roughness*roughness*roughness;
float d = nDotH * nDotH * (a - 1.0) + 1.0; float d = nDotH*nDotH*(a - 1.0) + 1.0;
d = PI * d * d; d = PI*d*d;
return a / max(d,0.0000001); return (a/max(d,0.0000001));
} }
float GeomSmith(float nDotV,float nDotL,float roughness) float GeomSmith(float nDotV,float nDotL,float roughness)
{ {
float r = roughness + 1.0; float r = roughness + 1.0;
float k = r*r / 8.0; float k = r*r/8.0;
float ik = 1.0 - k; float ik = 1.0 - k;
float ggx1 = nDotV/(nDotV*ik + k); float ggx1 = nDotV/(nDotV*ik + k);
float ggx2 = nDotL/(nDotL*ik + k); float ggx2 = nDotL/(nDotL*ik + k);
@ -91,7 +91,7 @@ vec3 ComputePBR()
if (useTexMRA == 1) if (useTexMRA == 1)
{ {
vec4 mra = texture(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y))*useTexMRA; vec4 mra = texture(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y));
metallic = clamp(mra.r + metallicValue, 0.04, 1.0); metallic = clamp(mra.r + metallicValue, 0.04, 1.0);
roughness = clamp(mra.g + roughnessValue, 0.04, 1.0); roughness = clamp(mra.g + roughnessValue, 0.04, 1.0);
ao = (mra.b + aoValue)*0.5; ao = (mra.b + aoValue)*0.5;
@ -108,10 +108,10 @@ vec3 ComputePBR()
vec3 V = normalize(viewPos - fragPosition); vec3 V = normalize(viewPos - fragPosition);
vec3 emissive = vec3(0); vec3 emissive = vec3(0);
emissive = (texture(emissiveMap, vec2(fragTexCoord.x*tiling.x+offset.x, fragTexCoord.y*tiling.y+offset.y)).rgb).g * emissiveColor.rgb*emissivePower * useTexEmissive; emissive = (texture(emissiveMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb).g*emissiveColor.rgb*emissivePower*useTexEmissive;
// return N;//vec3(metallic,metallic,metallic); // return N;//vec3(metallic,metallic,metallic);
// if dia-electric use base reflectivity of 0.04 otherwise ut is a metal use albedo as base reflectivity // If dia-electric use base reflectivity of 0.04 otherwise ut is a metal use albedo as base reflectivity
vec3 baseRefl = mix(vec3(0.04), albedo.rgb, metallic); vec3 baseRefl = mix(vec3(0.04), albedo.rgb, metallic);
vec3 lightAccum = vec3(0.0); // Acumulate lighting lum vec3 lightAccum = vec3(0.0); // Acumulate lighting lum
@ -145,7 +145,7 @@ vec3 ComputePBR()
vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5; vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5;
return ambientFinal + lightAccum*ao + emissive; return (ambientFinal + lightAccum*ao + emissive);
} }
void main() void main()

View file

@ -27,12 +27,12 @@ void main()
{ {
// Compute binormal from vertex normal and tangent // Compute binormal from vertex normal and tangent
vec3 vertexBinormal = cross(vertexNormal, vertexTangent); vec3 vertexBinormal = cross(vertexNormal, vertexTangent);
// Compute fragment normal based on normal transformations // Compute fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(matModel))); mat3 normalMatrix = transpose(inverse(mat3(matModel)));
// Compute fragment position based on model transformations // Compute fragment position based on model transformations
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0f)); fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord*2.0; fragTexCoord = vertexTexCoord*2.0;
fragNormal = normalize(normalMatrix*vertexNormal); fragNormal = normalize(normalMatrix*vertexNormal);

View file

@ -134,14 +134,15 @@ int main(void)
} }
// Now we initialize the sampler2D uniform's in the deferred shader. // Now we initialize the sampler2D uniform's in the deferred shader.
// We do this by setting the uniform's value to the color channel slot we earlier // We do this by setting the uniform's values to the texture units that
// bound our textures to. // we later bind our g-buffer textures to.
rlEnableShader(deferredShader.id); rlEnableShader(deferredShader.id);
int texUnitPosition = 0;
rlSetUniformSampler(rlGetLocationUniform(deferredShader.id, "gPosition"), 0); int texUnitNormal = 1;
rlSetUniformSampler(rlGetLocationUniform(deferredShader.id, "gNormal"), 1); int texUnitAlbedoSpec = 2;
rlSetUniformSampler(rlGetLocationUniform(deferredShader.id, "gAlbedoSpec"), 2); SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gPosition"), &texUnitPosition, RL_SHADER_UNIFORM_SAMPLER2D);
SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gNormal"), &texUnitNormal, RL_SHADER_UNIFORM_SAMPLER2D);
SetShaderValue(deferredShader, rlGetLocationUniform(deferredShader.id, "gAlbedoSpec"), &texUnitAlbedoSpec, RL_SHADER_UNIFORM_SAMPLER2D);
rlDisableShader(); rlDisableShader();
// Assign out lighting shader to model // Assign out lighting shader to model
@ -208,11 +209,10 @@ int main(void)
// Draw // Draw
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
BeginDrawing(); BeginDrawing();
ClearBackground(RAYWHITE);
// Draw to the geometry buffer by first activating it // Draw to the geometry buffer by first activating it
rlEnableFramebuffer(gBuffer.framebuffer); rlEnableFramebuffer(gBuffer.framebuffer);
rlClearColor(0, 0, 0, 0);
rlClearScreenBuffers(); // Clear color and depth buffer rlClearScreenBuffers(); // Clear color and depth buffer
rlDisableColorBlend(); rlDisableColorBlend();
@ -246,14 +246,14 @@ int main(void)
BeginMode3D(camera); BeginMode3D(camera);
rlDisableColorBlend(); rlDisableColorBlend();
rlEnableShader(deferredShader.id); rlEnableShader(deferredShader.id);
// Activate our g-buffer textures // Bind our g-buffer textures
// These will now be bound to the sampler2D uniforms `gPosition`, `gNormal`, // We are binding them to locations that we earlier set in sampler2D uniforms `gPosition`, `gNormal`,
// and `gAlbedoSpec` // and `gAlbedoSpec`
rlActiveTextureSlot(0); rlActiveTextureSlot(texUnitPosition);
rlEnableTexture(gBuffer.positionTexture); rlEnableTexture(gBuffer.positionTexture);
rlActiveTextureSlot(1); rlActiveTextureSlot(texUnitNormal);
rlEnableTexture(gBuffer.normalTexture); rlEnableTexture(gBuffer.normalTexture);
rlActiveTextureSlot(2); rlActiveTextureSlot(texUnitAlbedoSpec);
rlEnableTexture(gBuffer.albedoSpecTexture); rlEnableTexture(gBuffer.albedoSpecTexture);
// Finally, we draw a fullscreen quad to our default framebuffer // Finally, we draw a fullscreen quad to our default framebuffer
@ -269,8 +269,8 @@ int main(void)
rlBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight, 0x00000100); // GL_DEPTH_BUFFER_BIT rlBlitFramebuffer(0, 0, screenWidth, screenHeight, 0, 0, screenWidth, screenHeight, 0x00000100); // GL_DEPTH_BUFFER_BIT
rlDisableFramebuffer(); rlDisableFramebuffer();
// Since our shader is now done and disabled, we can draw our lights in default // Since our shader is now done and disabled, we can draw spheres
// forward rendering // that represent light positions in default forward rendering
BeginMode3D(camera); BeginMode3D(camera);
rlEnableShader(rlGetShaderIdDefault()); rlEnableShader(rlGetShaderIdDefault());
for(int i = 0; i < MAX_LIGHTS; i++) for(int i = 0; i < MAX_LIGHTS; i++)

Some files were not shown because too many files have changed in this diff Show more